ldap4net
ldap4net copied to clipboard
Referral Chasing mode
Is your feature request related to a problem? Please describe. At enterprise level infrastructure contains multiple domains. You connect to domain via kerberos and couldn't search at another trusted domain. This is fixed at Windows default library with ReferralChasingOptions option. Class LdapSessionOptions.
Settings: LdapOption.LDAP_OPT_REFERRALS LdapOption.LDAP_OPT_REFERRAL_HOP_LIMIT
Also usefull fuction: LdapOption.LDAP_OPT_AUTO_RECONNECT
Describe the solution you'd like Add referral chasing function to code. Example: https://www.php.net/manual/en/function.ldap-set-rebind-proc.php https://linux.die.net/man/5/slapd-meta
https://klikr.org/4bbb0c55d527603667041ed0ce0a.png This is current net framework referral connection example.
Will this implemented at 2.5 release?
No. Maybe in next release - 2.6. As workaround you could set properties manually. Also contributions are welcome.
Well, I try to release Referral Chase... So at windows it created via register LDAP_OPT_REFERRAL_CALLBACK callback:
private int ProcessDereferenceConnection(
IntPtr PrimaryConnection,
IntPtr ConnectionToDereference)
{
if (ConnectionToDereference != (IntPtr) 0 && this.callbackRoutine.DereferenceConnection != null)
{
WeakReference weakReference = (WeakReference) null;
lock (LdapConnection.objectLock)
weakReference = (WeakReference) LdapConnection.handleTable[(object) ConnectionToDereference];
LdapConnection ldapConnection;
if (weakReference == null || !weakReference.IsAlive)
{
ldapConnection = new LdapConnection((LdapDirectoryIdentifier) this.connection.Directory, this.connection.GetCredential(), this.connection.AuthType, ConnectionToDereference);
}
else
{
ldapConnection = (LdapConnection) weakReference.Target;
LdapSessionOptions.ReleaseLdapHandleRef(ldapConnection);
}
this.callbackRoutine.DereferenceConnection(this.connection, ldapConnection);
}
return 1;
}
private int ProcessQueryConnection(
IntPtr PrimaryConnection,
IntPtr ReferralFromConnection,
IntPtr NewDNPtr,
string HostName,
int PortNumber,
SEC_WINNT_AUTH_IDENTITY_EX SecAuthIdentity,
Luid CurrentUserToken,
ref IntPtr ConnectionToUse)
{
ConnectionToUse = IntPtr.Zero;
string newDistinguishedName = (string) null;
if (this.callbackRoutine.QueryForConnection == null)
return 1;
if (NewDNPtr != (IntPtr) 0)
newDistinguishedName = Marshal.PtrToStringUni(NewDNPtr);
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.Append(HostName);
stringBuilder.Append(":");
stringBuilder.Append(PortNumber);
LdapDirectoryIdentifier identifier = new LdapDirectoryIdentifier(stringBuilder.ToString());
NetworkCredential credential = this.ProcessSecAuthIdentity(SecAuthIdentity);
LdapConnection referralFromConnection = (LdapConnection) null;
if (ReferralFromConnection != (IntPtr) 0)
{
lock (LdapConnection.objectLock)
{
WeakReference weakReference = (WeakReference) LdapConnection.handleTable[(object) ReferralFromConnection];
if (weakReference != null && weakReference.IsAlive)
{
referralFromConnection = (LdapConnection) weakReference.Target;
}
else
{
if (weakReference != null)
LdapConnection.handleTable.Remove((object) ReferralFromConnection);
referralFromConnection = new LdapConnection((LdapDirectoryIdentifier) this.connection.Directory, this.connection.GetCredential(), this.connection.AuthType, ReferralFromConnection);
LdapConnection.handleTable.Add((object) ReferralFromConnection, (object) new WeakReference((object) referralFromConnection));
}
}
}
long currentUserToken = (long) (uint) CurrentUserToken.LowPart + ((long) CurrentUserToken.HighPart << 32);
LdapConnection ldapConnection = this.callbackRoutine.QueryForConnection(this.connection, referralFromConnection, newDistinguishedName, identifier, credential, currentUserToken);
if (ldapConnection != null && ldapConnection.ldapHandle != null && (!ldapConnection.ldapHandle.IsInvalid && LdapSessionOptions.AddLdapHandleRef(ldapConnection)))
ConnectionToUse = ldapConnection.ldapHandle.DangerousGetHandle();
return 0;
}
Now it released via LdapResultCompleteStatus.Partial
. So I think it should be OK to handle it via delegate?
Our library is crossplatform. Unfortunately openldap library (linux and osx implementation based on openldap) does not have option LDAP_OPT_REFERRAL_CALLBACK. So I think we need to use openldap's approach: use boolean option for enable referral's handler.
So how we could implement it in windows? At novell I handle LdapReferralException and recreate it with new base DN + new connection. I think this is overkill for this situation. Also I research this code:
/* automatically chase referrals ("chase-referrals [{yes|no}]" statement) */
ldap_set_option( msc->msc_ld, LDAP_OPT_REFERRALS,
META_BACK_TGT_CHASE_REFERRALS( mt ) ? LDAP_OPT_ON : LDAP_OPT_OFF );
We could use LDAP_OPT_REFERRALS on windows