**Use case**
In some organisations are using AD with hierarchical structure (nested organisation unit) and DN follow this structure. As result we can not  use permanent build_dn for users with different OU.

**Describe the solution you'd like**
Solution can be look like:
1) bind as service account
2) set dn for user_name by some filter string to user_dn
3) bind as user_dn with password
3) use user_dn with filter for group/roles fetching

This approach is implemented in Metabase.

#include <Access/ExternalAuthenticators.h>
#include <Access/LDAPClient.h>
#include <Common/Exception.h>
#include <Common/quoteString.h>
#include <Poco/Util/AbstractConfiguration.h>
#include <boost/algorithm/string/case_conv.hpp>
#include <optional>
#include <utility>
namespace DB
{
namespace ErrorCodes
{
    extern const int BAD_ARGUMENTS;
}
namespace
{
auto parseLDAPServer(const Poco::Util::AbstractConfiguration & config, const String & name)
{
    if (name.empty())
        throw Exception("LDAP server name cannot be empty", ErrorCodes::BAD_ARGUMENTS);
    LDAPClient::Params params;
    const String ldap_server_config = "ldap_servers." + name;
    const bool has_host = config.has(ldap_server_config + ".host");
    const bool has_port = config.has(ldap_server_config + ".port");
    const bool has_bind_dn = config.has(ldap_server_config + ".bind_dn");
    const bool has_auth_dn_prefix = config.has(ldap_server_config + ".auth_dn_prefix");
    const bool has_auth_dn_suffix = config.has(ldap_server_config + ".auth_dn_suffix");
    const bool has_verification_cooldown = config.has(ldap_server_config + ".verification_cooldown");
    const bool has_enable_tls = config.has(ldap_server_config + ".enable_tls");
    const bool has_tls_minimum_protocol_version = config.has(ldap_server_config + ".tls_minimum_protocol_version");