**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.

virtual ext::scope_guard subscribeForChangesImpl(EntityType type, const OnChangedHandler & handler) const override;
    virtual bool hasSubscriptionImpl(const UUID & id) const override;
    virtual bool hasSubscriptionImpl(EntityType type) const override;
    virtual UUID loginImpl(const Credentials & credentials, const Poco::Net::IPAddress & address, const ExternalAuthenticators & external_authenticators) const override;
    virtual UUID getIDOfLoggedUserImpl(const String & user_name) const override;
private:
    void setConfiguration(AccessControlManager * access_control_manager_, const Poco::Util::AbstractConfiguration & config, const String & prefix);
    void processRoleChange(const UUID & id, const AccessEntityPtr & entity);
    void applyRoleChangeNoLock(bool grant, const UUID & role_id, const String & role_name);
    void assignRolesNoLock(User & user, const LDAPClient::SearchResultsList & external_roles) const;
    void assignRolesNoLock(User & user, const LDAPClient::SearchResultsList & external_roles, const std::size_t external_roles_hash) const;
    void updateAssignedRolesNoLock(const UUID & id, const String & user_name, const LDAPClient::SearchResultsList & external_roles) const;
    std::set<String> mapExternalRolesNoLock(const LDAPClient::SearchResultsList & external_roles) const;
    bool areLDAPCredentialsValidNoLock(const User & user, const Credentials & credentials,
        const ExternalAuthenticators & external_authenticators, LDAPClient::SearchResultsList & search_results) const;
    mutable std::recursive_mutex mutex;
    AccessControlManager * access_control_manager = nullptr;
    String ldap_server_name;
    LDAPClient::SearchParamsList role_search_params;
    std::set<String> common_role_names;                         
    mutable std::map<String, std::size_t> external_role_hashes; 
    mutable std::map<String, std::set<String>> users_per_roles; 
    mutable std::map<String, std::set<String>> roles_per_users; 
    mutable std::map<UUID, String> granted_role_names;          
    mutable std::map<String, UUID> granted_role_ids;            
    ext::scope_guard role_change_subscription;
    mutable MemoryAccessStorage memory_storage;
};
}