bool AD::Connect() { DWORD ret; LONG value; //if(!Init()) //{ if(!InitSSL()) { Util::Warn(L"Unable to initialize an LDAP context."); return false; } else { if((ret = ldap_get_option(ldap, LDAP_OPT_SSL, (void *)&value)) != LDAP_SUCCESS) { Util::Error(LdapGetLastError(), L"ldap_get_option()"); } if((void *)value == LDAP_OPT_ON) { if((ret = ldap_set_option(ldap, LDAP_OPT_SSL, LDAP_OPT_ON)) != LDAP_SUCCESS) { Util::Error(LdapGetLastError(), L"ldap_set_option()"); } } } //} if(ldap_set_option(ldap, LDAP_OPT_PROTOCOL_VERSION, (void *)LDAP_VERSION3) != LDAP_SUCCESS) { Util::Error(LdapGetLastError(), L"ldap_set_option()"); wprintf(L"Ret = %x\n", LdapGetLastError()); } return (ldap_connect(ldap, NULL) == LDAP_SUCCESS) ? true : false; }
bool AD::Login() { if(!Connect()) { Util::Warn(L"Couldn't connect via LDAP.\n"); wprintf(L"ret = %x\n", LdapGetLastError()); return false; } if(ldap_bind_s(ldap, NULL, NULL, LDAP_AUTH_NEGOTIATE) != LDAP_SUCCESS) { Util::Error(LdapGetLastError(), L"ldap_bind_s()"); return false; } return true; }
STDMETHODIMP CLDAPQuery::pageQuery( /* [in] */ LONG connect_id, /* [in] */ BSTR basedn, /* [in] */ BSTR scope, /* [in] */ BSTR filter, /* [in] */ BSTR attributes, /* [in] */ ULONG total_results, /* [retval][out] */ LONG* results_id) { m_errorCode = 0L; const int id = m_connections.FindKey(connect_id); if(id > -1) { ÑConnectInfo * const cinfo = m_connections.GetValueAt(id); const PLDAP ld = cinfo->ld(); const ULONG no_limit = LDAP_NO_LIMIT; ULONG ulScope = LDAP_SCOPE_BASE; CString csScope = scope; csScope.MakeLower(); if(csScope == _T("subtree")) ulScope = LDAP_SCOPE_SUBTREE; else if(csScope == _T("onelevel")) ulScope = LDAP_SCOPE_ONELEVEL; else if(csScope == _T("base")) ulScope = LDAP_SCOPE_BASE; CString csBaseDN = basedn; if(csBaseDN.IsEmpty() && (ulScope == LDAP_SCOPE_ONELEVEL || (!cinfo->canFindFromRoot() && ulScope == LDAP_SCOPE_SUBTREE))) { csBaseDN = cinfo->defaultNamingContext(); } CSimpleArray<PTCHAR> attributesArr; PTCHAR nextAttributes = NULL; CString csArrs = attributes; PTCHAR attribute = _tcstok_s(csArrs.GetBuffer(), _T(","), &nextAttributes); while(attribute != NULL) { attributesArr.Add(attribute); attribute = _tcstok_s(NULL, _T(","), &nextAttributes); } csArrs.ReleaseBuffer(); attributesArr.Add(NULL); // NULL-terminated array PLDAPSearch pPages = ldap_search_init_page(ld, csBaseDN.GetBuffer(), ulScope, CString(filter).GetBuffer(), attributesArr.GetData(), 0, NULL, NULL, no_limit, total_results, NULL); m_errorCode = LdapGetLastError(); if(pPages) { *results_id = cinfo->addResult(pPages); } } return S_OK; }
static LDAP *ldap_init_and_bind (const char *host, #ifdef WIN32 gboolean use_ssl, #endif const char *user_dn, const char *password) { LDAP *ld; int res; int desired_version = LDAP_VERSION3; #ifndef WIN32 res = ldap_initialize (&ld, host); if (res != LDAP_SUCCESS) { ccnet_warning ("ldap_initialize failed: %s.\n", ldap_err2string(res)); return NULL; } #else char *host_copy = g_strdup (host); if (!use_ssl) ld = ldap_init (host_copy, LDAP_PORT); else ld = ldap_sslinit (host_copy, LDAP_SSL_PORT, 1); g_free (host_copy); if (!ld) { ccnet_warning ("ldap_init failed: %ul.\n", LdapGetLastError()); return NULL; } #endif /* set the LDAP version to be 3 */ res = ldap_set_option (ld, LDAP_OPT_PROTOCOL_VERSION, &desired_version); if (res != LDAP_OPT_SUCCESS) { ccnet_warning ("ldap_set_option failed: %s.\n", ldap_err2string(res)); return NULL; } if (user_dn) { #ifndef WIN32 res = ldap_bind_s (ld, user_dn, password, LDAP_AUTH_SIMPLE); #else char *dn_copy = g_strdup(user_dn); char *password_copy = g_strdup(password); res = ldap_bind_s (ld, dn_copy, password_copy, LDAP_AUTH_SIMPLE); g_free (dn_copy); g_free (password_copy); #endif if (res != LDAP_SUCCESS ) { ccnet_warning ("ldap_bind failed: %s.\n", ldap_err2string(res)); ldap_unbind_s (ld); return NULL; } } return ld; }
void AD::GetDN() { LPWSTR filters[2]; LDAPMessage *search; LDAPMessage *entry; PWCHAR attribute; PWCHAR *value; BerElement *berElement; filters[0] = L"rootDomainNamingContext"; filters[1] = NULL; ldap = ldap_init((PWCHAR)host.c_str(), LDAP_PORT); // Null binding; to do that we simply do not call ldap_bind. if(ldap_connect(ldap, NULL) != LDAP_SUCCESS) { Util::Error(LdapGetLastError(), L"ldap_connect()"); wprintf(L"Ret = %x\n", LdapGetLastError()); } if(ldap_search_s(ldap, L"", LDAP_SCOPE_BASE, L"(&(objectClass=*))", filters, 0, &search) != LDAP_SUCCESS) { Util::Error(LdapGetLastError(), L"ldap_search_s()"); wprintf(L"Ret= %x\n", LdapGetLastError()); } entry = ldap_first_entry(ldap, search); attribute = ldap_first_attribute(ldap, entry, &berElement); if(lstrcmpi(L"rootDomainNamingContext", attribute) == 0) { value = ldap_get_values(ldap, entry, attribute); wprintf(L"value = %s\n", value[0]); dn = value[0]; } else { dn.clear(); } ldap_value_free(value); ldap_memfree(attribute); ldap_msgfree(search); ber_free(berElement, 0); }
STDMETHODIMP CLDAPQuery::err2string( /* [in] */ ULONG ufn, /* [retval][out] */ BSTR *string) { const PTCHAR pStr = ldap_err2string(ufn); m_errorCode = LdapGetLastError(); if(pStr) { *string = CComBSTR(pStr).Detach(); ldap_memfree(pStr); } return S_OK; }
STDMETHODIMP CLDAPQuery::dn2ufn( /* [in] */ BSTR dn, /* [retval][out] */ BSTR *ufn) { const PTCHAR pUfn = ldap_dn2ufn(CComBSTR(dn)); m_errorCode = LdapGetLastError(); if(pUfn) { *ufn = CComBSTR(pUfn).Detach(); ldap_memfree(pUfn); } return S_OK; }
// Sorry that this is kind of crappy, but passing the point to wstring // is basically necessary unless you want thrashed memory for strings. void AD::CNToAccountName(LPWSTR s, std::wstring *d) { LDAPMessage *search = NULL; LDAPMessage *entry = NULL; PWCHAR attribute; PWCHAR *values; BerElement *berElement = NULL; DWORD i; DWORD j; LPWSTR filters[2]; filters[0] = L"samAccountName"; filters[1] = NULL; d->clear(); if(ldap_search_s(ldap, s, LDAP_SCOPE_SUBTREE, NULL, filters, 0, &search) != LDAP_SUCCESS) { Util::Error(LdapGetLastError(), L"ldap_search_s()"); } entry = ldap_first_entry(ldap, search); for(i = 0; i < ldap_count_entries(ldap, search); i++) { if(!i) { entry = ldap_first_entry(ldap, search); } else { entry = ldap_next_entry(ldap, entry); } attribute = ldap_first_attribute(ldap, entry, &berElement); while(attribute != NULL) { values = ldap_get_values(ldap, entry, attribute); if(lstrcmpi(attribute, L"samaccountname") == 0) { d->append(values[0]); } ldap_value_free(values); ldap_memfree(attribute); attribute = ldap_next_attribute(ldap, entry, berElement); } } ber_free(berElement, 0); ldap_msgfree(search); }
STDMETHODIMP CLDAPQuery::rename( /* [in] */ LONG connect_id, /* [in] */ BSTR dn, /* [in] */ BSTR newRDN, /* [in] */ BSTR newParent, /* [in] */ BOOL deleteOldRdn) { m_errorCode = 0L; const int id = m_connections.FindKey(connect_id); if(id > -1) { const ÑConnectInfo* const cinfo = m_connections.GetValueAt(id); ldap_rename(cinfo->ld(), CComBSTR(dn), CComBSTR(newRDN), CComBSTR(newParent), deleteOldRdn ? 1 : 0, NULL, NULL, NULL); m_errorCode = LdapGetLastError(); } return S_OK; }
STDMETHODIMP CLDAPQuery::explodeDn( /* [in] */ BSTR str, /* [in] */ ULONG notypes, /* [retval][out] */ SAFEARRAY **result) { PTCHAR *vals = ldap_explode_dn(CComBSTR(str), notypes); m_errorCode = LdapGetLastError(); if(vals) { CComSafeArray<VARIANT> dnValues; for(LONG i = 0L; vals[i]!=NULL; i++) { dnValues.Add(CComVariant(vals[i])); } ldap_value_free(vals); *result = dnValues.Detach(); } return S_OK; }
void AD::Enumerate(ADSearchFilter searchFilter) { LDAPMessage *search = NULL; LDAPMessage *entry = NULL; PWCHAR *value; PWCHAR attribute; berval *ber = NULL; DWORD i; DWORD j; // 20 strings should be enough? LPWSTR filters[20]; BerElement *berElement = NULL; // Fill our filters array (NULL-terminated) with search-specific filters. switch(searchFilter) { case AD_SEARCH_USER: SetFilter(L"(&(objectClass=user)(objectCategory=person))"); filters[0] = L"samAccountName"; filters[1] = L"cn"; filters[2] = L"homeDirectory"; filters[3] = L"memberOf"; filters[4] = NULL; break; case AD_SEARCH_GROUP: SetFilter(L"(&(objectCategory=group))"); filters[0] = L"samAccountName"; filters[1] = L"cn"; filters[2] = L"member"; filters[3] = NULL; break; case AD_SEARCH_MACHINE: SetFilter(L"(&(objectCategory=computer))"); filters[0] = L"samAccountName"; filters[1] = L"cn"; filters[2] = NULL; break; default: break; } if(ldap_search_s(ldap, (const PWCHAR)dn.c_str(), LDAP_SCOPE_SUBTREE, (PWCHAR)filter.c_str(), NULL, 0, &search) != LDAP_SUCCESS) { Util::Error(LdapGetLastError(), L"ldap_search"); Util::Notice(L"ret = %x\n", LdapGetLastError()); } switch(searchFilter) { case AD_SEARCH_USER: AddUsers(search); break; case AD_SEARCH_GROUP: AddGroups(search); break; case AD_SEARCH_MACHINE: AddServers(search); break; default: break; } ldap_msgfree(search); ber_free(berElement, 0); }
void LDAPConnectionVersion3ProtocolPolicy::setProtocolVersion(LDAP* ldap) { unsigned long version = LDAP_VERSION3; int iRtn = ldap_set_option(ldap, LDAP_OPT_PROTOCOL_VERSION, (void*)&version); if(iRtn != LDAP_SUCCESS) { std::ostringstream buffer; buffer << "LDAP version setting failed: "; ULONG errorCode = LdapGetLastError(); ULONG win32ErrorCode = LdapMapErrorToWin32(errorCode); LPVOID lpMsgBuf; FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, win32ErrorCode, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language (LPTSTR) &lpMsgBuf, 0, NULL ); std::string win32Message((LPCTSTR)lpMsgBuf); LocalFree( lpMsgBuf ); buffer << " " << win32Message; switch(iRtn) { case LDAP_ADMIN_LIMIT_EXCEEDED: throw LDAPAdminLimitExceededException(buffer.str()); case LDAP_AFFECTS_MULTIPLE_DSAS: throw LDAPAffectsMultipleDsasException(buffer.str()); case LDAP_ALIAS_DEREF_PROBLEM: throw LDAPAliasDerefProblemException(buffer.str()); case LDAP_ALIAS_PROBLEM: throw LDAPAliasProblemException(buffer.str()); case LDAP_ALREADY_EXISTS: throw LDAPAlreadyExistsException(buffer.str()); case LDAP_ATTRIBUTE_OR_VALUE_EXISTS: throw LDAPAttributeOrValueExistsException(buffer.str()); case LDAP_AUTH_METHOD_NOT_SUPPORTED: throw LDAPAuthMethodNotSupportedException(buffer.str()); case LDAP_AUTH_UNKNOWN: throw LDAPAuthUnknownException(buffer.str()); case LDAP_BUSY: throw LDAPBusyException(buffer.str()); case LDAP_CLIENT_LOOP: throw LDAPClientLoopException(buffer.str()); case LDAP_CONFIDENTIALITY_REQUIRED: throw LDAPConfidentialityRequiredException(buffer.str()); case LDAP_CONNECT_ERROR: throw LDAPConnectErrorException(buffer.str()); case LDAP_CONSTRAINT_VIOLATION: throw LDAPConstraintViolationException(buffer.str()); case LDAP_CONTROL_NOT_FOUND: throw LDAPControlNotFoundException(buffer.str()); case LDAP_DECODING_ERROR: throw LDAPDecodingErrorException(buffer.str()); case LDAP_ENCODING_ERROR: throw LDAPEncodingErrorException(buffer.str()); case LDAP_FILTER_ERROR: throw LDAPFilterErrorException(buffer.str()); case LDAP_INAPPROPRIATE_AUTH: throw LDAPInappropriateAuthException(buffer.str()); case LDAP_INAPPROPRIATE_MATCHING: throw LDAPInappropriateMatchingException(buffer.str()); case LDAP_INSUFFICIENT_RIGHTS: throw LDAPInsufficientRightsException(buffer.str()); case LDAP_INVALID_CREDENTIALS: throw LDAPInvalidCredentialsException(buffer.str()); case LDAP_INVALID_DN_SYNTAX: throw LDAPInvalidDNSyntaxException(buffer.str()); case LDAP_INVALID_SYNTAX: throw LDAPInvalidSyntaxException(buffer.str()); case LDAP_LOCAL_ERROR: throw LDAPLocalErrorException(buffer.str()); case LDAP_NAMING_VIOLATION: throw LDAPNamingViolationException(buffer.str()); case LDAP_NO_MEMORY: throw LDAPNoMemoryException(buffer.str()); case LDAP_NO_OBJECT_CLASS_MODS: throw LDAPNoObjectClassModsException(buffer.str()); case LDAP_NO_RESULTS_RETURNED: throw LDAPNoResultsReturnedException(buffer.str()); case LDAP_NO_SUCH_ATTRIBUTE: throw LDAPNoSuchAttributeException(buffer.str()); case LDAP_NO_SUCH_OBJECT: throw LDAPNoSuchObjectException(buffer.str()); case LDAP_NOT_ALLOWED_ON_NONLEAF: throw LDAPOpNotAllowedOnNonleafException(buffer.str()); case LDAP_NOT_ALLOWED_ON_RDN: throw LDAPOpNotAllowedOnRDNException(buffer.str()); case LDAP_NOT_SUPPORTED: throw LDAPNotSupportedException(buffer.str()); case LDAP_OBJECT_CLASS_VIOLATION: throw LDAPObjectClassViolationException(buffer.str()); case LDAP_OPERATIONS_ERROR: throw LDAPOperationsErrorException(buffer.str()); case LDAP_OTHER: throw LDAPOtherException(buffer.str()); case LDAP_PARAM_ERROR: throw LDAPParamErrorException(buffer.str()); case LDAP_PROTOCOL_ERROR: throw LDAPProtocolErrorException(buffer.str()); case LDAP_REFERRAL_LIMIT_EXCEEDED: throw LDAPReferralLimitExceededException(buffer.str()); case LDAP_RESULTS_TOO_LARGE: throw LDAPResultsTooLargeException(buffer.str()); case LDAP_SERVER_DOWN: throw LDAPServerDownException(buffer.str()); case LDAP_SIZELIMIT_EXCEEDED: throw LDAPSizeLimitExceededException(buffer.str()); case LDAP_STRONG_AUTH_REQUIRED: throw LDAPStrongAuthRequiredException(buffer.str()); case LDAP_TIMELIMIT_EXCEEDED: throw LDAPTimeLimitExceededException(buffer.str()); case LDAP_TIMEOUT: throw LDAPTimeoutException(buffer.str()); case LDAP_UNAVAILABLE: throw LDAPUnavailableException(buffer.str()); case LDAP_UNAVAILABLE_CRIT_EXTENSION: throw LDAPUnavailableCritExtensionException(buffer.str()); case LDAP_UNDEFINED_TYPE: throw LDAPUndefinedTypeException(buffer.str()); case LDAP_UNWILLING_TO_PERFORM: throw LDAPUnwillingToPerformException(buffer.str()); case LDAP_USER_CANCELLED: throw LDAPUserCancelledException(buffer.str()); case LDAP_VIRTUAL_LIST_VIEW_ERROR: throw LDAPVirtualListViewErrorException(buffer.str()); } } }
STDMETHODIMP CLDAPQuery::connect( /* [in] */ BSTR username, /* [in] */ BSTR password, /* [in] */ BSTR host, /* [in] */ VARIANT_BOOL usessl, /* [retval][out] */ LONG *connect_id) { m_errorCode = 0L; const ULONG no_limit = LDAP_NO_LIMIT; PLDAP ld = NULL; bool useSSL = (usessl==VARIANT_TRUE)? true : false; bool canFindFromRoot = true; CAttributesSchema *attrsSchema = NULL; ULONG ulPort = useSSL?LDAP_SSL_PORT:LDAP_PORT; PTCHAR port = NULL; CString defaultNamingContext; CString csHost = host; CString hostname = _tcstok_s(csHost.GetBuffer(), _T(":"), &port); if(port && _tcslen(port) > 0) ulPort = _tcstol(port, NULL, 10); csHost.ReleaseBuffer(); try { if (useSSL) { if((ld = ldap_sslinit(hostname.GetBuffer(), ulPort, 1))==NULL) { m_errorCode = LdapGetLastError(); return S_FALSE; } m_errorCode = ldap_set_option(ld, LDAP_OPT_SERVER_CERTIFICATE, &CertRoutine); if (m_errorCode != LDAP_SUCCESS) throw _T("error LDAP_OPT_SERVER_CERTIFICATE"); } else { if((ld = ldap_init(hostname.GetBuffer(), ulPort))==NULL) { m_errorCode = LdapGetLastError(); return S_FALSE; } } const ULONG version = LDAP_VERSION3; m_errorCode = ldap_set_option(ld, LDAP_OPT_PROTOCOL_VERSION, (void*)&version); if (m_errorCode != LDAP_SUCCESS) throw _T("error LDAP_OPT_PROTOCOL_VERSION"); m_errorCode = ldap_set_option(ld, LDAP_OPT_SIZELIMIT, (void*)&no_limit); if (m_errorCode != LDAP_SUCCESS) throw _T("error LDAP_OPT_SIZELIMIT"); ld->ld_sizelimit = no_limit; m_errorCode = ldap_set_option(ld, LDAP_OPT_TIMELIMIT, (void*)&no_limit); if (m_errorCode != LDAP_SUCCESS) throw _T("error LDAP_OPT_TIMELIMIT"); ld->ld_timelimit = no_limit; m_errorCode = ldap_connect(ld, 0); if (m_errorCode != LDAP_SUCCESS ) throw _T("error ldap_connect"); m_errorCode = ldap_bind_s(ld, CString(username).GetBuffer(), CString(password).GetBuffer(), LDAP_AUTH_SIMPLE); if (m_errorCode != LDAP_SUCCESS) throw _T("error LDAP_AUTH_SIMPLE"); /* Get the RootDSE and BaseDN attribute (add checks on use this code).*/ CSimpleArray<PTCHAR> a; a.Add(_T("defaultNamingContext")); a.Add(_T("subschemaSubentry")); a.Add(NULL); PLDAPMessage pBaseMsg = NULL; if(ldap_search_s(ld, _T(""), LDAP_SCOPE_BASE, _T("(objectClass=*)"), a.GetData(), 0, &pBaseMsg) == LDAP_SUCCESS) { PLDAPMessage const entry = ldap_first_entry(ld, pBaseMsg); if(entry) { PTCHAR * const pschema = ldap_get_values(ld, entry, _T("subschemaSubentry")); if(pschema) { attrsSchema = new CAttributesSchema(ld, *pschema); ldap_value_free(pschema); } //try to find one item in subtree from root, if found it is Global Catalog search PLDAPSearch const pPages = ldap_search_init_page(ld, NULL, LDAP_SCOPE_SUBTREE, _T("(objectClass=*)"), NULL, 0, NULL, NULL, no_limit, 1, NULL); if(pPages) { PLDAPMessage pMsg = NULL; canFindFromRoot = (ldap_get_next_page_s(ld, pPages, NULL, 1, NULL, &pMsg) == LDAP_SUCCESS); if(pMsg) ldap_msgfree(pMsg); ldap_search_abandon_page(ld, pPages); } PTCHAR * const pDefaultNamingContext = ldap_get_values(ld, entry, _T("defaultNamingContext")); if(pDefaultNamingContext) { defaultNamingContext = *pDefaultNamingContext; ldap_value_free(pDefaultNamingContext); } } ldap_msgfree(pBaseMsg); } ÑConnectInfo * const cinfo = new ÑConnectInfo(ld, attrsSchema, defaultNamingContext, canFindFromRoot); *connect_id = ++m_maxConnectionId; m_connections.Add(*connect_id, cinfo); } catch (PTCHAR /*e*/) { if (ld) ldap_unbind_s(ld); *connect_id = -1; return S_FALSE; } return S_OK; }
//------------------------------------ // LdapUtils implementation //------------------------------------ LDAP* LdapUtils::LdapInit(const char* protocol, const char* host, int port, int secure_port) { LDAP* ld = NULL; if(stricmp(protocol, "ldaps") == 0) { #ifdef _WIN32 ld = ldap_sslinit((char*)host, secure_port, 1); if (ld == NULL ) throw MakeStringException(-1, "ldap_sslinit error" ); int rc = 0; unsigned long version = LDAP_VERSION3; long lv = 0; rc = ldap_set_option(ld, LDAP_OPT_PROTOCOL_VERSION, (void*)&version); if (rc != LDAP_SUCCESS) throw MakeStringException(-1, "ldap_set_option error - %s", ldap_err2string(rc)); rc = ldap_get_option(ld,LDAP_OPT_SSL,(void*)&lv); if (rc != LDAP_SUCCESS) throw MakeStringException(-1, "ldap_get_option error - %s", ldap_err2string(rc)); // If SSL is not enabled, enable it. if ((void*)lv != LDAP_OPT_ON) { rc = ldap_set_option(ld, LDAP_OPT_SSL, LDAP_OPT_ON); if (rc != LDAP_SUCCESS) throw MakeStringException(-1, "ldap_set_option error - %s", ldap_err2string(rc)); } ldap_set_option(ld, LDAP_OPT_SERVER_CERTIFICATE, verifyServerCert); #else // Initialize an LDAP session for TLS/SSL #ifndef HAVE_TLS //throw MakeStringException(-1, "openldap client library libldap not compiled with TLS support"); #endif StringBuffer uri("ldaps://"); uri.appendf("%s:%d", host, secure_port); DBGLOG("connecting to %s", uri.str()); int rc = LDAP_INIT(&ld, uri.str()); if(rc != LDAP_SUCCESS) { throw MakeStringException(-1, "ldap_initialize error %s", ldap_err2string(rc)); } int reqcert = LDAP_OPT_X_TLS_NEVER; ldap_set_option(NULL, LDAP_OPT_X_TLS_REQUIRE_CERT, &reqcert); #endif } else { // Initialize an LDAP session DBGLOG("connecting to ldap://%s:%d", host, port); #ifdef _WIN32 ld = LDAP_INIT(host, port); if(NULL == ld) { throw MakeStringException(-1, "ldap_init(%s,%d) error %s", host, port, ldap_err2string(LdapGetLastError())); } #else StringBuffer uri("ldap://"); uri.appendf("%s:%d", host, port); int rc = LDAP_INIT(&ld, uri.str()); if(rc != LDAP_SUCCESS) { throw MakeStringException(-1, "ldap_initialize(%s,%d) error %s", host, port, ldap_err2string(rc)); } #endif } return ld; }
static int CheckLDAPAuth(Port *port) { char *passwd; char server[128]; char basedn[128]; char prefix[128]; char suffix[128]; LDAP *ldap; bool ssl = false; int r; int ldapversion = LDAP_VERSION3; int ldapport = LDAP_PORT; char fulluser[NAMEDATALEN + 256 + 1]; if (!port->auth_arg || port->auth_arg[0] == '\0') { ereport(LOG, (errmsg("LDAP configuration URL not specified"))); return STATUS_ERROR; } /* * Crack the LDAP url. We do a very trivial parse: * * ldap[s]://<server>[:<port>]/<basedn>[;prefix[;suffix]] * * This code originally used "%127s" for the suffix, but that doesn't * work for embedded whitespace. We know that tokens formed by * hba.c won't include newlines, so we can use a "not newline" scanset * instead. */ server[0] = '\0'; basedn[0] = '\0'; prefix[0] = '\0'; suffix[0] = '\0'; /* ldap, including port number */ r = sscanf(port->auth_arg, "ldap://%127[^:]:%d/%127[^;];%127[^;];%127[^\n]", server, &ldapport, basedn, prefix, suffix); if (r < 3) { /* ldaps, including port number */ r = sscanf(port->auth_arg, "ldaps://%127[^:]:%d/%127[^;];%127[^;];%127[^\n]", server, &ldapport, basedn, prefix, suffix); if (r >= 3) ssl = true; } if (r < 3) { /* ldap, no port number */ r = sscanf(port->auth_arg, "ldap://%127[^/]/%127[^;];%127[^;];%127[^\n]", server, basedn, prefix, suffix); } if (r < 2) { /* ldaps, no port number */ r = sscanf(port->auth_arg, "ldaps://%127[^/]/%127[^;];%127[^;];%127[^\n]", server, basedn, prefix, suffix); if (r >= 2) ssl = true; } if (r < 2) { ereport(LOG, (errmsg("invalid LDAP URL: \"%s\"", port->auth_arg))); return STATUS_ERROR; } sendAuthRequest(port, AUTH_REQ_PASSWORD); passwd = recv_password_packet(port); if (passwd == NULL) return STATUS_EOF; /* client wouldn't send password */ ldap = ldap_init(server, ldapport); if (!ldap) { #ifndef WIN32 ereport(LOG, (errmsg("could not initialize LDAP: error code %d", errno))); #else ereport(LOG, (errmsg("could not initialize LDAP: error code %d", (int) LdapGetLastError()))); #endif return STATUS_ERROR; } if ((r = ldap_set_option(ldap, LDAP_OPT_PROTOCOL_VERSION, &ldapversion)) != LDAP_SUCCESS) { ldap_unbind(ldap); ereport(LOG, (errmsg("could not set LDAP protocol version: error code %d", r))); return STATUS_ERROR; } if (ssl) { #ifndef WIN32 if ((r = ldap_start_tls_s(ldap, NULL, NULL)) != LDAP_SUCCESS) #else static __ldap_start_tls_sA _ldap_start_tls_sA = NULL; if (_ldap_start_tls_sA == NULL) { /* * Need to load this function dynamically because it does not * exist on Windows 2000, and causes a load error for the whole * exe if referenced. */ HANDLE ldaphandle; ldaphandle = LoadLibrary("WLDAP32.DLL"); if (ldaphandle == NULL) { /* * should never happen since we import other files from * wldap32, but check anyway */ ldap_unbind(ldap); ereport(LOG, (errmsg("could not load wldap32.dll"))); return STATUS_ERROR; } _ldap_start_tls_sA = (__ldap_start_tls_sA) GetProcAddress(ldaphandle, "ldap_start_tls_sA"); if (_ldap_start_tls_sA == NULL) { ldap_unbind(ldap); ereport(LOG, (errmsg("could not load function _ldap_start_tls_sA in wldap32.dll"), errdetail("LDAP over SSL is not supported on this platform."))); return STATUS_ERROR; } /* * Leak LDAP handle on purpose, because we need the library to * stay open. This is ok because it will only ever be leaked once * per process and is automatically cleaned up on process exit. */ } if ((r = _ldap_start_tls_sA(ldap, NULL, NULL, NULL, NULL)) != LDAP_SUCCESS) #endif { ldap_unbind(ldap); ereport(LOG, (errmsg("could not start LDAP TLS session: error code %d", r))); return STATUS_ERROR; } } snprintf(fulluser, sizeof(fulluser), "%s%s%s", prefix, port->user_name, suffix); fulluser[sizeof(fulluser) - 1] = '\0'; r = ldap_simple_bind_s(ldap, fulluser, passwd); ldap_unbind(ldap); if (r != LDAP_SUCCESS) { ereport(LOG, (errmsg("LDAP login failed for user \"%s\" on server \"%s\": error code %d", fulluser, server, r))); return STATUS_ERROR; } return STATUS_OK; }
/* public idmap interface */ int nfs41_idmap_create( struct idmap_context **context_out) { struct idmap_context *context; int status = NO_ERROR; context = calloc(1, sizeof(struct idmap_context)); if (context == NULL) { status = GetLastError(); goto out; } /* initialize the caches */ cache_init(&context->users, &user_cache_ops); cache_init(&context->groups, &group_cache_ops); /* load ldap configuration from file */ status = config_init(&context->config); if (status) { eprintf("config_init() failed with %d\n", status); goto out_err_free; } /* initialize ldap and configure options */ context->ldap = ldap_init(context->config.hostname, context->config.port); if (context->ldap == NULL) { status = LdapGetLastError(); eprintf("ldap_init(%s) failed with %d: %s\n", context->config.hostname, status, ldap_err2stringA(status)); status = LdapMapErrorToWin32(status); goto out_err_free; } status = ldap_set_option(context->ldap, LDAP_OPT_PROTOCOL_VERSION, (void *)&context->config.version); if (status != LDAP_SUCCESS) { eprintf("ldap_set_option(version=%d) failed with %d\n", context->config.version, status); status = LdapMapErrorToWin32(status); goto out_err_free; } if (context->config.timeout) { status = ldap_set_option(context->ldap, LDAP_OPT_TIMELIMIT, (void *)&context->config.timeout); if (status != LDAP_SUCCESS) { eprintf("ldap_set_option(timeout=%d) failed with %d\n", context->config.timeout, status); status = LdapMapErrorToWin32(status); goto out_err_free; } } *context_out = context; out: return status; out_err_free: nfs41_idmap_free(context); goto out; }