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

granted_role_ids.erase(iit);
    }
    
    if (local_role_names.empty())
        roles_per_users.erase(user_name);
    else
        roles_per_users[user_name] = std::move(local_role_names);
    external_role_hashes[user_name] = external_roles_hash;
}
void LDAPAccessStorage::updateAssignedRolesNoLock(const UUID & id, const String & user_name, const LDAPClient::SearchResultsList & external_roles) const
{
    
    const auto external_roles_hash = boost::hash<LDAPClient::SearchResultsList>{}(external_roles);
    
    const auto it = external_role_hashes.find(user_name);
    if (it != external_role_hashes.end() && it->second == external_roles_hash)
        return;
    auto update_func = [this, &external_roles, external_roles_hash] (const AccessEntityPtr & entity_) -> AccessEntityPtr
    {
        if (auto user = typeid_cast<std::shared_ptr<const User>>(entity_))
        {
            auto changed_user = typeid_cast<std::shared_ptr<User>>(user->clone());
            assignRolesNoLock(*changed_user, external_roles, external_roles_hash);
            return changed_user;
        }
        return entity_;
    };
    memory_storage.update(id, update_func);
}
std::set<String> LDAPAccessStorage::mapExternalRolesNoLock(const LDAPClient::SearchResultsList & external_roles) const