private int InternalConnectToServer() { // In Linux you don't have to call Connect after calling init. You // directly call bind. However, we set the URI for the connection // here instead of during initialization because we need access to // the SessionOptions property to properly define it, which is not // available during init. Debug.Assert(!_ldapHandle.IsInvalid); string scheme = null; LdapDirectoryIdentifier directoryIdentifier = (LdapDirectoryIdentifier)_directoryIdentifier; if (directoryIdentifier.Connectionless) { scheme = "cldap://"; } else if (SessionOptions.SecureSocketLayer) { scheme = "ldaps://"; } else { scheme = "ldap://"; } string uris = null; string[] servers = directoryIdentifier.Servers; if (servers != null && servers.Length != 0) { StringBuilder temp = new StringBuilder(200); for (int i = 0; i < servers.Length; i++) { if (i != 0) { temp.Append(' '); } temp.Append(scheme); temp.Append(servers[i]); temp.Append(':'); temp.Append(directoryIdentifier.PortNumber); } if (temp.Length != 0) { uris = temp.ToString(); } } else { uris = $"{scheme}:{directoryIdentifier.PortNumber}"; } return(LdapPal.SetStringOption(_ldapHandle, LdapOption.LDAP_OPT_URI, uris)); }
private int InternalBind(NetworkCredential tempCredential, SEC_WINNT_AUTH_IDENTITY_EX cred, BindMethod method) { int error; if (tempCredential == null && (AuthType == AuthType.External || AuthType == AuthType.Kerberos)) { error = BindSasl(); } else { error = LdapPal.BindToDirectory(_ldapHandle, cred.user, cred.password); } return(error); }
internal static int BindToDirectory(ConnectionHandle ld, string who, string passwd) { IntPtr passwordPtr = IntPtr.Zero; try { passwordPtr = LdapPal.StringToPtr(passwd); berval passwordBerval = new berval { bv_len = passwd.Length, bv_val = passwordPtr, }; return Interop.Ldap.ldap_sasl_bind(ld, who, Interop.LDAP_SASL_SIMPLE, passwordBerval, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero); } finally { Marshal.FreeHGlobal(passwordPtr); } }
private int InternalBind(NetworkCredential tempCredential, SEC_WINNT_AUTH_IDENTITY_EX cred, BindMethod method) { int error; if (LocalAppContextSwitches.UseBasicAuthFallback) { if (tempCredential == null && (AuthType == AuthType.External || AuthType == AuthType.Kerberos)) { error = BindSasl(); } else { error = LdapPal.BindToDirectory(_ldapHandle, cred.user, cred.password); } } else { if (method == BindMethod.LDAP_AUTH_NEGOTIATE) { if (tempCredential == null) { error = BindSasl(); } else { // Explicit credentials were provided. If we call ldap_bind_s it will // return LDAP_NOT_SUPPORTED, so just skip the P/Invoke. error = (int)LdapError.NotSupported; } } else { // Basic and Anonymous are handled elsewhere. Debug.Assert(AuthType != AuthType.Anonymous && AuthType != AuthType.Basic); error = (int)LdapError.AuthUnknown; } } return(error); }
private void GetResultsHelper(LdapPartialAsyncResult asyncResult) { LdapConnection connection = asyncResult._con; ResultAll resultType = ResultAll.LDAP_MSG_RECEIVED; if (asyncResult._resultStatus == ResultsStatus.CompleteResult) { resultType = ResultAll.LDAP_MSG_POLLINGALL; } try { ValueTask <DirectoryResponse> vt = connection.ConstructResponseAsync(asyncResult._messageID, LdapOperation.LdapSearch, resultType, asyncResult._requestTimeout, false, sync: true); Debug.Assert(vt.IsCompleted); SearchResponse response = (SearchResponse)vt.GetAwaiter().GetResult(); // This should only happen in the polling thread case. if (response == null) { // Only when request time out has not yet expiered. if ((asyncResult._startTime.Ticks + asyncResult._requestTimeout.Ticks) > DateTime.Now.Ticks) { // This is expected, just the client does not have the result yet . return; } else { // time out, now we need to throw proper exception throw new LdapException((int)LdapError.TimeOut, LdapErrorMappings.MapResultCode((int)LdapError.TimeOut)); } } if (asyncResult._response != null) { AddResult(asyncResult._response, response); } else { asyncResult._response = response; } // If search is done, set the flag. if (response.searchDone) { asyncResult._resultStatus = ResultsStatus.Done; } } catch (Exception exception) { if (exception is DirectoryOperationException directoryOperationException) { SearchResponse response = (SearchResponse)directoryOperationException.Response; if (asyncResult._response != null) { AddResult(asyncResult._response, response); } else { asyncResult._response = response; } // Set the response back to the exception so it holds all the results up to now. directoryOperationException.Response = asyncResult._response; } else if (exception is LdapException ldapException) { if (asyncResult._response != null) { // add previous retrieved entries if available if (asyncResult._response.Entries != null) { for (int i = 0; i < asyncResult._response.Entries.Count; i++) { ldapException.PartialResults.Add(asyncResult._response.Entries[i]); } } // add previous retrieved references if available if (asyncResult._response.References != null) { for (int i = 0; i < asyncResult._response.References.Count; i++) { ldapException.PartialResults.Add(asyncResult._response.References[i]); } } } } // Exception occurs, this operation is done. asyncResult._exception = exception; asyncResult._resultStatus = ResultsStatus.Done; // Need to abandon this request. LdapPal.CancelDirectoryAsyncOperation(connection._ldapHandle, asyncResult._messageID); } }