LDAP * ldap_open(char *host, int port) { LDAP *ld; int err; if ((ld = ldap_init(host, port)) == NULL) { return (NULL); } Debug(LDAP_DEBUG_TRACE, catgets(slapdcat, 1, 113, "ldap_open (after ldap_init)\n"), 0, 0, 0); #ifdef _REENTRANT LOCK_LDAP(ld); #endif if ((err = open_default_ldap_connection(ld)) != LDAP_SUCCESS) { #ifdef _REENTRANT UNLOCK_LDAP(ld); #endif ldap_ld_free(ld, 0); Debug(LDAP_DEBUG_ANY, catgets(slapdcat, 1, 1275, "ldap_open failed, %s\n"), ldap_err2string(err), 0, 0); return (NULL); } Debug(LDAP_DEBUG_TRACE, catgets(slapdcat, 1, 194, "ldap_open successful, ld_host is %s\n"), (ld->ld_host == NULL) ? "(null)" : ld->ld_host, 0, 0); #ifdef _REENTRANT UNLOCK_LDAP(ld); #endif return (ld); }
LDAP_CALL ldap_open( const char *host, int port ) { LDAP *ld; LDAPDebug( LDAP_DEBUG_TRACE, "ldap_open\n", 0, 0, 0 ); if (( ld = ldap_init( host, port )) == NULL ) { return( NULL ); } LDAP_MUTEX_LOCK( ld, LDAP_CONN_LOCK ); if ( nsldapi_open_ldap_defconn( ld ) < 0 ) { LDAP_MUTEX_UNLOCK( ld, LDAP_CONN_LOCK ); ldap_ld_free( ld, NULL, NULL, 0 ); return( NULL ); } LDAP_MUTEX_UNLOCK( ld, LDAP_CONN_LOCK ); LDAPDebug( LDAP_DEBUG_TRACE, "ldap_open successful, ld_host is %s\n", ( ld->ld_host == NULL ) ? "(null)" : ld->ld_host, 0, 0 ); return( ld ); }
int main( int argc, char *argv[] ) { LDAP *ld; int result; int auth_method = LDAP_AUTH_SIMPLE; int desired_version = LDAP_VERSION3; char *ldap_host = "localhost"; char *root_dn = "cn=Manager, dc=example, dc=com"; char *root_pw = "secret"; BerElement* ber; LDAPMessage* msg; LDAPMessage* entry; char* base="ou=developers,dc=example,dc=com"; char* filter="(objectClass=*)"; char* errstring; char* dn = NULL; char* attr; char** vals; int i; if ((ld = ldap_init(ldap_host, LDAP_PORT)) == NULL ) { perror( "ldap_init failed" ); exit( EXIT_FAILURE ); } /* set the LDAP version to be 3 */ if (ldap_set_option(ld, LDAP_OPT_PROTOCOL_VERSION, &desired_version) != LDAP_OPT_SUCCESS) { ldap_perror(ld, "ldap_set_option"); exit(EXIT_FAILURE); } if (ldap_bind_s(ld, root_dn, root_pw, auth_method) != LDAP_SUCCESS ) { ldap_perror( ld, "ldap_bind" ); exit( EXIT_FAILURE ); } if (ldap_search_s(ld, base, LDAP_SCOPE_SUBTREE, filter, NULL, 0, &msg) != LDAP_SUCCESS) { ldap_perror( ld, "ldap_search_s" ); exit(EXIT_FAILURE); } printf("The number of entries returned was %d\n\n", ldap_count_entries(ld, msg)); /* Iterate through the returned entries */ for(entry = ldap_first_entry(ld, msg); entry != NULL; entry = ldap_next_entry(ld, entry)) { if((dn = ldap_get_dn(ld, entry)) != NULL) { printf("Returned dn: %s\n", dn); ldap_memfree(dn); } for( attr = ldap_first_attribute(ld, entry, &ber); attr != NULL; attr = ldap_next_attribute(ld, entry, ber)) { if ((vals = ldap_get_values(ld, entry, attr)) != NULL) { for(i = 0; vals[i] != NULL; i++) { printf("%s: %s\n", attr, vals[i]); } ldap_value_free(vals); } ldap_memfree(attr); } if (ber != NULL) { ber_free(ber,0); } printf("\n"); } /* clean up */ ldap_msgfree(msg); result = ldap_unbind_s(ld); if (result != 0) { fprintf(stderr, "ldap_unbind_s: %s\n", ldap_err2string(result)); exit( EXIT_FAILURE ); } return EXIT_SUCCESS; }
/* * Creates an LDAP search URL given a comma-separated list of attributes. * Returns a list of key=values separated by '\n' */ char * pref_get_ldap_attributes(char* host, char* base, char* filter, char* attrs, char** return_error) { char *value = NULL; LDAP* ld; int err, i; char *url; LDAPMessage *result; LDAPMessage *e; char *a; BerElement *ber; char **vals; ld = ldap_init(host, LDAP_PORT); if (!ld) return value; url = (char*) malloc(sizeof(char) * (strlen(host) + strlen(base) + strlen(filter) + strlen(attrs) + 20)); if (!url) return value; XP_SPRINTF(url, "ldap://%s/%s?%s?sub?%s", host, base, attrs, filter); err = ldap_url_search_s( ld, url, 0, &result ); XP_FREE(url); if (err != LDAP_SUCCESS) { *return_error = ldap_err2string(err); return value; } e = ldap_first_entry( ld, result ); if (e) { a = ldap_first_attribute( ld, e, &ber ); if (a) { int total_buf_size = 200; int remaining_buf_size = total_buf_size; value = (char*) malloc(sizeof(char*) * total_buf_size); if (!value) return NULL; value[0] = '\0'; for ( ; a != NULL; a = ldap_next_attribute( ld, e, ber )) { vals = ldap_get_values( ld, e, a ); if (vals && vals[0]) { remaining_buf_size -= (strlen(a) + strlen(vals[0]) + 2); if (remaining_buf_size < 1) { remaining_buf_size += 2 * total_buf_size; total_buf_size += 2 * total_buf_size; value = (char*) realloc(value, sizeof(char*) * total_buf_size); if (!value) return NULL; } strcat(value, "\n"); strcat(value, a); strcat(value, "="); strcat(value, vals[0]); ldap_value_free( vals ); } } ldap_memfree(a); } if (ber) ber_free(ber, 0); } ldap_msgfree(result); ldap_unbind(ld); return value; }
bool AD::Init() { ldap = ldap_init((PWCHAR)host.c_str(), LDAP_PORT); return ldap == NULL ? false : true; }
sInt32 CLDAPNode::BindProc ( sLDAPNodeStruct *inLDAPNodeStruct ) { sInt32 siResult = eDSNoErr; int bindMsgId = 0; int version = -1; sLDAPConfigData *pConfig = nil; char *ldapAcct = nil; char *ldapPasswd = nil; int openTO = 0; LDAP *inLDAPHost = inLDAPNodeStruct->fHost; LDAPMessage *result = nil; int ldapReturnCode = 0; try { if ( inLDAPNodeStruct == nil ) throw( (sInt32)eDSNullParameter ); if (inLDAPNodeStruct->fLDAPSessionMutex != nil) { inLDAPNodeStruct->fLDAPSessionMutex->Wait(); } // Here is the bind to the LDAP server // Note that there may be stored name/password in the config table // ie. always use the config table data if authentication has not explicitly been set // use LDAPAuthNodeMap if inLDAPNodeStruct contains a username //check that we were already here if (inLDAPHost == NULL) { //retrieve the config data //don't need to retrieve for the case of "generic unknown" so don't check index 0 if (( inLDAPNodeStruct->fLDAPConfigTableIndex < gConfigTableLen) && ( inLDAPNodeStruct->fLDAPConfigTableIndex >= 1 )) { pConfig = (sLDAPConfigData *)gConfigTable->GetItemData( inLDAPNodeStruct->fLDAPConfigTableIndex ); if (pConfig != nil) { if ( (pConfig->bSecureUse) && (inLDAPNodeStruct->fUserName == nil) ) { if (pConfig->fServerAccount != nil) { ldapAcct = new char[1+::strlen(pConfig->fServerAccount)]; ::strcpy( ldapAcct, pConfig->fServerAccount ); } if (pConfig->fServerPassword != nil) { ldapPasswd = new char[1+::strlen(pConfig->fServerPassword)]; ::strcpy( ldapPasswd, pConfig->fServerPassword ); } } else { if (inLDAPNodeStruct->fUserName != nil) { ldapAcct = new char[1+::strlen(inLDAPNodeStruct->fUserName)]; ::strcpy( ldapAcct, inLDAPNodeStruct->fUserName ); } if (inLDAPNodeStruct->fAuthCredential != nil) { if (inLDAPNodeStruct->fAuthType != nil) { //auth type of clear text means char * password if (strcmp(inLDAPNodeStruct->fAuthType,kDSStdAuthClearText) == 0) { ldapPasswd = new char[1+::strlen((char*)(inLDAPNodeStruct->fAuthCredential))]; ::strcpy( ldapPasswd, (char*)(inLDAPNodeStruct->fAuthCredential) ); } } else //default is password { ldapPasswd = new char[1+::strlen((char*)(inLDAPNodeStruct->fAuthCredential))]; ::strcpy( ldapPasswd, (char*)(inLDAPNodeStruct->fAuthCredential) ); } } } openTO = pConfig->fOpenCloseTimeout; } } if (inLDAPNodeStruct->fLDAPConfigTableIndex != 0) { if (pConfig != nil) { inLDAPHost = ldap_init( pConfig->fServerName, pConfig->fServerPort ); } } else { inLDAPHost = ldap_init( inLDAPNodeStruct->fServerName, inLDAPNodeStruct->fDirectLDAPPort ); } if ( inLDAPHost == nil ) throw( (sInt32)eDSCannotAccessSession ); if (pConfig != nil) { if ( pConfig->bIsSSL ) { int ldapOptVal = LDAP_OPT_X_TLS_HARD; ldap_set_option(inLDAPHost, LDAP_OPT_X_TLS, &ldapOptVal); } } /* LDAPv3 only */ version = LDAP_VERSION3; ldap_set_option( inLDAPHost, LDAP_OPT_PROTOCOL_VERSION, &version ); //heuristic to prevent many consecutive failures with long timeouts //ie. forcing quick failures after first failure during a window of //the same length as the timeout value //NN fLDAPNodeOpenMutex.Wait(); if ( inLDAPNodeStruct->bHasFailed ) { if ( time( nil ) < inLDAPNodeStruct->fDelayedBindTime ) { //NN fLDAPNodeOpenMutex.Signal(); throw( (sInt32)eDSCannotAccessSession ); } else { inLDAPNodeStruct->bHasFailed = false; //fDelayedBindTime then is unused so no need to reset } } //NN fLDAPNodeOpenMutex.Signal(); //this is our and only our LDAP session for now //need to use our timeout so we don't hang indefinitely bindMsgId = ldap_bind( inLDAPHost, ldapAcct, ldapPasswd, LDAP_AUTH_SIMPLE ); if (openTO == 0) { ldapReturnCode = ldap_result(inLDAPHost, bindMsgId, 0, NULL, &result); } else { struct timeval tv; tv.tv_sec = openTO; tv.tv_usec = 0; ldapReturnCode = ldap_result(inLDAPHost, bindMsgId, 0, &tv, &result); } if ( ldapReturnCode == -1 ) { throw( (sInt32)eDSCannotAccessSession ); } else if ( ldapReturnCode == 0 ) { // timed out, let's forget it ldap_abandon(inLDAPHost, bindMsgId); //log this timed out connection if (pConfig != nil) { syslog(LOG_INFO,"DSLDAPv3PlugIn: Timed out in attempt to bind to [%s] LDAP server.", pConfig->fServerName); syslog(LOG_INFO,"DSLDAPv3PlugIn: Disabled future attempts to bind to [%s] LDAP server for next %d seconds.", pConfig->fServerName, inLDAPNodeStruct->fDelayRebindTry); } else { syslog(LOG_INFO,"DSLDAPv3PlugIn: Timed out in attempt to bind to [%s] LDAP server.", inLDAPNodeStruct->fServerName); syslog(LOG_INFO,"DSLDAPv3PlugIn: Disabled future attempts to bind to [%s] LDAP server for next %d seconds.", inLDAPNodeStruct->fServerName, inLDAPNodeStruct->fDelayRebindTry); } //NN fLDAPNodeOpenMutex.Wait(); inLDAPNodeStruct->bHasFailed = true; inLDAPNodeStruct->fDelayedBindTime = time( nil ) + inLDAPNodeStruct->fDelayRebindTry; //NN fLDAPNodeOpenMutex.Signal(); throw( (sInt32)eDSCannotAccessSession ); } else if ( ldap_result2error(inLDAPHost, result, 1) != LDAP_SUCCESS ) { //NN fLDAPNodeOpenMutex.Wait(); inLDAPNodeStruct->bHasFailed = true; inLDAPNodeStruct->fHost = inLDAPHost; //NN fLDAPNodeOpenMutex.Signal(); throw( (sInt32)eDSCannotAccessSession ); } //NN fLDAPNodeOpenMutex.Wait(); inLDAPNodeStruct->fHost = inLDAPHost; //NN fLDAPNodeOpenMutex.Signal(); //result is consumed above within ldap_result2error result = nil; } } // try catch ( sInt32 err ) { siResult = err; } if (ldapAcct != nil) { delete (ldapAcct); ldapAcct = nil; } if (ldapPasswd != nil) { delete (ldapPasswd); ldapPasswd = nil; } if (inLDAPNodeStruct->fLDAPSessionMutex != nil) { inLDAPNodeStruct->fLDAPSessionMutex->Signal(); } return (siResult); }// BindProc
static switch_xml_t xml_ldap_search(const char *section, const char *tag_name, const char *key_name, const char *key_value, switch_event_t *params, void *user_data) { xml_binding_t *binding = (xml_binding_t *) user_data; switch_event_header_t *hi; switch_xml_t xml = NULL, sub = NULL; struct ldap_c ldap_connection; struct ldap_c *ldap = &ldap_connection; int auth_method = LDAP_AUTH_SIMPLE; int desired_version = LDAP_VERSION3; xml_ldap_query_type_t query_type; char *dir_exten = NULL, *dir_domain = NULL; char *search_filter = NULL, *search_base = NULL; int off = 0, ret = 1; //char *buf; //buf = malloc(4096); if (!binding) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "No bindings...sorry bud returning now\n"); return NULL; } if (!strcmp(section, "configuration")) { query_type = XML_LDAP_CONFIG; } else if (!strcmp(section, "directory")) { query_type = XML_LDAP_DIRECTORY; } else if (!strcmp(section, "dialplan")) { query_type = XML_LDAP_DIALPLAN; } else if (!strcmp(section, "phrases")) { query_type = XML_LDAP_PHRASE; } else if (!strcmp(section, "languages")) { query_type = XML_LDAP_LANGUAGE; } else { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid section\n"); return NULL; } if (params) { if ((hi = params->headers)) { for (; hi; hi = hi->next) { switch (query_type) { case XML_LDAP_CONFIG: break; case XML_LDAP_DIRECTORY: if (!strcmp(hi->name, "user")) { dir_exten = strdup(hi->value); } else if (!strcmp(hi->name, "domain")) { dir_domain = strdup(hi->value); } break; case XML_LDAP_DIALPLAN: case XML_LDAP_PHRASE: case XML_LDAP_LANGUAGE: break; } } switch (query_type) { case XML_LDAP_CONFIG: break; case XML_LDAP_DIRECTORY: if (dir_exten && dir_domain) { if ((xml = switch_xml_new("directory"))) { switch_xml_set_attr_d(xml, "type", "freeswitch/xml"); if ((sub = switch_xml_add_child_d(xml, "section", off++))) { switch_xml_set_attr_d(sub, "name", "directory"); } if ((sub = switch_xml_add_child_d(sub, "domain", off++))) { switch_xml_set_attr_d(sub, "name", dir_domain); } if ((sub = switch_xml_add_child_d(sub, "user", off++))) { switch_xml_set_attr_d(sub, "id", dir_exten); } } search_filter = switch_mprintf(binding->filter, dir_exten); search_base = switch_mprintf(binding->basedn, dir_domain); free(dir_exten); dir_exten = NULL; free(dir_domain); dir_domain = NULL; } else { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Something bad happened during the query construction phase likely exten(%s) or domain(%s) is null\n", dir_exten, dir_domain); goto cleanup; } break; case XML_LDAP_DIALPLAN: if ((xml = switch_xml_new("document"))) { switch_xml_set_attr_d(xml, "type", "freeswitch/xml"); if ((sub = switch_xml_add_child_d(xml, "section", off++))) { switch_xml_set_attr_d(sub, "name", "dialplan"); } sub = switch_xml_add_child_d(xml, "context", off++); } break; case XML_LDAP_PHRASE: case XML_LDAP_LANGUAGE: break; } } else { goto cleanup; } } if ((ldap->ld = (LDAP *) ldap_init(binding->host, LDAP_PORT)) == NULL) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Unable to connect to ldap server.%s\n", binding->host); goto cleanup; } if (ldap_set_option(ldap->ld, LDAP_OPT_PROTOCOL_VERSION, &desired_version) != LDAP_OPT_SUCCESS) { goto cleanup; } ldap_set_option(ldap->ld, LDAP_OPT_X_SASL_SECPROPS, &ldap->sp); if (binding->binddn) { if (ldap_bind_s(ldap->ld, binding->binddn, binding->bindpass, auth_method) != LDAP_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Unable to bind to ldap server %s as %s\n", binding->host, binding->binddn); goto cleanup; } } else { if (ldap_sasl_interactive_bind_s (ldap->ld, NULL, binding->defaults->mech, NULL, NULL, (unsigned) (intptr_t) LDAP_SASL_SIMPLE, lutil_sasl_interact, binding->defaults) != LDAP_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Unable to sasl_bind to ldap server %s as %s\n", binding->host, binding->defaults->authcid); goto cleanup; } } if (ldap_search_s(ldap->ld, search_base, LDAP_SCOPE_SUBTREE, search_filter, NULL, 0, &ldap->msg) != LDAP_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Query failed: -b \"%s\" \"%s\"\n", search_base, search_filter); goto cleanup; } if (ldap_count_entries(ldap->ld, ldap->msg) <= 0) { goto cleanup; } if (sub && xml_ldap_result(&ldap_connection, binding, &sub, &off, query_type) != SWITCH_STATUS_SUCCESS) { goto cleanup; } ret = 0; cleanup: if (ldap->msg) { ldap_msgfree(ldap->msg); } if (ldap->ld) { ldap_unbind_s(ldap->ld); } switch_safe_free(search_filter); switch_safe_free(search_base); //switch_xml_toxml_buf(xml,buf,0,0,1); //switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Providing:\n%s\n", buf); if (ret) { switch_xml_free(xml); return NULL; } return xml; }
static CURLcode Curl_ldap(struct connectdata *conn, bool *done) { CURLcode result = CURLE_OK; int rc = 0; LDAP *server = NULL; LDAPURLDesc *ludp = NULL; LDAPMessage *ldapmsg = NULL; LDAPMessage *entryIterator; int num = 0; struct SessionHandle *data=conn->data; int ldap_proto = LDAP_VERSION3; int ldap_ssl = 0; char *val_b64 = NULL; size_t val_b64_sz = 0; curl_off_t dlsize = 0; #ifdef LDAP_OPT_NETWORK_TIMEOUT struct timeval ldap_timeout = {10,0}; /* 10 sec connection/search timeout */ #endif *done = TRUE; /* unconditionally */ infof(data, "LDAP local: LDAP Vendor = %s ; LDAP Version = %d\n", LDAP_VENDOR_NAME, LDAP_VENDOR_VERSION); infof(data, "LDAP local: %s\n", data->change.url); #ifdef HAVE_LDAP_URL_PARSE rc = ldap_url_parse(data->change.url, &ludp); #else rc = _ldap_url_parse(conn, &ludp); #endif if(rc != 0) { failf(data, "LDAP local: %s", ldap_err2string(rc)); result = CURLE_LDAP_INVALID_URL; goto quit; } /* Get the URL scheme ( either ldap or ldaps ) */ if(conn->given->flags & PROTOPT_SSL) ldap_ssl = 1; infof(data, "LDAP local: trying to establish %s connection\n", ldap_ssl ? "encrypted" : "cleartext"); #ifdef LDAP_OPT_NETWORK_TIMEOUT ldap_set_option(NULL, LDAP_OPT_NETWORK_TIMEOUT, &ldap_timeout); #endif ldap_set_option(NULL, LDAP_OPT_PROTOCOL_VERSION, &ldap_proto); if(ldap_ssl) { #ifdef HAVE_LDAP_SSL #ifdef CURL_LDAP_WIN /* Win32 LDAP SDK doesn't support insecure mode without CA! */ server = ldap_sslinit(conn->host.name, (int)conn->port, 1); ldap_set_option(server, LDAP_OPT_SSL, LDAP_OPT_ON); #else int ldap_option; char* ldap_ca = data->set.str[STRING_SSL_CAFILE]; #if defined(CURL_HAS_NOVELL_LDAPSDK) rc = ldapssl_client_init(NULL, NULL); if(rc != LDAP_SUCCESS) { failf(data, "LDAP local: ldapssl_client_init %s", ldap_err2string(rc)); result = CURLE_SSL_CERTPROBLEM; goto quit; } if(data->set.ssl.verifypeer) { /* Novell SDK supports DER or BASE64 files. */ int cert_type = LDAPSSL_CERT_FILETYPE_B64; if((data->set.str[STRING_CERT_TYPE]) && (Curl_raw_equal(data->set.str[STRING_CERT_TYPE], "DER"))) cert_type = LDAPSSL_CERT_FILETYPE_DER; if(!ldap_ca) { failf(data, "LDAP local: ERROR %s CA cert not set!", (cert_type == LDAPSSL_CERT_FILETYPE_DER ? "DER" : "PEM")); result = CURLE_SSL_CERTPROBLEM; goto quit; } infof(data, "LDAP local: using %s CA cert '%s'\n", (cert_type == LDAPSSL_CERT_FILETYPE_DER ? "DER" : "PEM"), ldap_ca); rc = ldapssl_add_trusted_cert(ldap_ca, cert_type); if(rc != LDAP_SUCCESS) { failf(data, "LDAP local: ERROR setting %s CA cert: %s", (cert_type == LDAPSSL_CERT_FILETYPE_DER ? "DER" : "PEM"), ldap_err2string(rc)); result = CURLE_SSL_CERTPROBLEM; goto quit; } ldap_option = LDAPSSL_VERIFY_SERVER; } else ldap_option = LDAPSSL_VERIFY_NONE; rc = ldapssl_set_verify_mode(ldap_option); if(rc != LDAP_SUCCESS) { failf(data, "LDAP local: ERROR setting cert verify mode: %s", ldap_err2string(rc)); result = CURLE_SSL_CERTPROBLEM; goto quit; } server = ldapssl_init(conn->host.name, (int)conn->port, 1); if(server == NULL) { failf(data, "LDAP local: Cannot connect to %s:%ld", conn->host.name, conn->port); result = CURLE_COULDNT_CONNECT; goto quit; } #elif defined(LDAP_OPT_X_TLS) if(data->set.ssl.verifypeer) { /* OpenLDAP SDK supports BASE64 files. */ if((data->set.str[STRING_CERT_TYPE]) && (!Curl_raw_equal(data->set.str[STRING_CERT_TYPE], "PEM"))) { failf(data, "LDAP local: ERROR OpenLDAP only supports PEM cert-type!"); result = CURLE_SSL_CERTPROBLEM; goto quit; } if(!ldap_ca) { failf(data, "LDAP local: ERROR PEM CA cert not set!"); result = CURLE_SSL_CERTPROBLEM; goto quit; } infof(data, "LDAP local: using PEM CA cert: %s\n", ldap_ca); rc = ldap_set_option(NULL, LDAP_OPT_X_TLS_CACERTFILE, ldap_ca); if(rc != LDAP_SUCCESS) { failf(data, "LDAP local: ERROR setting PEM CA cert: %s", ldap_err2string(rc)); result = CURLE_SSL_CERTPROBLEM; goto quit; } ldap_option = LDAP_OPT_X_TLS_DEMAND; } else ldap_option = LDAP_OPT_X_TLS_NEVER; rc = ldap_set_option(NULL, LDAP_OPT_X_TLS_REQUIRE_CERT, &ldap_option); if(rc != LDAP_SUCCESS) { failf(data, "LDAP local: ERROR setting cert verify mode: %s", ldap_err2string(rc)); result = CURLE_SSL_CERTPROBLEM; goto quit; } server = ldap_init(conn->host.name, (int)conn->port); if(server == NULL) { failf(data, "LDAP local: Cannot connect to %s:%ld", conn->host.name, conn->port); result = CURLE_COULDNT_CONNECT; goto quit; } ldap_option = LDAP_OPT_X_TLS_HARD; rc = ldap_set_option(server, LDAP_OPT_X_TLS, &ldap_option); if(rc != LDAP_SUCCESS) { failf(data, "LDAP local: ERROR setting SSL/TLS mode: %s", ldap_err2string(rc)); result = CURLE_SSL_CERTPROBLEM; goto quit; } /* rc = ldap_start_tls_s(server, NULL, NULL); if(rc != LDAP_SUCCESS) { failf(data, "LDAP local: ERROR starting SSL/TLS mode: %s", ldap_err2string(rc)); result = CURLE_SSL_CERTPROBLEM; goto quit; } */ #else /* we should probably never come up to here since configure should check in first place if we can support LDAP SSL/TLS */ failf(data, "LDAP local: SSL/TLS not supported with this version " "of the OpenLDAP toolkit\n"); result = CURLE_SSL_CERTPROBLEM; goto quit; #endif #endif #endif /* CURL_LDAP_USE_SSL */ } else { server = ldap_init(conn->host.name, (int)conn->port); if(server == NULL) { failf(data, "LDAP local: Cannot connect to %s:%ld", conn->host.name, conn->port); result = CURLE_COULDNT_CONNECT; goto quit; } } #ifdef CURL_LDAP_WIN ldap_set_option(server, LDAP_OPT_PROTOCOL_VERSION, &ldap_proto); #endif rc = ldap_simple_bind_s(server, conn->bits.user_passwd ? conn->user : NULL, conn->bits.user_passwd ? conn->passwd : NULL); if(!ldap_ssl && rc != 0) { ldap_proto = LDAP_VERSION2; ldap_set_option(server, LDAP_OPT_PROTOCOL_VERSION, &ldap_proto); rc = ldap_simple_bind_s(server, conn->bits.user_passwd ? conn->user : NULL, conn->bits.user_passwd ? conn->passwd : NULL); } if(rc != 0) { failf(data, "LDAP local: ldap_simple_bind_s %s", ldap_err2string(rc)); result = CURLE_LDAP_CANNOT_BIND; goto quit; } rc = ldap_search_s(server, ludp->lud_dn, ludp->lud_scope, ludp->lud_filter, ludp->lud_attrs, 0, &ldapmsg); if(rc != 0 && rc != LDAP_SIZELIMIT_EXCEEDED) { failf(data, "LDAP remote: %s", ldap_err2string(rc)); result = CURLE_LDAP_SEARCH_FAILED; goto quit; } for(num = 0, entryIterator = ldap_first_entry(server, ldapmsg); entryIterator; entryIterator = ldap_next_entry(server, entryIterator), num++) { BerElement *ber = NULL; char *attribute; /*! suspicious that this isn't 'const' */ char *dn = ldap_get_dn(server, entryIterator); int i; result = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"DN: ", 4); if(result) goto quit; result = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)dn, 0); if(result) goto quit; result = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"\n", 1); if(result) goto quit; dlsize += strlen(dn)+5; for(attribute = ldap_first_attribute(server, entryIterator, &ber); attribute; attribute = ldap_next_attribute(server, entryIterator, ber)) { BerValue **vals = ldap_get_values_len(server, entryIterator, attribute); if(vals != NULL) { for(i = 0; (vals[i] != NULL); i++) { result = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"\t", 1); if(result) goto quit; result = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)attribute, 0); if(result) goto quit; result = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)": ", 2); if(result) goto quit; dlsize += strlen(attribute)+3; if((strlen(attribute) > 7) && (strcmp(";binary", (char *)attribute + (strlen((char *)attribute) - 7)) == 0)) { /* Binary attribute, encode to base64. */ CURLcode error = Curl_base64_encode(data, vals[i]->bv_val, vals[i]->bv_len, &val_b64, &val_b64_sz); if(error) { ldap_value_free_len(vals); ldap_memfree(attribute); ldap_memfree(dn); if(ber) ber_free(ber, 0); result = error; goto quit; } if(val_b64_sz > 0) { result = Curl_client_write(conn, CLIENTWRITE_BODY, val_b64, val_b64_sz); free(val_b64); if(result) goto quit; dlsize += val_b64_sz; } } else { result = Curl_client_write(conn, CLIENTWRITE_BODY, vals[i]->bv_val, vals[i]->bv_len); if(result) goto quit; dlsize += vals[i]->bv_len; } result = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"\n", 0); if(result) goto quit; dlsize++; } /* Free memory used to store values */ ldap_value_free_len(vals); } result = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"\n", 1); if(result) goto quit; dlsize++; Curl_pgrsSetDownloadCounter(data, dlsize); ldap_memfree(attribute); } ldap_memfree(dn); if(ber) ber_free(ber, 0); } quit: if(ldapmsg) { ldap_msgfree(ldapmsg); LDAP_TRACE (("Received %d entries\n", num)); } if(rc == LDAP_SIZELIMIT_EXCEEDED) infof(data, "There are more than %d entries\n", num); if(ludp) ldap_free_urldesc(ludp); if(server) ldap_unbind_s(server); #if defined(HAVE_LDAP_SSL) && defined(CURL_HAS_NOVELL_LDAPSDK) if(ldap_ssl) ldapssl_client_deinit(); #endif /* HAVE_LDAP_SSL && CURL_HAS_NOVELL_LDAPSDK */ /* no data to transfer */ Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL); connclose(conn, "LDAP connection always disable re-use"); return result; }
static int do_init (LDAP ** ld, const char *uri, int ldapdefport) { int rc; int ldaps; char uribuf[512]; char *p; DBG("do_init():"); ldaps = (strncasecmp (uri, "ldaps://", sizeof ("ldaps://") - 1) == 0); p = strchr (uri, ':'); /* we should be looking for the second instance to find the port number */ if (p != NULL) { p = strchr (p, ':'); } #ifdef HAVE_LDAP_INITIALIZE if (p == NULL && ((ldaps && ldapdefport != LDAPS_PORT) || (!ldaps && ldapdefport != LDAP_PORT))) { /* No port specified in URI and non-default port specified */ snprintf (uribuf, sizeof (uribuf), "%s:%d", uri, ldapdefport); uri = uribuf; } rc = ldap_initialize (ld, uri); #else /* TODO: !HAVE_LDAP_INITIALIZE => no ldaps:// possible? */ if (strncasecmp (uri, "ldap://", sizeof ("ldap://") - 1) != 0) { return LDAP_UNAVAILABLE; } uri += sizeof ("ldap://") - 1; p = strchr (uri, ':'); if (p != NULL) { size_t urilen = (p - uri); if (urilen >= sizeof (uribuf)) { return LDAP_UNAVAILABLE; } memcpy (uribuf, uri, urilen); uribuf[urilen] = '\0'; ldapdefport = atoi (p + 1); uri = uribuf; } # ifdef HAVE_LDAP_INIT *ld = ldap_init (uri, ldapdefport); # else *ld = ldap_open (uri, ldapdefport); # endif rc = (*ld == NULL) ? LDAP_SERVER_DOWN : LDAP_SUCCESS; #endif /* HAVE_LDAP_INITIALIZE */ if (rc == LDAP_SUCCESS && *ld == NULL) { rc = LDAP_UNAVAILABLE; } return rc; }
static void ldapconnect(void) { int rc; /* On Windows ldap_start_tls_s is available starting from Windows XP, * so we need to bind at run-time with the function entry point */ #ifdef _SQUID_MSWIN_ if (use_tls) { HMODULE WLDAP32Handle; WLDAP32Handle = GetModuleHandle("wldap32"); if ((Win32_ldap_start_tls_s = (PFldap_start_tls_s) GetProcAddress(WLDAP32Handle, LDAP_START_TLS_S)) == NULL) { fprintf(stderr, PROGRAM_NAME ": ERROR: TLS (-Z) not supported on this platform.\n"); exit(1); } } #endif if (ld == NULL) { #if HAS_URI_SUPPORT if (strstr(ldapServer, "://") != NULL) { rc = ldap_initialize(&ld, ldapServer); if (rc != LDAP_SUCCESS) { fprintf(stderr, "\nUnable to connect to LDAPURI:%s\n", ldapServer); } } else #endif #if NETSCAPE_SSL if (sslpath) { if (!sslinit && (ldapssl_client_init(sslpath, NULL) != LDAP_SUCCESS)) { fprintf(stderr, "\nUnable to initialise SSL with cert path %s\n", sslpath); exit(1); } else { sslinit++; } if ((ld = ldapssl_init(ldapServer, port, 1)) == NULL) { fprintf(stderr, "\nUnable to connect to SSL LDAP server: %s port:%d\n", ldapServer, port); exit(1); } } else #endif if ((ld = ldap_init(ldapServer, port)) == NULL) { fprintf(stderr, "\nUnable to connect to LDAP server:%s port:%d\n", ldapServer, port); } if (connect_timeout) squid_ldap_set_connect_timeout(connect_timeout); #ifdef LDAP_VERSION3 if (version == -1) { version = LDAP_VERSION2; } if (ldap_set_option(ld, LDAP_OPT_PROTOCOL_VERSION, &version) != LDAP_SUCCESS) { fprintf(stderr, "Could not set LDAP_OPT_PROTOCOL_VERSION %d\n", version); ldap_unbind(ld); ld = NULL; } if (use_tls) { #ifdef LDAP_OPT_X_TLS if ((version == LDAP_VERSION3) && (ldap_start_tls_s(ld, NULL, NULL) == LDAP_SUCCESS)) { fprintf(stderr, "Could not Activate TLS connection\n"); ldap_unbind(ld); ld = NULL; } #else fprintf(stderr, "TLS not supported with your LDAP library\n"); ldap_unbind(ld); ld = NULL; #endif } #endif squid_ldap_set_timelimit(timelimit); squid_ldap_set_referrals(!noreferrals); squid_ldap_set_aliasderef(aliasderef); if (binddn && bindpasswd && *binddn && *bindpasswd) { rc = ldap_simple_bind_s(ld, binddn, bindpasswd); if (rc != LDAP_SUCCESS) { fprintf(stderr, PROGRAM_NAME " WARNING, could not bind to binddn '%s'\n", ldap_err2string(rc)); ldap_unbind(ld); ld = NULL; } } if (debug) fprintf(stderr, "Connected OK\n"); } }
LDAP * cldap_open( char *host, int port ) { int s; in_addr_t address; struct sockaddr_in sock; struct hostent *hp; LDAP *ld; char *p; int i; #ifdef SUN struct hostent hpret; char hpbuf[NSS_BUFLEN_HOSTS]; int hperrno; #endif in_addr_t inet_addr(const char *); int close(int); Debug( LDAP_DEBUG_TRACE, catgets(slapdcat, 1, 113, "ldap_open\n"), 0, 0, 0 ); if ( port == 0 ) { port = LDAP_PORT; } if ( (s = socket( AF_INET, SOCK_DGRAM, 0 )) < 0 ) { return( NULL ); } sock.sin_addr.s_addr = 0; sock.sin_family = AF_INET; sock.sin_port = 0; if ( bind(s, (struct sockaddr *) &sock, sizeof(sock)) < 0) { close( s ); return( NULL ); } if (( ld = ldap_init( host, port )) == NULL ) { close( s ); return( NULL ); } if ( (ld->ld_sb.sb_fromaddr = (void *) calloc( 1, sizeof( struct sockaddr ))) == NULL ) { free( ld ); close( s ); return( NULL ); } ld->ld_sb.sb_sd = s; ld->ld_sb.sb_naddr = 0; ld->ld_version = LDAP_VERSION; sock.sin_family = AF_INET; sock.sin_port = htons( port ); /* * 'host' may be a space-separated list. */ if ( host != NULL ) { for ( ; host != NULL; host = p ) { if (( p = strchr( host, ' ' )) != NULL ) { for (*p++ = '\0'; *p == ' '; p++) { ; } } if ( (address = inet_addr( host )) == -1 ) { #ifdef SUN if ( (hp = gethostbyname_r( host, &hpret, hpbuf, NSS_BUFLEN_HOSTS, &hperrno)) == NULL ) { errno = EHOSTUNREACH; continue; } #else if ( (hp = gethostbyname( host )) == NULL ) { errno = EHOSTUNREACH; continue; } #endif for ( i = 0; hp->h_addr_list[ i ] != 0; ++i ) { SAFEMEMCPY( (char *)&sock.sin_addr.s_addr, (char *)hp->h_addr_list[ i ], sizeof(sock.sin_addr.s_addr)); if ( add_addr( ld, (struct sockaddr *)&sock ) < 0 ) { close( s ); free( ld ); return( NULL ); } } } else { sock.sin_addr.s_addr = address; if ( add_addr( ld, (struct sockaddr *)&sock ) < 0 ) { close( s ); free( ld ); return( NULL ); } } if ( ld->ld_host == NULL ) { ld->ld_host = strdup( host ); } } } else { address = INADDR_LOOPBACK; sock.sin_addr.s_addr = htonl( address ); if ( add_addr( ld, (struct sockaddr *)&sock ) < 0 ) { close( s ); free( ld ); return( NULL ); } } if ( ld->ld_sb.sb_addrs == NULL #ifdef LDAP_REFERRALS || ( ld->ld_defconn = new_connection( ld, NULL, 1,0,0 )) == NULL #endif /* LDAP_REFERRALS */ ) { free( ld ); return( NULL ); } ld->ld_sb.sb_useaddr = ld->ld_sb.sb_addrs[ 0 ]; cldap_setretryinfo( ld, 0, 0 ); #ifdef LDAP_DEBUG putchar( '\n' ); for ( i = 0; i < ld->ld_sb.sb_naddr; ++i ) { Debug( LDAP_DEBUG_TRACE, catgets(slapdcat, 1, 114, "end of cldap_open address %1$d is %2$s\n"), i, inet_ntoa( ((struct sockaddr_in *) ld->ld_sb.sb_addrs[ i ])->sin_addr ), 0 ); } #endif return( ld ); }
/** LDAP* open_ldap_connection(char* fn) 設定ファイルを読み込み後,LDAPサーバに接続する @param fn 設定の格納されたファイル名.fn, /etc/openldap/ldap.conf, /etc/ldap.conf を順に読んで大域変数 JBXLdapHost, JBXLdapDnBind に情報を格納する. @return LDAPサーバへのセッションハンドラ.接続に失敗した場合は NULL */ LDAP* open_ldap_connection(char* fn) { if (JBXLdapHost==NULL||JBXLdapDnBind==NULL||fn!=NULL) read_ldap_config_file(fn); if (JBXLdapHost==NULL||JBXLdapDnBind==NULL) return NULL; if (JBXLdapDnBind->dnbind.buf==NULL) return NULL; if (JBXLdapDnBind->passwd.buf==NULL) return NULL; if (JBXLdapDnBind->passwd.buf[0]=='\0') return NULL; if (JBXLdapHost->hostname.buf==NULL) return NULL; if (JBXLdapHost->port<=0) return NULL; int ret; LDAP* ld = NULL; if (JBXLdapHost->useSSL!=TRUE || JBXLdapHost->port==389) { DEBUG_MODE print_message("INFO LDAP NORMAL Mode\n"); ld = ldap_init((char*)JBXLdapHost->hostname.buf, JBXLdapHost->port); if (ld==NULL) { DEBUG_MODE print_message("ERR LDAP Init error.\n"); return NULL; } if (JBXLdapHost->useSSL==TRUE) { // STARTTLS (動作未確認) DEBUG_MODE print_message("INFO LDAP STARTTLS Mode\n"); ret = ldap_set_option(NULL, LDAP_OPT_X_TLS_REQUIRE_CERT, &JBXLdapHost->reqCert); if (ret!=LDAP_SUCCESS) { DEBUG_MODE print_message("ERR LDAP STARTTLS Require Cert = %s\n", ldap_err2string(ret)); ldap_unbind_s(ld); return NULL; } int ldap_vers = LDAP_VERSION3; ret = ldap_set_option(ld, LDAP_OPT_PROTOCOL_VERSION, &ldap_vers); if (ret!=LDAP_SUCCESS) { DEBUG_MODE print_message("ERR LDAP STARTTLS Version = %s\n", ldap_err2string(ret)); ldap_unbind_s(ld); return NULL; } // ret = ldap_start_tls_s(ld, NULL, NULL); if (ret!=LDAP_SUCCESS) { DEBUG_MODE print_message("ERR LDAP STARTTLS Start = %s\n", ldap_err2string(ret)); ldap_unbind_s(ld); return NULL; } } } // else { // LDAP over SSL DEBUG_MODE print_message("INFO LDAP Over SSL Mode\n"); Buffer url = make_Buffer_bystr("ldaps://"); cat_Buffer(&JBXLdapHost->hostname, &url); cat_s2Buffer(":", &url); cat_s2Buffer(itostr(JBXLdapHost->port), &url); DEBUG_MODE print_message("INFO LDAP SSL URL = %s\n", (char*)url.buf); // ret = ldap_initialize(&ld, (char*)url.buf); free_Buffer(&url); if (ret!=LDAP_SUCCESS) { DEBUG_MODE print_message("ERR LDAP SSL Init = %s\n", ldap_err2string(ret)); return NULL; } // ret = ldap_set_option(NULL, LDAP_OPT_X_TLS_REQUIRE_CERT, &JBXLdapHost->reqCert); if (ret!=LDAP_SUCCESS) { DEBUG_MODE print_message("ERR LDAP SSL Require Cert = %s\n", ldap_err2string(ret)); ldap_unbind_s(ld); return NULL; } } ret = ldap_simple_bind_s(ld, (char*)JBXLdapDnBind->dnbind.buf, (char*)JBXLdapDnBind->passwd.buf); if (ret!=LDAP_SUCCESS) { DEBUG_MODE print_message("ERR LDAP Bind = %s\n", ldap_err2string(ret)); ldap_unbind_s(ld); return NULL; } return ld; }
static int ldap_pap_auth(char *user, char *password, char **msgp, struct wordlist **paddrs, struct wordlist **popts) { int rc,ldap_errno; int version = LDAP_VERSION3; char filter[LDAP_FILT_MAXSIZ]; char userdn[MAX_BUF]; char **ldap_values; LDAP *ldap; LDAPMessage *ldap_mesg; LDAPMessage *ldap_entry; /* Initiate session and bind to LDAP server */ if ((ldap = ldap_init(ldap_host, ldap_port)) == NULL) { error("LDAP: failed to initialize session\n"); return -1; } /* Set LDAP specific options such as timeout, version and tls */ if ((rc = ldap_set_option(ldap, LDAP_OPT_PROTOCOL_VERSION, &version) != LDAP_OPT_SUCCESS)) { error("LDAP: failed to set protocol version\n"); return -1; } if ((rc = ldap_set_option(ldap, LDAP_OPT_NETWORK_TIMEOUT, &ldap_nettimeout) != LDAP_OPT_SUCCESS)) { error("LDAP: failed to set network timeout version\n"); return -1; } if ((rc = ldap_set_option(ldap, LDAP_OPT_TIMELIMIT, &ldap_timeout) != LDAP_OPT_SUCCESS)) { error("LDAP: failed to set timeout option\n"); return -1; } #ifdef OPT_WITH_TLS /* Some servers support only LDAPS but not TLS */ if ((ldap_port == LDAPS_PORT) && ldap_usetls) { int tls_opt = LDAP_OPT_X_TLS_HARD; if ((rc = ldap_set_option(ldap, LDAP_OPT_X_TLS, (void *)&tls_opt)) != LDAP_SUCCESS) { ldap_get_option(ldap, LDAP_OPT_ERROR_NUMBER, &ldap_errno); error("LDAP: failed to set TLS option: %s\n", ldap_err2string(rc)); return -1; } } if (ldap_usetls) { #ifdef DEBUG info("LDAP: Setting TLS option -> ON\n"); #endif if((rc = ldap_start_tls_s(ldap, NULL, NULL) != LDAP_SUCCESS)) { ldap_get_option(ldap, LDAP_OPT_ERROR_NUMBER, &ldap_errno); error("LDAP: failed to initiate TLS: %s\n", ldap_err2string(ldap_errno)); return -1; } } #endif /* Perform binding at last */ if ((rc = ldap_bind_s(ldap, ldap_dn, ldap_pw, LDAP_AUTH_SIMPLE)) != LDAP_SUCCESS) { ldap_get_option(ldap, LDAP_OPT_ERROR_NUMBER, &ldap_errno); error("LDAP: failed to bind: %s\n",ldap_err2string(rc)); ldap_unbind(ldap); return -1; } /* Form a search filter from supplied peer's credentials */ if ((rc = snprintf(filter, LDAP_FILT_MAXSIZ,"(uid=%s)", user)) == -1) { error("LDAP: LDAP filter too big\n"); ldap_unbind(ldap); return -1; }; #ifdef DEBUG info("LDAP: search filter: %s\n",filter); #endif /* Perform search*/ if ((rc = ldap_search_s(ldap, userbasedn, LDAP_SCOPE_SUBTREE, filter, NULL, 0, &ldap_mesg)) != LDAP_SUCCESS) { ldap_get_option(ldap, LDAP_OPT_ERROR_NUMBER, &ldap_errno); error("LDAP: Can't perform search: %s\n", ldap_err2string(rc)); ldap_unbind(ldap); return -1; }; /* If search returned more than 2 results or 0 - something is wrong! */ if ( ldap_mesg == NULL ){ info("LDAP: No such user \"%s\"\n",user); ldap_unbind(ldap); return -1; } if ((ldap_count_entries(ldap, ldap_mesg)) > 1){ warn("LDAP: more than one user \"%s\" exists!\n",user); ldap_unbind(ldap); return -1; } /* Check existance of dialupAccess attribute and it's value */ #ifdef DEBUG info("LDAP: found %u entries\n",ldap_count_entries(ldap, ldap_mesg)); #endif ldap_entry = ldap_first_entry(ldap, ldap_mesg); if ((rc = snprintf(userdn,MAX_BUF,"%s",ldap_get_dn(ldap,ldap_entry))) == -1) warn("LDAP: user DN stripped\n"); #ifdef DEBUG info("LDAP: rebind DN: %s\n",userdn); #endif if ((rc = ldap_simple_bind_s(ldap,userdn,password)) != LDAP_SUCCESS) { error("LDAP: username or password incorrect\n"); *msgp = "Username or password incorrect!"; ldap_unbind(ldap); ldap_msgfree(ldap_mesg); return 0; } /* Set pppd options */ ldap_setoptions(ldap, ldap_mesg, &ldap_data); #ifdef DEBUG info("LDAP: Auth success\n"); #endif *msgp = "Access OK!"; ldap_data.access_ok = 1; /* Write ppp_utmp data in place */ return 1; }
/* * fetches a binary blob from an ldap url */ static err_t fetch_ldap_url(char *url, chunk_t *blob) { LDAPURLDesc *lurl; err_t ugh = NULL; int rc; DBG(DBG_CONTROL, DBG_log("Trying LDAP URL '%s'", url) ) rc = ldap_url_parse(url, &lurl); if (rc == LDAP_SUCCESS) { LDAP *ldap = ldap_init(lurl->lud_host, lurl->lud_port); if (ldap != NULL) { int ldap_version = (LDAP_VER == 2)? LDAP_VERSION2 : LDAP_VERSION3; struct timeval timeout; timeout.tv_sec = FETCH_CMD_TIMEOUT; timeout.tv_usec = 0; ldap_set_option(ldap, LDAP_OPT_PROTOCOL_VERSION, &ldap_version); ldap_set_option(ldap, LDAP_OPT_NETWORK_TIMEOUT, &timeout); rc = ldap_simple_bind_s(ldap, NULL, NULL); if (rc == LDAP_SUCCESS) { LDAPMessage *result; timeout.tv_sec = FETCH_CMD_TIMEOUT; timeout.tv_usec = 0; rc = ldap_search_st(ldap, lurl->lud_dn , lurl->lud_scope , lurl->lud_filter , lurl->lud_attrs , 0, &timeout, &result); if (rc == LDAP_SUCCESS) { ugh = parse_ldap_result(ldap, result, blob); ldap_msgfree(result); } else { ugh = ldap_err2string(rc); } } else { ugh = ldap_err2string(rc); } ldap_unbind_s(ldap); } else { ugh = "ldap init"; } ldap_free_urldesc(lurl); } else { ugh = ldap_err2string(rc); } return ugh; }
handler_t auth_ldap_init(server *srv, mod_auth_plugin_config *s) { #ifdef USE_LDAP int ret; #if 0 if (s->auth_ldap_basedn->used == 0) { log_error_write(srv, __FILE__, __LINE__, "s", "ldap: auth.backend.ldap.base-dn has to be set"); return HANDLER_ERROR; } #endif if (s->auth_ldap_filter->used) { char *dollar; /* parse filter */ if (NULL == (dollar = strchr(s->auth_ldap_filter->ptr, '$'))) { log_error_write(srv, __FILE__, __LINE__, "s", "ldap: auth.backend.ldap.filter is missing a replace-operator '$'"); return HANDLER_ERROR; } buffer_copy_string_len(s->ldap_filter_pre, s->auth_ldap_filter->ptr, dollar - s->auth_ldap_filter->ptr); buffer_copy_string(s->ldap_filter_post, dollar+1); } if (s->auth_ldap_hostname->used) { if (NULL == (s->ldap = ldap_init(s->auth_ldap_hostname->ptr, LDAP_PORT))) { log_error_write(srv, __FILE__, __LINE__, "ss", "ldap ...", strerror(errno)); return HANDLER_ERROR; } ret = LDAP_VERSION3; if (LDAP_OPT_SUCCESS != (ret = ldap_set_option(s->ldap, LDAP_OPT_PROTOCOL_VERSION, &ret))) { log_error_write(srv, __FILE__, __LINE__, "ss", "ldap:", ldap_err2string(ret)); return HANDLER_ERROR; } if (s->auth_ldap_starttls) { /* if no CA file is given, it is ok, as we will use encryption * if the server requires a CAfile it will tell us */ if (!buffer_is_empty(s->auth_ldap_cafile)) { if (LDAP_OPT_SUCCESS != (ret = ldap_set_option(NULL, LDAP_OPT_X_TLS_CACERTFILE, s->auth_ldap_cafile->ptr))) { log_error_write(srv, __FILE__, __LINE__, "ss", "Loading CA certificate failed:", ldap_err2string(ret)); return HANDLER_ERROR; } } if (LDAP_OPT_SUCCESS != (ret = ldap_start_tls_s(s->ldap, NULL, NULL))) { log_error_write(srv, __FILE__, __LINE__, "ss", "ldap startTLS failed:", ldap_err2string(ret)); return HANDLER_ERROR; } } /* 1. */ if (s->auth_ldap_binddn->used) { if (LDAP_SUCCESS != (ret = ldap_simple_bind_s(s->ldap, s->auth_ldap_binddn->ptr, s->auth_ldap_bindpw->ptr))) { log_error_write(srv, __FILE__, __LINE__, "ss", "ldap:", ldap_err2string(ret)); return HANDLER_ERROR; } } else { if (LDAP_SUCCESS != (ret = ldap_simple_bind_s(s->ldap, NULL, NULL))) { log_error_write(srv, __FILE__, __LINE__, "ss", "ldap:", ldap_err2string(ret)); return HANDLER_ERROR; } } } #else log_error_write(srv, __FILE__, __LINE__, "s", "no ldap support available"); return HANDLER_ERROR; #endif return HANDLER_GO_ON; }
/* * This function will look in ldap id the token correspond to the * requested user. It will returns 0 for failure and 1 for success. * * For the moment ldaps is not supported. ldap serve can be on a * remote host. * * You need the following parameters in you pam config: * ldapserver= OR ldap_uri= * ldapdn= * user_attr= * yubi_attr= * */ static int authorize_user_token_ldap (struct cfg *cfg, const char *user, const char *token_id) { DBG(("called")); int retval = 0; int protocol; #ifdef HAVE_LIBLDAP LDAP *ld = NULL; LDAPMessage *result = NULL, *e; BerElement *ber; char *a; char *attrs[2] = {NULL, NULL}; struct berval **vals; int i, rc; char *find = NULL, *sr = NULL; if (cfg->user_attr == NULL) { DBG (("Trying to look up user to YubiKey mapping in LDAP, but user_attr not set!")); return 0; } if (cfg->yubi_attr == NULL) { DBG (("Trying to look up user to YubiKey mapping in LDAP, but yubi_attr not set!")); return 0; } if (cfg->ldapdn == NULL) { DBG (("Trying to look up user to YubiKey mapping in LDAP, but ldapdn not set!")); return 0; } /* Get a handle to an LDAP connection. */ if (cfg->ldap_uri) { rc = ldap_initialize (&ld, cfg->ldap_uri); if (rc != LDAP_SUCCESS) { DBG (("ldap_init: %s", ldap_err2string (rc))); retval = 0; goto done; } } else { if ((ld = ldap_init (cfg->ldapserver, PORT_NUMBER)) == NULL) { DBG (("ldap_init")); retval = 0; goto done; } } /* LDAPv2 is historical -- RFC3494. */ protocol = LDAP_VERSION3; ldap_set_option (ld, LDAP_OPT_PROTOCOL_VERSION, &protocol); /* Bind anonymously to the LDAP server. */ rc = ldap_simple_bind_s (ld, NULL, NULL); if (rc != LDAP_SUCCESS) { DBG (("ldap_simple_bind_s: %s", ldap_err2string (rc))); retval = 0; goto done; } /* Allocation of memory for search strings depending on input size */ find = malloc((strlen(cfg->user_attr)+strlen(cfg->ldapdn)+strlen(user)+3)*sizeof(char)); sprintf (find, "%s=%s,%s", cfg->user_attr, user, cfg->ldapdn); attrs[0] = (char *) cfg->yubi_attr; DBG(("LDAP : look up object '%s', ask for attribute '%s'", find, cfg->yubi_attr)); /* Search for the entry. */ if ((rc = ldap_search_ext_s (ld, find, LDAP_SCOPE_BASE, NULL, attrs, 0, NULL, NULL, LDAP_NO_LIMIT, LDAP_NO_LIMIT, &result)) != LDAP_SUCCESS) { DBG (("ldap_search_ext_s: %s", ldap_err2string (rc))); retval = 0; goto done; } e = ldap_first_entry (ld, result); if (e == NULL) { DBG (("No result from LDAP search")); } else { /* Iterate through each returned attribute. */ for (a = ldap_first_attribute (ld, e, &ber); a != NULL; a = ldap_next_attribute (ld, e, ber)) { if ((vals = ldap_get_values_len (ld, e, a)) != NULL) { /* Compare each value for the attribute against the token id. */ for (i = 0; vals[i] != NULL; i++) { if (!strncmp (token_id, vals[i]->bv_val, strlen (token_id))) { DBG (("Token Found :: %s", vals[i]->bv_val)); retval = 1; } else { DBG (("No match : (%s) %s != %s", a, vals[i]->bv_val, token_id)); } } ldap_value_free_len (vals); } ldap_memfree (a); } if (ber != NULL) ber_free (ber, 0); } done: if (result != NULL) ldap_msgfree (result); if (ld != NULL) ldap_unbind (ld); /* free memory allocated for search strings */ if (find != NULL) free(find); if (sr != NULL) free(sr); #else DBG (("Trying to use LDAP, but this function is not compiled in pam_yubico!!")); DBG (("Install libldap-dev and then recompile pam_yubico.")); #endif return retval; }
static void do_modrdn( char *uri, char *host, int port, char *manager, char *passwd, char *entry, int maxloop ) { LDAP *ld = NULL; int i; pid_t pid; char *DNs[2]; char *rdns[2]; pid = getpid(); DNs[0] = entry; DNs[1] = strdup( entry ); /* reverse the RDN, make new DN */ { char *p1, *p2; p1 = strchr( entry, '=' ) + 1; p2 = strchr( p1, ',' ); *p2 = '\0'; rdns[1] = strdup( entry ); *p2-- = ','; for (i = p1 - entry;p2 >= p1;) DNs[1][i++] = *p2--; DNs[1][i] = '\0'; rdns[0] = strdup( DNs[1] ); DNs[1][i] = ','; } if ( uri ) { ldap_initialize( &ld, uri ); } else { ld = ldap_init( host, port ); } if ( ld == NULL ) { perror( "ldap_init" ); exit( EXIT_FAILURE ); } { int version = LDAP_VERSION3; (void) ldap_set_option( ld, LDAP_OPT_PROTOCOL_VERSION, &version ); } if ( ldap_bind_s( ld, manager, passwd, LDAP_AUTH_SIMPLE ) != LDAP_SUCCESS ) { ldap_perror( ld, "ldap_bind" ); exit( EXIT_FAILURE ); } fprintf( stderr, "PID=%ld - Modrdn(%d): entry=\"%s\".\n", (long) pid, maxloop, entry ); for ( i = 0; i < maxloop; i++ ) { int rc; if (( rc = ldap_modrdn2_s( ld, DNs[0], rdns[0], 0 )) != LDAP_SUCCESS ) { ldap_perror( ld, "ldap_modrdn" ); if ( rc != LDAP_NO_SUCH_OBJECT ) break; continue; } if (( rc = ldap_modrdn2_s( ld, DNs[1], rdns[1], 1 )) != LDAP_SUCCESS ) { ldap_perror( ld, "ldap_modrdn" ); if ( rc != LDAP_NO_SUCH_OBJECT ) break; continue; } } fprintf( stderr, " PID=%ld - Modrdn done.\n", (long) pid ); ldap_unbind( ld ); }
CURLcode Curl_ldap(struct connectdata *conn) { CURLcode status = CURLE_OK; int rc; void *(*ldap_init)(char *, int); int (*ldap_simple_bind_s)(void *, char *, char *); int (*ldap_unbind_s)(void *); int (*ldap_url_parse)(char *, LDAPURLDesc **); void (*ldap_free_urldesc)(void *); int (*ldap_search_s)(void *, char *, int, char *, char **, int, void **); int (*ldap_search_st)(void *, char *, int, char *, char **, int, void *, void **); void *(*ldap_first_entry)(void *, void *); void *(*ldap_next_entry)(void *, void *); char *(*ldap_err2string)(int); char *(*ldap_get_dn)(void *, void *); char *(*ldap_first_attribute)(void *, void *, void **); char *(*ldap_next_attribute)(void *, void *, void *); char **(*ldap_get_values)(void *, void *, char *); void (*ldap_value_free)(char **); void (*ldap_memfree)(void *); void (*ber_free)(void *, int); void *server; LDAPURLDesc *ludp; void *result; void *entryIterator; void *ber; void *attribute; struct SessionHandle *data=conn->data; infof(data, "LDAP: %s\n", data->change.url); DynaOpen(); if (libldap == NULL) { failf(data, "The needed LDAP library/libraries couldn't be opened"); return CURLE_LIBRARY_NOT_FOUND; } /* The types are needed because ANSI C distinguishes between * pointer-to-object (data) and pointer-to-function. */ DYNA_GET_FUNCTION(void *(*)(char *, int), ldap_init); DYNA_GET_FUNCTION(int (*)(void *, char *, char *), ldap_simple_bind_s); DYNA_GET_FUNCTION(int (*)(void *), ldap_unbind_s); DYNA_GET_FUNCTION(int (*)(char *, LDAPURLDesc **), ldap_url_parse); DYNA_GET_FUNCTION(void (*)(void *), ldap_free_urldesc); DYNA_GET_FUNCTION(int (*)(void *, char *, int, char *, char **, int, void **), ldap_search_s); DYNA_GET_FUNCTION(int (*)(void *, char *, int, char *, char **, int, void *, void **), ldap_search_st); DYNA_GET_FUNCTION(void *(*)(void *, void *), ldap_first_entry); DYNA_GET_FUNCTION(void *(*)(void *, void *), ldap_next_entry); DYNA_GET_FUNCTION(char *(*)(int), ldap_err2string); DYNA_GET_FUNCTION(char *(*)(void *, void *), ldap_get_dn); DYNA_GET_FUNCTION(char *(*)(void *, void *, void **), ldap_first_attribute); DYNA_GET_FUNCTION(char *(*)(void *, void *, void *), ldap_next_attribute); DYNA_GET_FUNCTION(char **(*)(void *, void *, char *), ldap_get_values); DYNA_GET_FUNCTION(void (*)(char **), ldap_value_free); DYNA_GET_FUNCTION(void (*)(void *), ldap_memfree); DYNA_GET_FUNCTION(void (*)(void *, int), ber_free); server = ldap_init(conn->hostname, conn->port); if (server == NULL) { failf(data, "LDAP: Cannot connect to %s:%d", conn->hostname, conn->port); status = CURLE_COULDNT_CONNECT; } else { rc = ldap_simple_bind_s(server, conn->bits.user_passwd?conn->user:NULL, conn->bits.user_passwd?conn->passwd:NULL); if (rc != 0) { failf(data, "LDAP: %s", ldap_err2string(rc)); status = CURLE_LDAP_CANNOT_BIND; } else { rc = ldap_url_parse(data->change.url, &ludp); if (rc != 0) { failf(data, "LDAP: %s", ldap_err2string(rc)); status = CURLE_LDAP_INVALID_URL; } else { rc = ldap_search_s(server, ludp->lud_dn, ludp->lud_scope, ludp->lud_filter, ludp->lud_attrs, 0, &result); if (rc != 0) { failf(data, "LDAP: %s", ldap_err2string(rc)); status = CURLE_LDAP_SEARCH_FAILED; } else { for (entryIterator = ldap_first_entry(server, result); entryIterator; entryIterator = ldap_next_entry(server, entryIterator)) { char *dn = ldap_get_dn(server, entryIterator); char **vals; int i; Curl_client_write(data, CLIENTWRITE_BODY, (char *)"DN: ", 4); Curl_client_write(data, CLIENTWRITE_BODY, dn, 0); Curl_client_write(data, CLIENTWRITE_BODY, (char *)"\n", 1); for(attribute = ldap_first_attribute(server, entryIterator, &ber); attribute; attribute = ldap_next_attribute(server, entryIterator, ber) ) { vals = ldap_get_values(server, entryIterator, attribute); if (vals != NULL) { for(i = 0; (vals[i] != NULL); i++) { Curl_client_write(data, CLIENTWRITE_BODY, (char*)"\t", 1); Curl_client_write(data, CLIENTWRITE_BODY, attribute, 0); Curl_client_write(data, CLIENTWRITE_BODY, (char *)": ", 2); Curl_client_write(data, CLIENTWRITE_BODY, vals[i], 0); Curl_client_write(data, CLIENTWRITE_BODY, (char *)"\n", 0); } } /* Free memory used to store values */ ldap_value_free(vals); } Curl_client_write(data, CLIENTWRITE_BODY, (char *)"\n", 1); ldap_memfree(attribute); ldap_memfree(dn); if (ber) ber_free(ber, 0); } } ldap_free_urldesc(ludp); } ldap_unbind_s(server); } } DynaClose(); /* no data to transfer */ Curl_Transfer(conn, -1, -1, FALSE, NULL, -1, NULL); return status; }
int main( int argc, char **argv ) { LDAP *ld; LDAPMessage *result, *e; char *attrfail, *matched = NULL, *errmsg = NULL; char **vals, **referrals; int rc, parse_rc, version; unsigned long sortrc; LDAPControl *sortctrl = NULL; LDAPControl *requestctrls[ 2 ]; LDAPControl **resultctrls = NULL; LDAPsortkey **sortkeylist; /* Arrange for all connections to use LDAPv3 */ version = LDAP_VERSION3; if ( ldap_set_option( NULL, LDAP_OPT_PROTOCOL_VERSION, &version ) != 0 ) { fprintf( stderr, "ldap_set_option protocol version to %d failed\n", version ); return( 1 ); } /* Get a handle to an LDAP connection */ if ( (ld = ldap_init( MY_HOST, MY_PORT ) ) == NULL ) { perror( "ldap_init" ); return( 1 ); } /* Authenticate as Directory Manager */ if ( ldap_simple_bind_s( ld, MGR_DN, MGR_PW ) != LDAP_SUCCESS ) { ldap_perror( ld, "ldap_simple_bind_s" ); ldap_unbind( ld ); return( 1 ); } /* * Create a sort key list that specifies the sort order of the results. * Sort the results by last name first, then by first name. */ ldap_create_sort_keylist( &sortkeylist, "description -givenname" ); /* Create the sort control. */ rc = ldap_create_sort_control( ld, sortkeylist, 1, &sortctrl ); if ( rc != LDAP_SUCCESS ) { fprintf( stderr, "ldap_create_sort_control: %s\n", ldap_err2string( rc ) ); ldap_unbind( ld ); return( 1 ); } requestctrls[ 0 ] = sortctrl; requestctrls[ 1 ] = NULL; /* Search for all entries in Sunnyvale */ rc = ldap_search_ext_s( ld, PEOPLE_BASE, LDAP_SCOPE_SUBTREE, "(objectclass=person)", NULL, 0, requestctrls, NULL, NULL, 0, &result ); if ( rc != LDAP_SUCCESS ) { fprintf( stderr, "ldap_search_ext_s: %s\n", ldap_err2string( rc ) ); ldap_unbind( ld ); return( 1 ); } parse_rc = ldap_parse_result( ld, result, &rc, &matched, &errmsg, &referrals, &resultctrls, 0 ); if ( parse_rc != LDAP_SUCCESS ) { fprintf( stderr, "ldap_parse_result: %s\n", ldap_err2string( parse_rc ) ); ldap_unbind( ld ); return( 1 ); } if ( rc != LDAP_SUCCESS ) { fprintf( stderr, "ldap_search_ext_s: %s\n", ldap_err2string( rc ) ); if ( errmsg != NULL && *errmsg != '\0' ) { fprintf( stderr, "%s\n", errmsg ); } ldap_unbind( ld ); return( 1 ); } parse_rc = ldap_parse_sort_control( ld, resultctrls, &sortrc, &attrfail ); if ( parse_rc != LDAP_SUCCESS ) { fprintf( stderr, "ldap_parse_sort_control: %s\n", ldap_err2string( parse_rc ) ); ldap_unbind( ld ); return( 1 ); } if ( sortrc != LDAP_SUCCESS ) { fprintf( stderr, "Sort error: %s\n", ldap_err2string( sortrc )); if ( attrfail != NULL && *attrfail != '\0' ) { fprintf( stderr, "Bad attribute: %s\n", attrfail); } ldap_unbind( ld ); return( 1 ); } /* for each entry print out name + all attrs and values */ for ( e = ldap_first_entry( ld, result ); e != NULL; e = ldap_next_entry( ld, e ) ) { if ((vals = ldap_get_values( ld, e, "sn")) != NULL ) { if ( vals[0] != NULL ) { printf( "%s", vals[0] ); } ldap_value_free( vals ); } if ((vals = ldap_get_values( ld, e, "givenname")) != NULL ) { if ( vals[0] != NULL ) { printf( "\t%s", vals[0] ); } ldap_value_free( vals ); } putchar( '\n' ); } ldap_msgfree( result ); ldap_free_sort_keylist( sortkeylist ); ldap_control_free( sortctrl ); ldap_controls_free( resultctrls ); ldap_unbind( ld ); return( 0 ); }
/** Initialise libldap and check library versions * * @return * - 0 on success. * - -1 on failure. */ int fr_ldap_init(void) { int ldap_errno; static LDAPAPIInfo info = { .ldapai_info_version = LDAP_API_INFO_VERSION }; /* static to quiet valgrind about this being uninitialised */ fr_ldap_config_t *handle_config = &ldap_global_handle_config; if (instance_count > 0) { instance_count++; return 0; } /* * Only needs to be done once, prevents races in environment * initialisation within libldap. * * See: https://github.com/arr2036/ldapperf/issues/2 */ #ifdef HAVE_LDAP_INITIALIZE ldap_initialize(&ldap_global_handle, ""); #else ldap_global_handle = ldap_init("", 0); #endif if (!ldap_global_handle) { ERROR("Failed initialising global LDAP handle"); return -1; } ldap_errno = ldap_get_option(NULL, LDAP_OPT_API_INFO, &info); if (ldap_errno == LDAP_OPT_SUCCESS) { /* * Don't generate warnings if the compile type vendor name * is found within the link time vendor name. * * This allows the server to be built against OpenLDAP but * run with Symas OpenLDAP. */ if (strcasestr(info.ldapai_vendor_name, LDAP_VENDOR_NAME) == NULL) { WARN("ldap - libldap vendor changed since the server was built"); WARN("ldap - linked: %s, built: %s", info.ldapai_vendor_name, LDAP_VENDOR_NAME); } if (info.ldapai_vendor_version < LDAP_VENDOR_VERSION) { WARN("ldap - libldap older than the version the server was built against"); WARN("ldap - linked: %i, built: %i", info.ldapai_vendor_version, LDAP_VENDOR_VERSION); } INFO("ldap - libldap vendor: %s, version: %i", info.ldapai_vendor_name, info.ldapai_vendor_version); if (info.ldapai_extensions) { char **p; for (p = info.ldapai_extensions; *p != NULL; p++) { INFO("ldap - extension: %s", *p); ldap_memfree(*p); } ldap_memfree(info.ldapai_extensions); } ldap_memfree(info.ldapai_vendor_name); } else { DEBUG("ldap - Falling back to build time libldap version info. Query for LDAP_OPT_API_INFO " "returned: %i", ldap_errno); INFO("ldap - libldap vendor: %s, version: %i.%i.%i", LDAP_VENDOR_NAME, LDAP_VENDOR_VERSION_MAJOR, LDAP_VENDOR_VERSION_MINOR, LDAP_VENDOR_VERSION_PATCH); } instance_count++; return 0; }
int main( int argc, char **argv ) { LDAP *ld; LDAPMessage *result, *e; BerElement *ber; char *host, *a, *dn; char **vals; int i; int rc; int finished; int msgid; int num_entries = 0; struct timeval zerotime; if ( argc > 1 ) { host = argv[1]; } else { host = MY_HOST; } zerotime.tv_sec = zerotime.tv_usec = 0L; if ( prldap_install_routines( NULL, 1 /* shared */ ) != LDAP_SUCCESS ) { ldap_perror( NULL, "prldap_install_routines" ); return( 1 ); } /* get a handle to an LDAP connection */ if ( (ld = ldap_init( host, MY_PORT )) == NULL ) { perror( host ); return( 1 ); } /* authenticate to the directory as nobody */ if ( ldap_simple_bind_s( ld, NULL, NULL ) != LDAP_SUCCESS ) { ldap_perror( ld, "ldap_simple_bind_s" ); return( 1 ); } /* search for all entries with surname of Jensen */ if (( msgid = ldap_search( ld, MY_SEARCHBASE, LDAP_SCOPE_SUBTREE, MY_FILTER, NULL, 0 )) < 0 ) { ldap_perror( ld, "ldap_search" ); return( 1 ); } /* Loop, polling for results until finished */ finished = 0; while ( !finished ) { /* * Poll for results. We call ldap_result with the "all" argument * set to LDAP_MSG_ONE. This causes ldap_result() to return exactly one * entry if at least one entry is available. This allows us to * display the entries as they are received. */ result = NULL; rc = ldap_result( ld, msgid, LDAP_MSG_ONE, &zerotime, &result ); switch ( rc ) { case -1: /* some error occurred */ ldap_perror( ld, "ldap_result" ); return( 1 ); case 0: /* Timeout was exceeded. No entries are ready for retrieval. */ if ( result != NULL ) { ldap_msgfree( result ); } break; default: /* * Either an entry is ready for retrieval, or all entries have * been retrieved. */ if (( e = ldap_first_entry( ld, result )) == NULL ) { /* All done */ finished = 1; if ( result != NULL ) { ldap_msgfree( result ); } continue; } /* for each entry print out name + all attrs and values */ num_entries++; if (( dn = ldap_get_dn( ld, e )) != NULL ) { printf( "dn: %s\n", dn ); ldap_memfree( dn ); } for ( a = ldap_first_attribute( ld, e, &ber ); a != NULL; a = ldap_next_attribute( ld, e, ber ) ) { if (( vals = ldap_get_values( ld, e, a )) != NULL ) { for ( i = 0; vals[ i ] != NULL; i++ ) { printf( "%s: %s\n", a, vals[ i ] ); } ldap_value_free( vals ); } ldap_memfree( a ); } if ( ber != NULL ) { ber_free( ber, 0 ); } printf( "\n" ); ldap_msgfree( result ); } /* Do other work here while you are waiting... */ do_other_work(); } /* All done. Print a summary. */ printf( "%d entries retrieved. I counted to %ld " "while I was waiting.\n", num_entries, global_counter ); ldap_unbind( ld ); return( 0 ); }
int main( int argc, char **argv ) { LDAP *ld; LDAPMessage *result, *e; char **vals, *attrs[ 5 ]; int i; /* get a handle to an LDAP connection */ if ( (ld = ldap_init( MY_HOST, MY_PORT )) == NULL ) { perror( "ldap_init" ); return( 1 ); } attrs[ 0 ] = "cn"; /* Get canonical name(s) (full name) */ attrs[ 1 ] = "sn"; /* Get surname(s) (last name) */ attrs[ 2 ] = "mail"; /* Get email address(es) */ attrs[ 3 ] = "telephonenumber"; /* Get telephone number(s) */ attrs[ 4 ] = NULL; if ( ldap_search_s( ld, ENTRYDN, LDAP_SCOPE_BASE, "(objectclass=*)", attrs, 0, &result ) != LDAP_SUCCESS ) { ldap_perror( ld, "ldap_search_s" ); return( 1 ); } /* print it out */ if (( e = ldap_first_entry( ld, result )) != NULL ) { if (( vals = ldap_get_values( ld, e, "cn" )) != NULL ) { printf( "Full name:\n" ); for ( i = 0; vals[i] != NULL; i++ ) { printf( "\t%s\n", vals[i] ); } ldap_value_free( vals ); } if (( vals = ldap_get_values( ld, e, "sn" )) != NULL ) { printf( "Last name (surname):\n" ); for ( i = 0; vals[i] != NULL; i++ ) { printf( "\t%s\n", vals[i] ); } ldap_value_free( vals ); } if (( vals = ldap_get_values( ld, e, "mail" )) != NULL ) { printf( "Email address:\n" ); for ( i = 0; vals[i] != NULL; i++ ) { printf( "\t%s\n", vals[i] ); } ldap_value_free( vals ); } if (( vals = ldap_get_values( ld, e, "telephonenumber" )) != NULL ) { printf( "Telephone number:\n" ); for ( i = 0; vals[i] != NULL; i++ ) { printf( "\t%s\n", vals[i] ); } ldap_value_free( vals ); } } ldap_msgfree( result ); ldap_unbind( ld ); return( 0 ); }
/* * Map key -> value resolution * NOTE: these are old-fashion maps; new maps will be parsed on separate * config lines, and referred by name. */ int rewrite_xmap_apply( struct rewrite_info *info, struct rewrite_op *op, struct rewrite_map *map, struct berval *key, struct berval *val ) { int rc = REWRITE_SUCCESS; assert( info != NULL ); assert( op != NULL ); assert( map != NULL ); assert( key != NULL ); assert( val != NULL ); val->bv_val = NULL; val->bv_len = 0; switch ( map->lm_type ) { #ifdef HAVE_GETPWNAM case REWRITE_MAP_XPWDMAP: { struct passwd *pwd; #ifdef USE_REWRITE_LDAP_PVT_THREADS ldap_pvt_thread_mutex_lock( &xpasswd_mutex ); #endif /* USE_REWRITE_LDAP_PVT_THREADS */ pwd = getpwnam( key->bv_val ); if ( pwd == NULL ) { #ifdef USE_REWRITE_LDAP_PVT_THREADS ldap_pvt_thread_mutex_unlock( &xpasswd_mutex ); #endif /* USE_REWRITE_LDAP_PVT_THREADS */ rc = LDAP_NO_SUCH_OBJECT; break; } #ifdef HAVE_STRUCT_PASSWD_PW_GECOS if ( pwd->pw_gecos != NULL && pwd->pw_gecos[0] != '\0' ) { int l = strlen( pwd->pw_gecos ); val->bv_val = strdup( pwd->pw_gecos ); val->bv_len = l; } else #endif /* HAVE_STRUCT_PASSWD_PW_GECOS */ { val->bv_val = strdup( key->bv_val ); val->bv_len = key->bv_len; } #ifdef USE_REWRITE_LDAP_PVT_THREADS ldap_pvt_thread_mutex_unlock( &xpasswd_mutex ); #endif /* USE_REWRITE_LDAP_PVT_THREADS */ if ( val->bv_val == NULL ) { rc = REWRITE_ERR; } break; } #endif /* HAVE_GETPWNAM*/ case REWRITE_MAP_XFILEMAP: { char buf[1024]; if ( map->lm_args == NULL ) { rc = REWRITE_ERR; break; } #ifdef USE_REWRITE_LDAP_PVT_THREADS ldap_pvt_thread_mutex_lock( &map->lm_mutex ); #endif /* USE_REWRITE_LDAP_PVT_THREADS */ rewind( ( FILE * )map->lm_args ); while ( fgets( buf, sizeof( buf ), ( FILE * )map->lm_args ) ) { char *p; int blen; blen = strlen( buf ); if ( buf[ blen - 1 ] == '\n' ) { buf[ blen - 1 ] = '\0'; } p = strtok( buf, " " ); if ( p == NULL ) { #ifdef USE_REWRITE_LDAP_PVT_THREADS ldap_pvt_thread_mutex_unlock( &map->lm_mutex ); #endif /* USE_REWRITE_LDAP_PVT_THREADS */ rc = REWRITE_ERR; goto rc_return; } if ( strcasecmp( p, key->bv_val ) == 0 && ( p = strtok( NULL, "" ) ) ) { val->bv_val = strdup( p ); if ( val->bv_val == NULL ) { return REWRITE_ERR; } val->bv_len = strlen( p ); #ifdef USE_REWRITE_LDAP_PVT_THREADS ldap_pvt_thread_mutex_unlock( &map->lm_mutex ); #endif /* USE_REWRITE_LDAP_PVT_THREADS */ goto rc_return; } } #ifdef USE_REWRITE_LDAP_PVT_THREADS ldap_pvt_thread_mutex_unlock( &map->lm_mutex ); #endif /* USE_REWRITE_LDAP_PVT_THREADS */ rc = REWRITE_ERR; break; } case REWRITE_MAP_XLDAPMAP: { LDAP *ld; char filter[1024]; LDAPMessage *res = NULL, *entry; LDAPURLDesc *lud = ( LDAPURLDesc * )map->lm_args; int attrsonly = 0; char **values; assert( lud != NULL ); /* * No mutex because there is no write on the map data */ ld = ldap_init( lud->lud_host, lud->lud_port ); if ( ld == NULL ) { rc = REWRITE_ERR; goto rc_return; } snprintf( filter, sizeof( filter ), lud->lud_filter, key->bv_val ); if ( strcasecmp( lud->lud_attrs[ 0 ], "dn" ) == 0 ) { attrsonly = 1; } rc = ldap_search_s( ld, lud->lud_dn, lud->lud_scope, filter, lud->lud_attrs, attrsonly, &res ); if ( rc != LDAP_SUCCESS ) { ldap_unbind( ld ); rc = REWRITE_ERR; goto rc_return; } if ( ldap_count_entries( ld, res ) != 1 ) { ldap_unbind( ld ); rc = REWRITE_ERR; goto rc_return; } entry = ldap_first_entry( ld, res ); if ( entry == NULL ) { ldap_msgfree( res ); ldap_unbind( ld ); rc = REWRITE_ERR; goto rc_return; } if ( attrsonly == 1 ) { val->bv_val = ldap_get_dn( ld, entry ); } else { values = ldap_get_values( ld, entry, lud->lud_attrs[0] ); if ( values != NULL ) { val->bv_val = strdup( values[ 0 ] ); ldap_value_free( values ); } } ldap_msgfree( res ); ldap_unbind( ld ); if ( val->bv_val == NULL ) { rc = REWRITE_ERR; goto rc_return; } val->bv_len = strlen( val->bv_val ); rc = REWRITE_SUCCESS; } break; } rc_return:; return rc; }
int abook_ldap_searchstart(abook_ldap_state **ldap_state, abook_fielddata *flist, int fcount) { abook_ldap_state *mystate; int msgid, rc; int sizelimit; char *msg; char *attrs[20]; LDAP *ld; LDAPMessage *result; char *filter, *secondaryfilter; int searching_secondary = 0; if (config_ldap() < 0) { syslog(LOG_ERR, "abook_ldap_searchstart: failed to configure LDAP"); return -1; } if (imsp_to_ldap_filter(flist, fcount, &filter, config) < 0) { syslog(LOG_ERR, "abook_ldap_searchstart: failed to convert filter"); return -1; } ld = ldap_init(config.ldaphost, config.ldapport); if (ld == NULL) { syslog(LOG_ERR, "abook_ldap_searchstart: LDAP init failed: %s", strerror(errno)); return -1; } rc = ldap_simple_bind_s(ld, NULL, NULL); if (rc != LDAP_SUCCESS) { syslog(LOG_ERR, "abook_ldap_searchstart: simple bind failed: %s", ldap_err2string(rc)); return -1; } /* For testing the error handlers... sizelimit = 4; ldap_set_option(ld, LDAP_OPT_SIZELIMIT, &sizelimit); */ attrs[0] = config.fullnameattr; attrs[1] = config.uniqueattr; attrs[2] = NULL; msgid = ldap_search(ld, config.searchbase, config.scope, filter, attrs, 0/*attrs-only*/); if (msgid == -1) { syslog(LOG_ERR, "abook_ldap_searchstart: LDAP search failed"); ldap_unbind(ld); return -1; } rc = ldap_result(ld, msgid, 0, NULL, &result); switch (rc) { case LDAP_RES_SEARCH_ENTRY: /* Do nothing here. The abook_search function will pull out this * entry and send it back for display to the user. * The result is freed later. */ break; case LDAP_RES_SEARCH_RESULT: rc = ldap_result2error(ld, result, 1 /* free result */); if (rc == LDAP_SUCCESS) { /* * Search returned successfully, but with no matching entries. * * Try to do the secondary search, if configured to do so. * fails, then set the prevresult to NULL. */ if (secondaryconfig.ldaphost) { searching_secondary = 1; /* close the connection to the primary ldap server */ ldap_unbind(ld); if (imsp_to_ldap_filter(flist, fcount, &secondaryfilter, secondaryconfig) < 0) { syslog(LOG_ERR, "abook_ldap_searchstart: failed to convert filter"); return -1; } /* open connection to the secondary server */ ld = ldap_init(secondaryconfig.ldaphost, secondaryconfig.ldapport); if (ld == NULL) { syslog(LOG_ERR, "abook_ldap_searchstart: LDAP init failed: %s", strerror(errno)); return -1; } rc = ldap_simple_bind_s(ld, NULL, NULL); if (rc != LDAP_SUCCESS) { syslog(LOG_ERR, "abook_ldap_searchstart: simple bind failed: %s", ldap_err2string(rc)); return -1; } attrs[0] = secondaryconfig.fullnameattr; attrs[1] = secondaryconfig.uniqueattr; attrs[2] = NULL; msgid = ldap_search(ld, secondaryconfig.searchbase, secondaryconfig.scope, secondaryfilter, attrs, 0 /*attrs-only*/); if (msgid == -1) { syslog(LOG_ERR, "abook_ldap_searchstart: LDAP search failed"); ldap_unbind(ld); return -1; } rc = ldap_result(ld, msgid, 0, NULL, &result); switch (rc) { case LDAP_RES_SEARCH_ENTRY: /* Do nothing here. The abook_search function will pull out this * entry and send it back for display to the user. * The result is freed later. */ break; case LDAP_RES_SEARCH_RESULT: /* Still didn't get any data. Send a null "prevresult" to the * abook_search function. */ result = NULL; break; default: syslog(LOG_ERR, "abook_ldap_searchstart: ldap_result failed: %s (%d)", ldap_err2string(rc), rc); (void) ldap_msgfree(result); /* ignore message type return value */ ldap_unbind(ld); return -1; } } /* if (secondaryconfig.ldaphost) */ } else { syslog(LOG_ERR,"abook_ldap_searchstart: search returned error: %s", ldap_err2string(rc)); ldap_unbind(ld); return -1; } break; default: syslog(LOG_ERR, "abook_ldap_searchstart: ldap_result failed: A1 SEARCHADDRESS %s", ldap_err2string(rc)); (void) ldap_msgfree(result); /* ignore message type return value */ ldap_unbind(ld); return -1; } mystate = (abook_ldap_state *) malloc (sizeof (abook_ldap_state)); *ldap_state = mystate; if (mystate == NULL) { syslog(LOG_ERR, "abook_ldap_searchstart: Out of memory"); (void) ldap_msgfree(result); /* ignore message type return value */ ldap_unbind(ld); return -1; } mystate->ld = ld; mystate->msgid = msgid; mystate->prevresult = result; if (searching_secondary == 0) { mystate->ldapconfig = &config; } else { mystate->ldapconfig = &secondaryconfig; } return 0; }
int main (int argc, char *argv[]) { LDAP *ld; LDAPMessage *result; /* should be int result = STATE_UNKNOWN; */ int status = STATE_UNKNOWN; long microsec; double elapsed_time; /* for ldap tls */ int tls; int version=3; /* for entry counting */ LDAPMessage *next_entry; int status_entries = STATE_OK; int num_entries = 0; setlocale (LC_ALL, ""); bindtextdomain (PACKAGE, LOCALEDIR); textdomain (PACKAGE); if (strstr(argv[0],"check_ldaps")) { xasprintf (&progname, "check_ldaps"); } /* Parse extra opts if any */ argv=np_extra_opts (&argc, argv, progname); if (process_arguments (argc, argv) == ERROR) usage4 (_("Could not parse arguments")); if (strstr(argv[0],"check_ldaps") && ! starttls && ! ssl_on_connect) starttls = TRUE; /* initialize alarm signal handling */ signal (SIGALRM, socket_timeout_alarm_handler); /* set socket timeout */ alarm (timeout_interval); /* get the start time */ gettimeofday (&tv, NULL); /* initialize ldap */ if (ld_uri != NULL) { #ifdef HAVE_LDAP_INITIALIZE int result = ldap_initialize(&ld, ld_uri); if (result != LDAP_SUCCESS) { printf ("Failed to connect to LDAP server at %s: %s\n", ld_uri, ldap_err2string(result)); return STATE_CRITICAL; } #else printf ("Sorry, this version of %s was compiled without URI support!\n", argv[0]); return STATE_CRITICAL; #endif } #ifdef HAVE_LDAP_INIT else if (!(ld = ldap_init (ld_host, ld_port))) { printf ("Could not connect to the server at port %i\n", ld_port); return STATE_CRITICAL; } #else else if (!(ld = ldap_open (ld_host, ld_port))) { if (verbose) ldap_perror(ld, "ldap_open"); printf (_("Could not connect to the server at port %i\n"), ld_port); return STATE_CRITICAL; } #endif /* HAVE_LDAP_INIT */ #ifdef HAVE_LDAP_SET_OPTION /* set ldap options */ if (ldap_set_option (ld, LDAP_OPT_PROTOCOL_VERSION, &ld_protocol) != LDAP_OPT_SUCCESS ) { printf(_("Could not set protocol version %d\n"), ld_protocol); return STATE_CRITICAL; } #endif if (ld_port == LDAPS_PORT || ssl_on_connect) { xasprintf (&SERVICE, "LDAPS"); #if defined(HAVE_LDAP_SET_OPTION) && defined(LDAP_OPT_X_TLS) /* ldaps: set option tls */ tls = LDAP_OPT_X_TLS_HARD; if (ldap_set_option (ld, LDAP_OPT_X_TLS, &tls) != LDAP_SUCCESS) { if (verbose) ldap_perror(ld, "ldaps_option"); printf (_("Could not init TLS at port %i!\n"), ld_port); return STATE_CRITICAL; } #else printf (_("TLS not supported by the libraries!\n")); return STATE_CRITICAL; #endif /* LDAP_OPT_X_TLS */ } else if (starttls) { xasprintf (&SERVICE, "LDAP-TLS"); #if defined(HAVE_LDAP_SET_OPTION) && defined(HAVE_LDAP_START_TLS_S) /* ldap with startTLS: set option version */ if (ldap_get_option(ld,LDAP_OPT_PROTOCOL_VERSION, &version) == LDAP_OPT_SUCCESS ) { if (version < LDAP_VERSION3) { version = LDAP_VERSION3; ldap_set_option(ld, LDAP_OPT_PROTOCOL_VERSION, &version); } } /* call start_tls */ if (ldap_start_tls_s(ld, NULL, NULL) != LDAP_SUCCESS) { if (verbose) ldap_perror(ld, "ldap_start_tls"); printf (_("Could not init startTLS at port %i!\n"), ld_port); return STATE_CRITICAL; } #else printf (_("startTLS not supported by the library, needs LDAPv3!\n")); return STATE_CRITICAL; #endif /* HAVE_LDAP_START_TLS_S */ } /* bind to the ldap server */ if (ldap_bind_s (ld, ld_binddn, ld_passwd, LDAP_AUTH_SIMPLE) != LDAP_SUCCESS) { if (verbose) ldap_perror(ld, "ldap_bind"); printf (_("Could not bind to the LDAP server\n")); return STATE_CRITICAL; } /* do a search of all objectclasses in the base dn */ if (ldap_search_s (ld, ld_base, (crit_entries!=NULL || warn_entries!=NULL) ? LDAP_SCOPE_SUBTREE : LDAP_SCOPE_BASE, ld_attr, NULL, 0, &result) != LDAP_SUCCESS) { if (verbose) ldap_perror(ld, "ldap_search"); printf (_("Could not search/find objectclasses in %s\n"), ld_base); return STATE_CRITICAL; } else if (crit_entries!=NULL || warn_entries!=NULL) { num_entries = ldap_count_entries(ld, result); } /* unbind from the ldap server */ ldap_unbind (ld); /* reset the alarm handler */ alarm (0); /* calcutate the elapsed time and compare to thresholds */ microsec = deltime (tv); elapsed_time = (double)microsec / 1.0e6; if (crit_time!=UNDEFINED && elapsed_time>crit_time) status = STATE_CRITICAL; else if (warn_time!=UNDEFINED && elapsed_time>warn_time) status = STATE_WARNING; else status = STATE_OK; if(entries_thresholds != NULL) { if (verbose) { printf ("entries found: %d\n", num_entries); print_thresholds("entry threasholds", entries_thresholds); } status_entries = get_status(num_entries, entries_thresholds); if (status_entries == STATE_CRITICAL) { status = STATE_CRITICAL; } else if (status != STATE_CRITICAL) { status = status_entries; } } /* print out the result */ if (crit_entries!=NULL || warn_entries!=NULL) { printf (_("LDAP %s - found %d entries in %.3f seconds|%s %s\n"), state_text (status), num_entries, elapsed_time, fperfdata ("time", elapsed_time, "s", (int)warn_time, warn_time, (int)crit_time, crit_time, TRUE, 0, FALSE, 0), sperfdata ("entries", (double)num_entries, "", warn_entries, crit_entries, TRUE, 0.0, FALSE, 0.0)); } else { printf (_("LDAP %s - %.3f seconds response time|%s\n"), state_text (status), elapsed_time, fperfdata ("time", elapsed_time, "s", (int)warn_time, warn_time, (int)crit_time, crit_time, TRUE, 0, FALSE, 0)); } return status; }
abook_fielddata * abook_ldap_fetch(char *alias, int *count) { int i, rc, ldapcount, mappedfieldcount; char *ptr; char prefix[1024]; char filter[1024]; abook_fielddata *fdata, *fptr; char *searchattr; char *searchkey; LDAP *ld; LDAPMessage *results, *entry; char **values; if (config_ldap() < 0) { syslog(LOG_ERR, "abook_ldap_fetch: failed to configure LDAP"); return NULL; } /* * Decide how to search for the user. */ snprintf(prefix, sizeof(prefix), "[%s:", config.uniqueattr); ptr = strstr(alias, prefix); if (ptr != NULL) { *ptr = '\0'; ptr += 1 /*[*/ + strlen(config.uniqueattr) + 1 /*:*/; searchkey = ptr; ptr += strlen(ptr) - 1 /*]*/; *ptr = '\0'; searchattr = config.uniqueattr; } else { searchkey = alias; searchattr = config.fullnameattr; } snprintf(filter, sizeof(filter), "(&%s(%s=%s))", config.defaultfilter, searchattr, searchkey); ld = ldap_init(config.ldaphost, config.ldapport); if (ld == NULL) { syslog(LOG_ERR, "abook_ldap_fetch: LDAP init failed: %s", strerror(errno)); return NULL; } rc = ldap_simple_bind_s(ld, NULL, NULL); if (rc != LDAP_SUCCESS) { syslog(LOG_ERR, "abook_ldap_fetch: simple bind failed: %s", ldap_err2string(rc)); return NULL; } rc = ldap_search_s(ld, config.searchbase, config.scope, filter, NULL/*get all attrs*/, 0/*attrs-only*/, &results); if (rc != LDAP_SUCCESS) { syslog(LOG_ERR, "abook_ldap_fetch: LDAP search failed: %s", ldap_err2string(rc)); ldap_unbind(ld); return NULL; } ldapcount = ldap_count_entries(ld, results); if (ldapcount == 0) { /* no matches on primary search, try secondary search if configured */ if (secondaryconfig.ldaphost) { /* close the connection to the primary server */ ldap_unbind(ld); snprintf(prefix, sizeof(prefix), "[%s:", secondaryconfig.uniqueattr); ptr = strstr(alias, prefix); if (ptr != NULL) { *ptr = '\0'; ptr += 1 /*[*/ + strlen(secondaryconfig.uniqueattr) + 1 /*:*/; searchkey = ptr; ptr += strlen(ptr) - 1 /*]*/; *ptr = '\0'; searchattr = secondaryconfig.uniqueattr; } else { searchkey = alias; searchattr = secondaryconfig.fullnameattr; } snprintf(filter, sizeof(filter), "(&%s(%s=%s))", secondaryconfig.defaultfilter, searchattr, searchkey); ld=ldap_init(secondaryconfig.ldaphost, secondaryconfig.ldapport); if (ld == NULL){ syslog(LOG_ERR, "abook_ldap_fetch: LDAP secondary init failed: %s", strerror(errno)); return NULL; } rc = ldap_simple_bind_s(ld, NULL, NULL); if (rc != LDAP_SUCCESS) { syslog(LOG_ERR, "abook_ldap_fetch: simple secondary bind failed: %s", ldap_err2string(rc)); return NULL; } rc = ldap_search_s(ld, secondaryconfig.searchbase, secondaryconfig.scope, filter, NULL/*get all attrs*/, 0/*attrs-only*/, &results); if (rc != LDAP_SUCCESS) { syslog(LOG_ERR, "abook_ldap_fetch: LDAP secondary search failed: %s", ldap_err2string(rc)); ldap_unbind(ld); return NULL; } ldapcount = ldap_count_entries(ld, results); if (ldapcount != 1) { syslog(LOG_ERR, "abook_ldap_fetch: unexpected count of secondary search" " hits: %d", ldapcount); (void) ldap_msgfree(results); /* ignore message type return value */ ldap_unbind(ld); return NULL; } entry = ldap_first_entry(ld, results); if (entry == NULL) { syslog(LOG_ERR, "abook_ldap_fetch: ldap_first_entry failed"); (void) ldap_msgfree(results); /* ignore message type return value */ ldap_unbind(ld); return NULL; } /* This memory is freed by abook_fetchdone() which is called by * show_address() after it's finished sending the field/data pairs * back to the IMSP client */ mappedfieldcount = 0; for (i = 0; secondaryconfig.map[i].field != NULL; i++) { if (secondaryconfig.map[i].attr != NULL) mappedfieldcount++; } fdata = (abook_fielddata *) malloc(sizeof (abook_fielddata) * mappedfieldcount); if (fdata == NULL) { syslog(LOG_ERR, "abook_ldap_fetch: Out of memory"); (void) ldap_msgfree(results); /* ignore message type return value */ ldap_unbind(ld); return NULL; } *count = 0; fptr = fdata; for (i = 0; secondaryconfig.map[i].field != NULL; i++) { if ((secondaryconfig.map[i].attr != NULL) && (strcmp(secondaryconfig.map[i].attr, secondaryconfig.fullnameattr) != 0)) { values = ldap_get_values(ld, entry, secondaryconfig.map[i].attr); if (values != NULL && values[0] != NULL) { fptr->field = strdup(secondaryconfig.map[i].field); if (secondaryconfig.map[i].append != NULL) { int fptrdatalen = strlen(values[0])+strlen(secondaryconfig.map[i].append)+1; fptr->data=malloc(fptrdatalen); if(!fptr->data) fatal("out of memory", EC_TEMPFAIL); strlcpy(fptr->data, values[0], fptrdatalen); strlcat(fptr->data, secondaryconfig.map[i].append, fptrdatalen); } else { fptr->data = strdup(values[0]); if(!fptr->data) fatal("out of memory", EC_TEMPFAIL); } (*count)++; fptr++; } if (values != NULL) ldap_value_free(values); } } (void) ldap_msgfree(results); /* ignore message type return value */ ldap_unbind(ld); return (fdata); } } if (ldapcount != 1) { syslog(LOG_ERR, "abook_ldap_fetch: unexpected count of search" " hits: %d", ldapcount); (void) ldap_msgfree(results); /* ignore message type return value */ ldap_unbind(ld); return NULL; } entry = ldap_first_entry(ld, results); if (entry == NULL) { syslog(LOG_ERR, "abook_ldap_fetch: ldap_first_entry failed"); (void) ldap_msgfree(results); /* ignore message type return value */ ldap_unbind(ld); return NULL; } /* This memory is freed by abook_fetchdone() which is called by * show_address() after it's finished sending the field/data pairs * back to the IMSP client */ mappedfieldcount = 0; for (i = 0; config.map[i].field != NULL; i++) { if (config.map[i].attr != NULL) mappedfieldcount++; } fdata = (abook_fielddata *) malloc(sizeof (abook_fielddata) * mappedfieldcount); if (fdata == NULL) { syslog(LOG_ERR, "abook_ldap_fetch: Out of memory"); (void) ldap_msgfree(results); /* ignore message type return value */ ldap_unbind(ld); return NULL; } *count = 0; fptr = fdata; for (i = 0; config.map[i].field != NULL; i++) { if ((config.map[i].attr != NULL) && (strcmp(config.map[i].attr, config.fullnameattr) != 0)) { values = ldap_get_values(ld, entry, config.map[i].attr); if (values != NULL && values[0] != NULL) { fptr->field = strdup(config.map[i].field); if (config.map[i].append != NULL) { printf("appending %s to field: %s value: %s\n", config.map[i].append, config.map[i].field,values[0]); fptr->data=malloc(strlen(values[0])+strlen(config.map[i].append)+1); fptr->data=strcat(fptr->data, values[0]); fptr->data=strcat(fptr->data, config.map[i].append); } else { fptr->data = strdup(values[0]); } (*count)++; fptr++; } if (values != NULL) ldap_value_free(values); } } (void) ldap_msgfree(results); /* ignore message type return value */ ldap_unbind(ld); return (fdata); }
handler_t auth_ldap_init(server *srv, mod_auth_plugin_config *s) { #ifdef USE_LDAP int ret; #if 0 if (s->auth_ldap_basedn->used == 0) { log_error_write(srv, __FILE__, __LINE__, "s", "ldap: auth.backend.ldap.base-dn has to be set"); return HANDLER_ERROR; } #endif if (s->auth_ldap_hostname->used) { /* free old context */ if (NULL != s->ldap) ldap_unbind_s(s->ldap); if (NULL == (s->ldap = ldap_init(s->auth_ldap_hostname->ptr, LDAP_PORT))) { log_error_write(srv, __FILE__, __LINE__, "ss", "ldap ...", strerror(errno)); return HANDLER_ERROR; } ret = LDAP_VERSION3; if (LDAP_OPT_SUCCESS != (ret = ldap_set_option(s->ldap, LDAP_OPT_PROTOCOL_VERSION, &ret))) { log_error_write(srv, __FILE__, __LINE__, "ss", "ldap:", ldap_err2string(ret)); return HANDLER_ERROR; } if (s->auth_ldap_starttls) { /* if no CA file is given, it is ok, as we will use encryption * if the server requires a CAfile it will tell us */ if (!buffer_is_empty(s->auth_ldap_cafile)) { if (LDAP_OPT_SUCCESS != (ret = ldap_set_option(NULL, LDAP_OPT_X_TLS_CACERTFILE, s->auth_ldap_cafile->ptr))) { log_error_write(srv, __FILE__, __LINE__, "ss", "Loading CA certificate failed:", ldap_err2string(ret)); return HANDLER_ERROR; } } if (LDAP_OPT_SUCCESS != (ret = ldap_start_tls_s(s->ldap, NULL, NULL))) { log_error_write(srv, __FILE__, __LINE__, "ss", "ldap startTLS failed:", ldap_err2string(ret)); return HANDLER_ERROR; } } /* 1. */ if (s->auth_ldap_binddn->used) { if (LDAP_SUCCESS != (ret = ldap_simple_bind_s(s->ldap, s->auth_ldap_binddn->ptr, s->auth_ldap_bindpw->ptr))) { log_error_write(srv, __FILE__, __LINE__, "ss", "ldap:", ldap_err2string(ret)); return HANDLER_ERROR; } } else { if (LDAP_SUCCESS != (ret = ldap_simple_bind_s(s->ldap, NULL, NULL))) { log_error_write(srv, __FILE__, __LINE__, "ss", "ldap:", ldap_err2string(ret)); return HANDLER_ERROR; } } } return HANDLER_GO_ON; #else UNUSED(s); log_error_write(srv, __FILE__, __LINE__, "s", "no ldap support available"); return HANDLER_ERROR; #endif }
int main(int argc, char **argv) { LDAPAPIInfo api; int ival; char *sval; printf("Compile time API Information\n"); #ifdef LDAP_API_INFO_VERSION api.ldapai_info_version = LDAP_API_INFO_VERSION; printf(" API Info version: %d\n", (int) api.ldapai_info_version); #else api.ldapai_info_version = 1; printf(" API Info version: unknown\n"); #endif #ifdef LDAP_FEATURE_INFO_VERSION printf(" Feature Info version: %d\n", (int) LDAP_FEATURE_INFO_VERSION); #else printf(" Feature Info version: unknown\n"); api.ldapai_info_version = 1; #endif #ifdef LDAP_API_VERSION printf(" API version: %d\n", (int) LDAP_API_VERSION); #else printf(" API version: unknown\n"); #endif #ifdef LDAP_VERSION printf(" Protocol Version: %d\n", (int) LDAP_VERSION); #else printf(" Protocol Version: unknown\n"); #endif #ifdef LDAP_VERSION_MIN printf(" Protocol Min: %d\n", (int) LDAP_VERSION_MIN); #else printf(" Protocol Min: unknown\n"); #endif #ifdef LDAP_VERSION_MAX printf(" Protocol Max: %d\n", (int) LDAP_VERSION_MAX); #else printf(" Protocol Max: unknown\n"); #endif #ifdef LDAP_VENDOR_NAME printf(" Vendor Name: %s\n", LDAP_VENDOR_NAME); #else printf(" Vendor Name: unknown\n"); #endif #ifdef LDAP_VENDOR_VERSION printf(" Vendor Version: %d\n", (int) LDAP_VENDOR_VERSION); #else printf(" Vendor Version: unknown\n"); #endif if(ldap_get_option(NULL, LDAP_OPT_API_INFO, &api) != LDAP_SUCCESS) { fprintf(stderr, "%s: ldap_get_option(API_INFO) failed\n", argv[0]); return EXIT_FAILURE; } printf("\nExecution time API Information\n"); printf(" API Info version: %d\n", api.ldapai_info_version); if (api.ldapai_info_version != LDAP_API_INFO_VERSION) { printf(" API INFO version mismatch: got %d, expected %d\n", api.ldapai_info_version, LDAP_API_INFO_VERSION); return EXIT_FAILURE; } printf(" API Version: %d\n", api.ldapai_api_version); printf(" Protocol Max: %d\n", api.ldapai_protocol_version); if(api.ldapai_extensions == NULL) { printf(" Extensions: none\n"); } else { int i; for(i=0; api.ldapai_extensions[i] != NULL; i++) /* empty */; printf(" Extensions: %d\n", i); for(i=0; api.ldapai_extensions[i] != NULL; i++) { #ifdef LDAP_OPT_API_FEATURE_INFO LDAPAPIFeatureInfo fi; fi.ldapaif_info_version = LDAP_FEATURE_INFO_VERSION; fi.ldapaif_name = api.ldapai_extensions[i]; fi.ldapaif_version = 0; if( ldap_get_option(NULL, LDAP_OPT_API_FEATURE_INFO, &fi) == LDAP_SUCCESS ) { if(fi.ldapaif_info_version != LDAP_FEATURE_INFO_VERSION) { printf(" %s feature info mismatch: got %d, expected %d\n", api.ldapai_extensions[i], LDAP_FEATURE_INFO_VERSION, fi.ldapaif_info_version); } else { printf(" %s: version %d\n", fi.ldapaif_name, fi.ldapaif_version); } } else { printf(" %s (NO FEATURE INFO)\n", api.ldapai_extensions[i]); } #else printf(" %s\n", api.ldapai_extensions[i]); #endif ldap_memfree(api.ldapai_extensions[i]); } ldap_memfree(api.ldapai_extensions); } printf(" Vendor Name: %s\n", api.ldapai_vendor_name); ldap_memfree(api.ldapai_vendor_name); printf(" Vendor Version: %d\n", api.ldapai_vendor_version); printf("\nExecution time Default Options\n"); if(ldap_get_option(NULL, LDAP_OPT_DEREF, &ival) != LDAP_SUCCESS) { fprintf(stderr, "%s: ldap_get_option(api) failed\n", argv[0]); return EXIT_FAILURE; } printf(" DEREF: %d\n", ival); if(ldap_get_option(NULL, LDAP_OPT_SIZELIMIT, &ival) != LDAP_SUCCESS) { fprintf(stderr, "%s: ldap_get_option(sizelimit) failed\n", argv[0]); return EXIT_FAILURE; } printf(" SIZELIMIT: %d\n", ival); if(ldap_get_option(NULL, LDAP_OPT_TIMELIMIT, &ival) != LDAP_SUCCESS) { fprintf(stderr, "%s: ldap_get_option(timelimit) failed\n", argv[0]); return EXIT_FAILURE; } printf(" TIMELIMIT: %d\n", ival); if(ldap_get_option(NULL, LDAP_OPT_REFERRALS, &ival) != LDAP_SUCCESS) { fprintf(stderr, "%s: ldap_get_option(referrals) failed\n", argv[0]); return EXIT_FAILURE; } printf(" REFERRALS: %s\n", ival ? "on" : "off"); if(ldap_get_option(NULL, LDAP_OPT_RESTART, &ival) != LDAP_SUCCESS) { fprintf(stderr, "%s: ldap_get_option(restart) failed\n", argv[0]); return EXIT_FAILURE; } printf(" RESTART: %s\n", ival ? "on" : "off"); if(ldap_get_option(NULL, LDAP_OPT_PROTOCOL_VERSION, &ival) != LDAP_SUCCESS) { fprintf(stderr, "%s: ldap_get_option(protocol version) failed\n", argv[0]); return EXIT_FAILURE; } printf(" PROTOCOL VERSION: %d\n", ival); if(ldap_get_option(NULL, LDAP_OPT_HOST_NAME, &sval) != LDAP_SUCCESS) { fprintf(stderr, "%s: ldap_get_option(host name) failed\n", argv[0]); return EXIT_FAILURE; } if( sval != NULL ) { printf(" HOST NAME: %s\n", sval); ldap_memfree(sval); } else { puts(" HOST NAME: <not set>"); } #if 0 /* API tests */ { /* bindless unbind */ LDAP *ld; int rc; ld = ldap_init( "localhost", 389 ); if( ld == NULL ) { perror("ldap_init"); return EXIT_FAILURE; } rc = ldap_unbind( ld ); if( rc != LDAP_SUCCESS ) { perror("ldap_unbind"); return EXIT_FAILURE; } } { /* bindless unbind */ LDAP *ld; int rc; ld = ldap_init( "localhost", 389 ); if( ld == NULL ) { perror("ldap_init"); return EXIT_FAILURE; } rc = ldap_abandon_ext( ld, 0, NULL, NULL ); if( rc != LDAP_SERVER_DOWN ) { ldap_debug_perror( ld, "ldap_abandon"); return EXIT_FAILURE; } rc = ldap_unbind( ld ); if( rc != LDAP_SUCCESS ) { perror("ldap_unbind"); return EXIT_FAILURE; } } #endif return EXIT_SUCCESS; }
/** Instantiate the module * * Creates a new instance of the module reading parameters from a configuration section. * * @param conf to parse. * @param instance Where to write pointer to configuration data. * @return 0 on success < 0 on failure. */ static int mod_instantiate(CONF_SECTION *conf, void *instance) { static bool version_done; CONF_SECTION *options; ldap_instance_t *inst = instance; inst->cs = conf; options = cf_section_sub_find(conf, "options"); if (!options || !cf_pair_find(options, "chase_referrals")) { inst->chase_referrals_unset = true; /* use OpenLDAP defaults */ } inst->xlat_name = cf_section_name2(conf); if (!inst->xlat_name) { inst->xlat_name = cf_section_name1(conf); } /* * Only needs to be done once, prevents races in environment * initialisation within libldap. * * See: https://github.com/arr2036/ldapperf/issues/2 */ #ifdef HAVE_LDAP_INITIALIZE ldap_initialize(&inst->handle, ""); #else inst->handle = ldap_init("", 0); #endif /* * Get version info from the LDAP API. */ if (!version_done) { static LDAPAPIInfo info; /* static to quiet valgrind about this being uninitialised */ int ldap_errno; version_done = true; ldap_errno = ldap_get_option(NULL, LDAP_OPT_API_INFO, &info); if (ldap_errno == LDAP_OPT_SUCCESS) { if (strcmp(info.ldapai_vendor_name, LDAP_VENDOR_NAME) != 0) { WARN("rlm_ldap: libldap vendor changed since the server was built"); WARN("rlm_ldap: linked: %s, built: %s", info.ldapai_vendor_name, LDAP_VENDOR_NAME); } if (info.ldapai_vendor_version != LDAP_VENDOR_VERSION) { WARN("rlm_ldap: libldap version changed since the server was built"); WARN("rlm_ldap: linked: %i, built: %i", info.ldapai_vendor_version, LDAP_VENDOR_VERSION); } INFO("rlm_ldap: libldap vendor: %s, version: %i", info.ldapai_vendor_name, info.ldapai_vendor_version); ldap_memfree(info.ldapai_vendor_name); ldap_memfree(info.ldapai_extensions); } else { DEBUG("rlm_ldap: Falling back to build time libldap version info. Query for LDAP_OPT_API_INFO " "returned: %i", ldap_errno); INFO("rlm_ldap: libldap vendor: %s, version: %i.%i.%i", LDAP_VENDOR_NAME, LDAP_VENDOR_VERSION_MAJOR, LDAP_VENDOR_VERSION_MINOR, LDAP_VENDOR_VERSION_PATCH); } } /* * If the configuration parameters can't be parsed, then fail. */ if ((parse_sub_section(inst, conf, &inst->accounting, RLM_COMPONENT_ACCT) < 0) || (parse_sub_section(inst, conf, &inst->postauth, RLM_COMPONENT_POST_AUTH) < 0)) { cf_log_err_cs(conf, "Failed parsing configuration"); goto error; } /* * Sanity checks for cacheable groups code. */ if (inst->cacheable_group_name && inst->groupobj_membership_filter) { if (!inst->groupobj_name_attr) { cf_log_err_cs(conf, "Directive 'group.name_attribute' must be set if cacheable " "group names are enabled"); goto error; } } /* * Split original server value out into URI, server and port * so whatever initialization function we use later will have * the server information in the format it needs. */ if (ldap_is_ldap_url(inst->server)) { LDAPURLDesc *ldap_url; int port; if (ldap_url_parse(inst->server, &ldap_url)){ cf_log_err_cs(conf, "Parsing LDAP URL \"%s\" failed", inst->server); return -1; } /* * Figure out the port from the URL */ if (ldap_url->lud_port == 0) { if (strcmp(ldap_url->lud_scheme, "ldaps://") == 0) { if (inst->start_tls == true) { start_tls_error: cf_log_err_cs(conf, "ldaps:// scheme is not compatible with 'start_tls'"); return -1; } port = 636; } else { port = 384; } } else { port = ldap_url->lud_port; } inst->uri = inst->server; inst->server = talloc_strdup(inst, ldap_url->lud_host); if ((inst->port != 384) && (port != inst->port)) { WARN("Non-default 'port' directive %i set to %i by LDAP URI", inst->port, port); } inst->port = port; /* * @todo We could set a few other top level * directives using the URL, like base_dn * and scope. */ ldap_free_urldesc(ldap_url); /* * We need to construct an LDAP URI */ } else { switch (inst->port) { default: case 384: inst->uri = talloc_asprintf(inst, "ldap://%s:%i/", inst->server, inst->port); break; case 636: if (inst->start_tls == true) goto start_tls_error; inst->uri = talloc_asprintf(inst, "ldaps://%s:%i/", inst->server, inst->port); break; } } #ifdef LDAP_OPT_X_TLS_NEVER /* * Workaround for servers which support LDAPS but not START TLS */ if (inst->port == LDAPS_PORT || inst->tls_mode) { inst->tls_mode = LDAP_OPT_X_TLS_HARD; } else { inst->tls_mode = 0; } #endif /* * Convert dereference strings to enumerated constants */ if (inst->dereference_str) { inst->dereference = fr_str2int(ldap_dereference, inst->dereference_str, -1); if (inst->dereference < 0) { cf_log_err_cs(conf, "Invalid 'dereference' value \"%s\", expected 'never', 'searching', " "'finding' or 'always'", inst->dereference_str); goto error; } } #if LDAP_SET_REBIND_PROC_ARGS != 3 /* * The 2-argument rebind doesn't take an instance variable. Our rebind function needs the instance * variable for the username, password, etc. */ if (inst->rebind == true) { cf_log_err_cs(conf, "Cannot use 'rebind' directive as this version of libldap " "does not support the API that we need"); goto error; } #endif /* * Convert scope strings to enumerated constants */ inst->userobj_scope = fr_str2int(ldap_scope, inst->userobj_scope_str, -1); if (inst->userobj_scope < 0) { cf_log_err_cs(conf, "Invalid 'user.scope' value \"%s\", expected 'sub', 'one'" #ifdef LDAP_SCOPE_CHILDREN ", 'base' or 'children'" #else " or 'base'" #endif , inst->userobj_scope_str); goto error; } inst->groupobj_scope = fr_str2int(ldap_scope, inst->groupobj_scope_str, -1); if (inst->groupobj_scope < 0) { cf_log_err_cs(conf, "Invalid 'group.scope' value \"%s\", expected 'sub', 'one'" #ifdef LDAP_SCOPE_CHILDREN ", 'base' or 'children'" #else " or 'base'" #endif , inst->groupobj_scope_str); goto error; } inst->clientobj_scope = fr_str2int(ldap_scope, inst->clientobj_scope_str, -1); if (inst->clientobj_scope < 0) { cf_log_err_cs(conf, "Invalid 'client.scope' value \"%s\", expected 'sub', 'one'" #ifdef LDAP_SCOPE_CHILDREN ", 'base' or 'children'" #else " or 'base'" #endif , inst->clientobj_scope_str); goto error; } if (inst->tls_require_cert_str) { #ifdef LDAP_OPT_X_TLS_NEVER /* * Convert cert strictness to enumerated constants */ inst->tls_require_cert = fr_str2int(ldap_tls_require_cert, inst->tls_require_cert_str, -1); if (inst->tls_require_cert < 0) { cf_log_err_cs(conf, "Invalid 'tls.require_cert' value \"%s\", expected 'never', " "'demand', 'allow', 'try' or 'hard'", inst->tls_require_cert_str); goto error; } #else cf_log_err_cs(conf, "Modifying 'tls.require_cert' is not supported by current " "version of libldap. Please upgrade or substitute current libldap and " "rebuild this module"); goto error; #endif } /* * Build the attribute map */ if (map_afrom_cs(&inst->user_map, cf_section_sub_find(inst->cs, "update"), PAIR_LIST_REPLY, PAIR_LIST_REQUEST, rlm_ldap_map_verify, inst, LDAP_MAX_ATTRMAP) < 0) { return -1; } /* * Group comparison checks. */ if (cf_section_name2(conf)) { static ATTR_FLAGS flags; char buffer[256]; snprintf(buffer, sizeof(buffer), "%s-Ldap-Group", inst->xlat_name); if (dict_addattr(buffer, -1, 0, PW_TYPE_STRING, flags) < 0) { LDAP_ERR("Error creating group attribute: %s", fr_strerror()); return -1; } inst->group_da = dict_attrbyname(buffer); if (!inst->group_da) { LDAP_ERR("Failed creating attribute %s", buffer); goto error; } paircompare_register(inst->group_da, dict_attrbyvalue(PW_USER_NAME, 0), false, rlm_ldap_groupcmp, inst); /* * Were the default instance */ } else { inst->group_da = dict_attrbyvalue(PW_LDAP_GROUP, 0); paircompare_register(dict_attrbyvalue(PW_LDAP_GROUP, 0), dict_attrbyvalue(PW_USER_NAME, 0), false, rlm_ldap_groupcmp, inst); } xlat_register(inst->xlat_name, ldap_xlat, rlm_ldap_escape_func, inst); /* * Setup the cache attribute */ if (inst->cache_attribute) { static ATTR_FLAGS flags; if (dict_addattr(inst->cache_attribute, -1, 0, PW_TYPE_STRING, flags) < 0) { LDAP_ERR("Error creating cache attribute: %s", fr_strerror()); goto error; } inst->cache_da = dict_attrbyname(inst->cache_attribute); } else { inst->cache_da = inst->group_da; /* Default to the group_da */ } /* * Initialize the socket pool. */ inst->pool = fr_connection_pool_module_init(inst->cs, inst, mod_conn_create, NULL, NULL); if (!inst->pool) goto error; /* * Bulk load dynamic clients. */ if (inst->do_clients) { CONF_SECTION *cs; cs = cf_section_sub_find(inst->cs, "client"); if (!cs) { cf_log_err_cs(conf, "Told to load clients but no client section found"); goto error; } cs = cf_section_sub_find(cs, "attribute"); if (!cs) { cf_log_err_cs(conf, "Told to load clients but no attribute section found"); goto error; } if (rlm_ldap_client_load(inst, cs) < 0) { cf_log_err_cs(conf, "Error loading clients"); return -1; } } return 0; error: return -1; }
int main(int argc, char **argv) { char buf[8192]; char *user, *group, *extension_dn = NULL; char *ldapServer = NULL; LDAP *ld = NULL; int tryagain = 0, rc; int port = LDAP_PORT; int use_extension_dn = 0; int strip_nt_domain = 0; int strip_kerberos_realm = 0; setbuf(stdout, NULL); while (argc > 1 && argv[1][0] == '-') { char *value = ""; char option = argv[1][1]; switch (option) { case 'P': case 'R': case 'z': case 'Z': case 'd': case 'g': case 'S': case 'K': break; default: if (strlen(argv[1]) > 2) { value = argv[1] + 2; } else if (argc > 2) { value = argv[2]; argv++; argc--; } else value = ""; break; } argv++; argc--; switch (option) { case 'H': #if !HAS_URI_SUPPORT fprintf(stderr, "ERROR: Your LDAP library does not have URI support\n"); exit(1); #endif /* Fall thru to -h */ case 'h': if (ldapServer) { int len = strlen(ldapServer) + 1 + strlen(value) + 1; char *newhost = malloc(len); snprintf(newhost, len, "%s %s", ldapServer, value); free(ldapServer); ldapServer = newhost; } else { ldapServer = strdup(value); } break; case 'b': basedn = value; break; case 'f': searchfilter = value; break; case 'B': userbasedn = value; break; case 'F': usersearchfilter = value; break; case 'u': userdnattr = value; break; case 's': if (strcmp(value, "base") == 0) searchscope = LDAP_SCOPE_BASE; else if (strcmp(value, "one") == 0) searchscope = LDAP_SCOPE_ONELEVEL; else if (strcmp(value, "sub") == 0) searchscope = LDAP_SCOPE_SUBTREE; else { fprintf(stderr, PROGRAM_NAME " ERROR: Unknown search scope '%s'\n", value); exit(1); } break; case 'E': #if defined(NETSCAPE_SSL) sslpath = value; if (port == LDAP_PORT) port = LDAPS_PORT; #else fprintf(stderr, PROGRAM_NAME " ERROR: -E unsupported with this LDAP library\n"); exit(1); #endif break; case 'c': connect_timeout = atoi(value); break; case 't': timelimit = atoi(value); break; case 'a': if (strcmp(value, "never") == 0) aliasderef = LDAP_DEREF_NEVER; else if (strcmp(value, "always") == 0) aliasderef = LDAP_DEREF_ALWAYS; else if (strcmp(value, "search") == 0) aliasderef = LDAP_DEREF_SEARCHING; else if (strcmp(value, "find") == 0) aliasderef = LDAP_DEREF_FINDING; else { fprintf(stderr, PROGRAM_NAME " ERROR: Unknown alias dereference method '%s'\n", value); exit(1); } break; case 'D': binddn = value; break; case 'w': bindpasswd = value; break; case 'W': readSecret(value); break; case 'P': persistent = !persistent; break; case 'p': port = atoi(value); break; case 'R': noreferrals = !noreferrals; break; #ifdef LDAP_VERSION3 case 'v': switch (atoi(value)) { case 2: version = LDAP_VERSION2; break; case 3: version = LDAP_VERSION3; break; default: fprintf(stderr, "Protocol version should be 2 or 3\n"); exit(1); } break; case 'Z': if (version == LDAP_VERSION2) { fprintf(stderr, "TLS (-Z) is incompatible with version %d\n", version); exit(1); } version = LDAP_VERSION3; use_tls = 1; break; #endif case 'd': debug = 1; break; case 'g': use_extension_dn = 1; break; case 'S': strip_nt_domain = 1; break; case 'K': strip_kerberos_realm = 1; break; default: fprintf(stderr, PROGRAM_NAME " ERROR: Unknown command line option '%c'\n", option); exit(1); } } while (argc > 1) { char *value = argv[1]; if (ldapServer) { int len = strlen(ldapServer) + 1 + strlen(value) + 1; char *newhost = malloc(len); snprintf(newhost, len, "%s %s", ldapServer, value); free(ldapServer); ldapServer = newhost; } else { ldapServer = strdup(value); } argc--; argv++; } if (!ldapServer) ldapServer = "localhost"; if (!basedn || !searchfilter) { fprintf(stderr, "\n" PROGRAM_NAME " version " PROGRAM_VERSION "\n\n"); fprintf(stderr, "Usage: " PROGRAM_NAME " -b basedn -f filter [options] ldap_server_name\n\n"); fprintf(stderr, "\t-b basedn (REQUIRED)\tbase dn under where to search for groups\n"); fprintf(stderr, "\t-f filter (REQUIRED)\tgroup search filter pattern. %%u = user,\n\t\t\t\t%%g = group\n"); fprintf(stderr, "\t-B basedn (REQUIRED)\tbase dn under where to search for users\n"); fprintf(stderr, "\t-F filter (REQUIRED)\tuser search filter pattern. %%s = login\n"); fprintf(stderr, "\t-s base|one|sub\t\tsearch scope\n"); fprintf(stderr, "\t-D binddn\t\tDN to bind as to perform searches\n"); fprintf(stderr, "\t-w bindpasswd\t\tpassword for binddn\n"); fprintf(stderr, "\t-W secretfile\t\tread password for binddn from file secretfile\n"); #if HAS_URI_SUPPORT fprintf(stderr, "\t-H URI\t\t\tLDAPURI (defaults to ldap://localhost)\n"); #endif fprintf(stderr, "\t-h server\t\tLDAP server (defaults to localhost)\n"); fprintf(stderr, "\t-p port\t\t\tLDAP server port (defaults to %d)\n", LDAP_PORT); fprintf(stderr, "\t-P\t\t\tpersistent LDAP connection\n"); #if defined(NETSCAPE_SSL) fprintf(stderr, "\t-E sslcertpath\t\tenable LDAP over SSL\n"); #endif fprintf(stderr, "\t-c timeout\t\tconnect timeout\n"); fprintf(stderr, "\t-t timelimit\t\tsearch time limit\n"); fprintf(stderr, "\t-R\t\t\tdo not follow referrals\n"); fprintf(stderr, "\t-a never|always|search|find\n\t\t\t\twhen to dereference aliases\n"); #ifdef LDAP_VERSION3 fprintf(stderr, "\t-v 2|3\t\t\tLDAP version\n"); fprintf(stderr, "\t-Z\t\t\tTLS encrypt the LDAP connection, requires\n\t\t\t\tLDAP version 3\n"); #endif fprintf(stderr, "\t-g\t\t\tfirst query parameter is base DN extension\n\t\t\t\tfor this query\n"); fprintf(stderr, "\t-S\t\t\tStrip NT domain from usernames\n"); fprintf(stderr, "\t-K\t\t\tStrip Kerberos realm from usernames\n"); fprintf(stderr, "\t-d\t\t\tenable debug mode\n"); fprintf(stderr, "\n"); fprintf(stderr, "\tIf you need to bind as a user to perform searches then use the\n\t-D binddn -w bindpasswd or -D binddn -W secretfile options\n\n"); exit(1); } /* On Windows ldap_start_tls_s is available starting from Windows XP, * so we need to bind at run-time with the function entry point */ #ifdef _SQUID_MSWIN_ if (use_tls) { HMODULE WLDAP32Handle; WLDAP32Handle = GetModuleHandle("wldap32"); if ((Win32_ldap_start_tls_s = (PFldap_start_tls_s) GetProcAddress(WLDAP32Handle, LDAP_START_TLS_S)) == NULL) { fprintf(stderr, PROGRAM_NAME ": ERROR: TLS (-Z) not supported on this platform.\n"); exit(1); } } #endif while (fgets(buf, 256, stdin) != NULL) { int found = 0; if (!strchr(buf, '\n')) { /* too large message received.. skip and deny */ fprintf(stderr, "%s: ERROR: Too large: %s\n", argv[0], buf); while (fgets(buf, sizeof(buf), stdin)) { fprintf(stderr, "%s: ERROR: Too large..: %s\n", argv[0], buf); if (strchr(buf, '\n') != NULL) break; } goto error; } user = strtok(buf, " \n"); if (!user) { fprintf(stderr, "%s: Invalid request\n", argv[0]); goto error; } rfc1738_unescape(user); if (strip_nt_domain) { char *u = strrchr(user, '\\'); if (!u) u = strrchr(user, '/'); if (!u) u = strrchr(user, '+'); if (u && u[1]) user = u + 1; } if (strip_kerberos_realm) { char *u = strchr(user, '@'); if (u != NULL) { *u = '\0'; } } if (use_extension_dn) { extension_dn = strtok(NULL, " \n"); if (!extension_dn) { fprintf(stderr, "%s: Invalid request\n", argv[0]); goto error; } rfc1738_unescape(extension_dn); } while (!found && user && (group = strtok(NULL, " \n")) != NULL) { rfc1738_unescape(group); recover: if (ld == NULL) { #if HAS_URI_SUPPORT if (strstr(ldapServer, "://") != NULL) { rc = ldap_initialize(&ld, ldapServer); if (rc != LDAP_SUCCESS) { fprintf(stderr, "\nUnable to connect to LDAPURI:%s\n", ldapServer); break; } } else #endif #if NETSCAPE_SSL if (sslpath) { if (!sslinit && (ldapssl_client_init(sslpath, NULL) != LDAP_SUCCESS)) { fprintf(stderr, "\nUnable to initialise SSL with cert path %s\n", sslpath); exit(1); } else { sslinit++; } if ((ld = ldapssl_init(ldapServer, port, 1)) == NULL) { fprintf(stderr, "\nUnable to connect to SSL LDAP server: %s port:%d\n", ldapServer, port); exit(1); } } else #endif if ((ld = ldap_init(ldapServer, port)) == NULL) { fprintf(stderr, "\nUnable to connect to LDAP server:%s port:%d\n", ldapServer, port); break; } if (connect_timeout) squid_ldap_set_connect_timeout(ld, connect_timeout); #ifdef LDAP_VERSION3 if (version == -1) { version = LDAP_VERSION2; } if (ldap_set_option(ld, LDAP_OPT_PROTOCOL_VERSION, &version) != LDAP_SUCCESS) { fprintf(stderr, "Could not set LDAP_OPT_PROTOCOL_VERSION %d\n", version); ldap_unbind(ld); ld = NULL; break; } if (use_tls) { #ifdef LDAP_OPT_X_TLS if (version != LDAP_VERSION3) { fprintf(stderr, "TLS requires LDAP version 3\n"); exit(1); } else if (ldap_start_tls_s(ld, NULL, NULL) != LDAP_SUCCESS) { fprintf(stderr, "Could not Activate TLS connection\n"); ldap_unbind(ld); ld = NULL; break; } #else fprintf(stderr, "TLS not supported with your LDAP library\n"); exit(1); #endif } #endif squid_ldap_set_timelimit(ld, timelimit); squid_ldap_set_referrals(ld, !noreferrals); squid_ldap_set_aliasderef(ld, aliasderef); if (binddn && bindpasswd && *binddn && *bindpasswd) { rc = ldap_simple_bind_s(ld, binddn, bindpasswd); if (rc != LDAP_SUCCESS) { fprintf(stderr, PROGRAM_NAME " WARNING, could not bind to binddn '%s'\n", ldap_err2string(rc)); ldap_unbind(ld); ld = NULL; break; } } if (debug) fprintf(stderr, "Connected OK\n"); } if (searchLDAP(ld, group, user, extension_dn) == 0) { found = 1; break; } else { if (tryagain) { tryagain = 0; ldap_unbind(ld); ld = NULL; goto recover; } } } if (found) printf("OK\n"); else { error: printf("ERR\n"); } if (ld != NULL) { if (!persistent || (squid_ldap_errno(ld) != LDAP_SUCCESS && squid_ldap_errno(ld) != LDAP_INVALID_CREDENTIALS)) { ldap_unbind(ld); ld = NULL; } else { tryagain = 1; } } } if (ld) ldap_unbind(ld); return 0; }