DWORD VmDirSASLGSSAPIBind( LDAP** ppLd, PCSTR pszURI ) { DWORD dwError = 0; int retVal = 0; LDAP* pLd = NULL; const int ldapVer = LDAP_VERSION3; if ( ppLd == NULL || pszURI == NULL ) { dwError = VMDIR_ERROR_INVALID_PARAMETER; BAIL_ON_VMDIR_ERROR(dwError); } retVal = ldap_initialize( &pLd, pszURI); BAIL_ON_SIMPLE_LDAP_ERROR(retVal); retVal = ldap_set_option(pLd, LDAP_OPT_PROTOCOL_VERSION, &ldapVer); BAIL_ON_SIMPLE_LDAP_ERROR(retVal); retVal = ldap_sasl_interactive_bind_s( pLd, NULL, "GSSAPI", NULL, NULL, LDAP_SASL_QUIET, _VmDirSASLGSSAPIInteraction, NULL); BAIL_ON_SIMPLE_LDAP_ERROR(retVal); *ppLd = pLd; cleanup: return dwError; ldaperror: VMDIR_LOG_VERBOSE( VMDIR_LOG_MASK_ALL, "_VmDirSASLGSSBind failed. (%d)(%s)", retVal, ldap_err2string(retVal) ); dwError = VmDirMapLdapError(retVal); error: if (retVal == 0) { VMDIR_LOG_VERBOSE( VMDIR_LOG_MASK_ALL, "_VmDirSASLGSSBind failed. (%u)", dwError); } if ( pLd ) { ldap_unbind_ext_s( pLd, NULL, NULL); } goto cleanup; }
DWORD VmDirAnonymousLDAPBindWithTimeout( LDAP** ppLd, PCSTR pszLdapURI, int timeout ) { DWORD dwError = 0; int retVal = 0; const int ldapVer = LDAP_VERSION3; BerValue ldapBindPwd = {0}; LDAP* pLocalLd = NULL; struct timeval nettimeout = {0}; if (ppLd == NULL || pszLdapURI == NULL) { dwError = VMDIR_ERROR_INVALID_PARAMETER; BAIL_ON_VMDIR_ERROR(dwError); } retVal = ldap_initialize( &pLocalLd, pszLdapURI); BAIL_ON_SIMPLE_LDAP_ERROR(retVal); retVal = ldap_set_option( pLocalLd, LDAP_OPT_PROTOCOL_VERSION, &ldapVer); BAIL_ON_SIMPLE_LDAP_ERROR(retVal); if (timeout > 0) { nettimeout.tv_sec = timeout; // timeout connect retVal = ldap_set_option(pLocalLd, LDAP_OPT_NETWORK_TIMEOUT, (void *)&nettimeout); BAIL_ON_SIMPLE_LDAP_ERROR(retVal); } ldapBindPwd.bv_val = NULL; ldapBindPwd.bv_len = 0; retVal = ldap_sasl_bind_s( pLocalLd, "", LDAP_SASL_SIMPLE, &ldapBindPwd, // no credentials NULL, NULL, NULL); BAIL_ON_SIMPLE_LDAP_ERROR(retVal); *ppLd = pLocalLd; cleanup: return dwError; ldaperror: VMDIR_LOG_ERROR( VMDIR_LOG_MASK_ALL, "VmDirAnonymousLDAPBind to (%s) failed. (%d)(%s)", VDIR_SAFE_STRING(pszLdapURI), retVal, ldap_err2string(retVal) ); dwError = VmDirMapLdapError(retVal); error: if (retVal == 0) { VMDIR_LOG_VERBOSE( VMDIR_LOG_MASK_ALL, "VmDirAnonymousLDAPBind to (%s) failed. (%u)", VDIR_SAFE_STRING(pszLdapURI), dwError); } if (pLocalLd) { ldap_unbind_ext_s( pLocalLd, NULL, NULL); } goto cleanup; }
DWORD VmDirSASLSRPBindExt1( LDAP** ppLd, PCSTR pszURI, PCSTR pszUPN, PCSTR pszPass, int iTimeout ) { DWORD dwError = 0; int retVal = 0; PSTR pszLowerCaseUPN = NULL; LDAP* pLd = NULL; const int ldapVer = LDAP_VERSION3; const int iSaslNoCanon = 1; VMDIR_SASL_INTERACTIVE_DEFAULT srpDefault = {0}; int iCnt = 0; struct timeval optTimeout={0}; optTimeout.tv_usec = 0; optTimeout.tv_sec = iTimeout; if ( ppLd == NULL || pszURI == NULL || pszUPN == NULL || pszPass == NULL ) { dwError = VMDIR_ERROR_INVALID_PARAMETER; BAIL_ON_VMDIR_ERROR(dwError); } dwError = VmDirAllocASCIIUpperToLower( pszUPN, &pszLowerCaseUPN ); BAIL_ON_VMDIR_ERROR(dwError); srpDefault.pszAuthName = pszLowerCaseUPN; srpDefault.pszPass = pszPass; for (iCnt=0; iCnt<2; iCnt++) { retVal = ldap_initialize( &pLd, pszURI); BAIL_ON_SIMPLE_LDAP_ERROR(retVal); retVal = ldap_set_option(pLd, LDAP_OPT_PROTOCOL_VERSION, &ldapVer); BAIL_ON_SIMPLE_LDAP_ERROR(retVal); // turn off SASL hostname canonicalization for SRP mech retVal = ldap_set_option(pLd, LDAP_OPT_X_SASL_NOCANON, &iSaslNoCanon); BAIL_ON_SIMPLE_LDAP_ERROR(retVal); if (iTimeout > 0) { // timeout connect retVal = ldap_set_option(pLd, LDAP_OPT_NETWORK_TIMEOUT, (void *)&optTimeout); BAIL_ON_SIMPLE_LDAP_ERROR(retVal); } retVal = ldap_sasl_interactive_bind_s( pLd, NULL, "SRP", NULL, NULL, LDAP_SASL_QUIET, _VmDirSASLSRPInteraction, &srpDefault); if (retVal == LDAP_SERVER_DOWN || retVal == LDAP_TIMEOUT) { VmDirSleep(50); // pause 50 ms if ( pLd ) { ldap_unbind_ext_s(pLd, NULL, NULL); pLd = NULL; } continue; // if transient network error, retry once. } else { break; } } BAIL_ON_SIMPLE_LDAP_ERROR(retVal); // bail ldap_sasl_interactive_bind_s failure. *ppLd = pLd; cleanup: VMDIR_SAFE_FREE_MEMORY(pszLowerCaseUPN); return dwError; ldaperror: VMDIR_LOG_VERBOSE( VMDIR_LOG_MASK_ALL, "_VmDirSASLSRPBind failed. (%d)(%s)", retVal, ldap_err2string(retVal) ); dwError = VmDirMapLdapError(retVal); error: if (retVal == 0) { VMDIR_LOG_VERBOSE( VMDIR_LOG_MASK_ALL, "_VmDirSASLSRPBind failed. (%u)", dwError); } if ( pLd ) { ldap_unbind_ext_s( pLd, NULL, NULL); } goto cleanup; }
/* * Bind to a LDAP server via SSL port. * Require server certificate verification. * * In 5.5. mix mode, replication goes through ldaps port. */ DWORD VmDirSSLBind( LDAP** ppLd, PCSTR pszURI, PCSTR pszDN, PCSTR pszPassword ) { DWORD dwError = 0; int retVal = 0; LDAP* pLd = NULL; BerValue ldapBindPwd = {0}; const int ldapVer = LDAP_VERSION3; int iTLSDEMAND = LDAP_OPT_X_TLS_DEMAND; int iTLSMin = LDAP_OPT_X_TLS_PROTOCOL_TLS1_0; PSTR pszTrustCertFile = NULL; SSL_CTX* pSslCtx = NULL; if ( ppLd == NULL || pszURI == NULL ) { dwError = VMDIR_ERROR_INVALID_PARAMETER; BAIL_ON_VMDIR_ERROR(dwError); } // only allow ldaps traffic over SSL port if ( VmDirStringNCompareA( pszURI, VMDIR_LDAPS_PROTOCOL, 5, FALSE) != 0 ) { dwError = VMDIR_ERROR_ACCESS_DENIED; BAIL_ON_VMDIR_ERROR(dwError); } dwError = VmDirPrepareOpensslClientCtx( &pSslCtx, &pszTrustCertFile, pszURI ); BAIL_ON_VMDIR_ERROR(dwError); retVal = ldap_set_option( NULL, LDAP_OPT_X_TLS_REQUIRE_CERT, &iTLSDEMAND); BAIL_ON_SIMPLE_LDAP_ERROR(retVal); retVal = ldap_set_option(NULL, LDAP_OPT_X_TLS_PROTOCOL_MIN, &iTLSMin); BAIL_ON_SIMPLE_LDAP_ERROR(retVal); retVal = ldap_initialize(&pLd, pszURI); BAIL_ON_SIMPLE_LDAP_ERROR(retVal); retVal = ldap_set_option(pLd, LDAP_OPT_PROTOCOL_VERSION, &ldapVer); BAIL_ON_SIMPLE_LDAP_ERROR(retVal); retVal = ldap_set_option( pLd, LDAP_OPT_X_TLS_CTX, pSslCtx); BAIL_ON_SIMPLE_LDAP_ERROR(retVal); ldapBindPwd.bv_val = 0; ldapBindPwd.bv_len = 0; if (pszPassword) { ldapBindPwd.bv_val = (PSTR) pszPassword; ldapBindPwd.bv_len = (ULONG) VmDirStringLenA(pszPassword); } retVal = ldap_sasl_bind_s( pLd, pszDN, LDAP_SASL_SIMPLE, &ldapBindPwd, // ldaps with credentials NULL, NULL, NULL); BAIL_ON_SIMPLE_LDAP_ERROR(retVal); *ppLd = pLd; cleanup: if (pSslCtx) { SSL_CTX_free(pSslCtx); } VMDIR_SAFE_FREE_MEMORY(pszTrustCertFile); return dwError; ldaperror: VMDIR_LOG_ERROR( VMDIR_LOG_MASK_ALL, "VmDirSSLBind failed for %s %s. (%d)(%s)", pszURI, pszDN, retVal, ldap_err2string(retVal)); dwError = VmDirMapLdapError(retVal); error: if (retVal == 0) { VMDIR_LOG_VERBOSE( VMDIR_LOG_MASK_ALL, "_VmDirSSLBind failed. (%u)", dwError); } if ( pLd ) { ldap_unbind_ext_s( pLd, NULL, NULL); } goto cleanup; }
DWORD VmDirSASLSRPBind( LDAP** ppLd, PCSTR pszURI, PCSTR pszUPN, PCSTR pszPass ) { DWORD dwError = 0; int retVal = 0; PSTR pszLowerCaseUPN = NULL; LDAP* pLd = NULL; const int ldapVer = LDAP_VERSION3; VMDIR_SASL_INTERACTIVE_DEFAULT srpDefault = {0}; int iCnt = 0; if ( ppLd == NULL || pszURI == NULL || pszUPN == NULL || pszPass == NULL ) { dwError = VMDIR_ERROR_INVALID_PARAMETER; BAIL_ON_VMDIR_ERROR(dwError); } dwError = VmDirAllocASCIIUpperToLower( pszUPN, &pszLowerCaseUPN ); BAIL_ON_VMDIR_ERROR(dwError); srpDefault.pszAuthName = pszLowerCaseUPN; srpDefault.pszPass = pszPass; for (iCnt=0; iCnt<2; iCnt++) { retVal = ldap_initialize( &pLd, pszURI); BAIL_ON_SIMPLE_LDAP_ERROR(retVal); retVal = ldap_set_option(pLd, LDAP_OPT_PROTOCOL_VERSION, &ldapVer); BAIL_ON_SIMPLE_LDAP_ERROR(retVal); retVal = ldap_sasl_interactive_bind_s( pLd, NULL, "SRP", NULL, NULL, LDAP_SASL_QUIET, _VmDirSASLSRPInteraction, &srpDefault); if (retVal == LDAP_SERVER_DOWN) { VmDirSleep(50); // pause 50 ms if ( pLd ) { ldap_unbind_ext_s(pLd, NULL, NULL); pLd = NULL; } continue; // if transient network error, retry once. } else { break; } } BAIL_ON_SIMPLE_LDAP_ERROR(retVal); // bail ldap_sasl_interactive_bind_s failure. *ppLd = pLd; cleanup: VMDIR_SAFE_FREE_MEMORY(pszLowerCaseUPN); return dwError; ldaperror: VMDIR_LOG_VERBOSE( VMDIR_LOG_MASK_ALL, "_VmDirSASLSRPBind failed. (%d)(%s)", retVal, ldap_err2string(retVal) ); dwError = VmDirMapLdapError(retVal); error: if (retVal == 0) { VMDIR_LOG_VERBOSE( VMDIR_LOG_MASK_ALL, "_VmDirSASLSRPBind failed. (%u)", dwError); } if ( pLd ) { ldap_unbind_ext_s( pLd, NULL, NULL); } goto cleanup; }