/* ** Perform a search operation. ** @return #1 Function to iterate over the result entries. ** @return #2 nil. ** @return #3 nil as first entry. ** The search result is defined as an upvalue of the iterator. */ static int lualdap_search (lua_State *L) { conn_data *conn = getconnection (L); ldap_pchar_t base; ldap_pchar_t filter; char *attrs[LUALDAP_MAX_ATTRS]; int scope, attrsonly, msgid, rc, sizelimit; struct timeval st, *timeout; if (!lua_istable (L, 2)) return luaL_error (L, LUALDAP_PREFIX"no search specification"); if (!get_attrs_param (L, attrs)) return 2; /* get other parameters */ attrsonly = booltabparam (L, "attrsonly", 0); base = (ldap_pchar_t) strtabparam (L, "base", NULL); filter = (ldap_pchar_t) strtabparam (L, "filter", NULL); scope = string2scope (L, strtabparam (L, "scope", NULL)); sizelimit = longtabparam (L, "sizelimit", LDAP_NO_LIMIT); timeout = get_timeout_param (L, &st); rc = ldap_search_ext (conn->ld, base, scope, filter, attrs, attrsonly, NULL, NULL, timeout, sizelimit, &msgid); if (rc != LDAP_SUCCESS) return luaL_error (L, LUALDAP_PREFIX"%s", ldap_err2string (rc)); create_search (L, 1, msgid); lua_pushcclosure (L, next_message, 1); return 1; }
static krb5_error_code LDAP_firstkey(krb5_context context, HDB *db, unsigned flags, hdb_entry_ex *entry) { krb5_error_code ret; int msgid; ret = LDAP__connect(context, db); if (ret) return ret; ret = LDAP_no_size_limit(context, HDB2LDAP(db)); if (ret) return ret; ret = ldap_search_ext(HDB2LDAP(db), HDB2BASE(db), LDAP_SCOPE_SUBTREE, "(|(objectClass=krb5Principal)(objectClass=sambaSamAccount))", krb5kdcentry_attrs, 0, NULL, NULL, NULL, 0, &msgid); if (msgid < 0) return HDB_ERR_NOENTRY; HDBSETMSGID(db, msgid); return LDAP_seq(context, db, flags, entry); }
static int linphone_ldap_contact_provider_perform_search( LinphoneLDAPContactProvider* obj, LinphoneLDAPContactSearch* req) { int ret = -1; struct timeval timeout = { obj->timeout, 0 }; if( req->msgid == 0 ){ ms_message ( "Calling ldap_search_ext with predicate '%s' on base '%s', ld %p, attrs '%s', maxres = %d", req->filter, obj->base_object, obj->ld, obj->attributes[0], obj->max_results ); ret = ldap_search_ext(obj->ld, obj->base_object,// base from which to start LDAP_SCOPE_SUBTREE, req->filter, // search predicate obj->attributes, // which attributes to get 0, // 0 = get attrs AND value, 1 = get attrs only NULL, NULL, &timeout, // server timeout for the search obj->max_results,// max result number &req->msgid ); if( ret != LDAP_SUCCESS ){ ms_error("Error ldap_search_ext returned %d (%s)", ret, ldap_err2string(ret)); } else { ms_message("LinphoneLDAPContactSearch created @%p : msgid %d", req, req->msgid); } } else { ms_warning( "LDAP Search already performed for %s, msgid %d", req->filter, req->msgid); } return ret; }
/*********************************************************************** * ldap_search_extW (WLDAP32.@) * * Search a directory tree (asynchronous operation). * * PARAMS * ld [I] Pointer to an LDAP context. * base [I] Starting point for the search. * scope [I] Search scope. One of LDAP_SCOPE_BASE, * LDAP_SCOPE_ONELEVEL and LDAP_SCOPE_SUBTREE. * filter [I] Search filter. * attrs [I] Attributes to return. * attrsonly [I] Return no values, only attributes. * serverctrls [I] Array of LDAP server controls. * clientctrls [I] Array of LDAP client controls. * timelimit [I] Timeout in seconds. * sizelimit [I] Maximum number of entries to return. Zero means unlimited. * message [O] Message ID of the search operation. * * RETURNS * Success: LDAP_SUCCESS * Failure: An LDAP error code. * * NOTES * Call ldap_result with the message ID to get the result of * the operation. Cancel the operation by calling ldap_abandon * with the message ID. */ ULONG CDECL ldap_search_extW( WLDAP32_LDAP *ld, PWCHAR base, ULONG scope, PWCHAR filter, PWCHAR attrs[], ULONG attrsonly, PLDAPControlW *serverctrls, PLDAPControlW *clientctrls, ULONG timelimit, ULONG sizelimit, ULONG *message ) { ULONG ret = WLDAP32_LDAP_NOT_SUPPORTED; #ifdef HAVE_LDAP char *baseU = NULL, *filterU = NULL, **attrsU = NULL; LDAPControl **serverctrlsU = NULL, **clientctrlsU = NULL; struct timeval tv, *tvp = NULL; ret = WLDAP32_LDAP_NO_MEMORY; TRACE( "(%p, %s, 0x%08x, %s, %p, 0x%08x, %p, %p, 0x%08x, 0x%08x, %p)\n", ld, debugstr_w(base), scope, debugstr_w(filter), attrs, attrsonly, serverctrls, clientctrls, timelimit, sizelimit, message ); if (!ld) return ~0u; if (base) { baseU = strWtoU( base ); if (!baseU) goto exit; } if (filter) { filterU = strWtoU( filter ); if (!filterU) goto exit; } if (attrs) { attrsU = strarrayWtoU( attrs ); if (!attrsU) goto exit; } if (serverctrls) { serverctrlsU = controlarrayWtoU( serverctrls ); if (!serverctrlsU) goto exit; } if (clientctrls) { clientctrlsU = controlarrayWtoU( clientctrls ); if (!clientctrlsU) goto exit; } if (timelimit) { tv.tv_sec = timelimit; tv.tv_usec = 0; tvp = &tv; } ret = map_error( ldap_search_ext( ld, baseU, scope, filterU, attrsU, attrsonly, serverctrlsU, clientctrlsU, tvp, sizelimit, (int *)message )); exit: strfreeU( baseU ); strfreeU( filterU ); strarrayfreeU( attrsU ); controlarrayfreeU( serverctrlsU ); controlarrayfreeU( clientctrlsU ); #endif return ret; }
static void export_retrieve_key (SeahorseLDAPSource *self, GSimpleAsyncResult *res) { ExportClosure *closure = g_simple_async_result_get_op_res_gpointer (res); LDAPServerInfo *sinfo; gchar *filter; char *attrs[2]; GSource *gsource; const gchar *fingerprint; GError *error = NULL; int length, rc; int ldap_op; if (closure->current_index > 0) { fingerprint = closure->fingerprints->pdata[closure->current_index]; seahorse_progress_end (closure->cancellable, fingerprint); } closure->current_index++; /* All done, complete operation */ if (closure->current_index == (gint)closure->fingerprints->len) { g_simple_async_result_complete (res); return; } fingerprint = closure->fingerprints->pdata[closure->current_index]; seahorse_progress_begin (closure->cancellable, fingerprint); length = strlen (fingerprint); if (length > 16) fingerprint += (length - 16); filter = g_strdup_printf ("(pgpcertid=%.16s)", fingerprint); sinfo = get_ldap_server_info (self, TRUE); attrs[0] = sinfo->key_attr; attrs[1] = NULL; rc = ldap_search_ext (closure->ldap, sinfo->base_dn, LDAP_SCOPE_SUBTREE, filter, attrs, 0, NULL, NULL, NULL, 0, &ldap_op); g_free (filter); if (seahorse_ldap_source_propagate_error (self, rc, &error)) { g_simple_async_result_take_error (res, error); g_simple_async_result_complete (res); return; } gsource = seahorse_ldap_gsource_new (closure->ldap, ldap_op, closure->cancellable); g_source_set_callback (gsource, (GSourceFunc)on_export_search_completed, g_object_ref (res), g_object_unref); g_source_attach (gsource, g_main_context_default ()); g_source_unref (gsource); }
static gboolean on_connect_bind_completed (LDAPMessage *result, gpointer user_data) { GSimpleAsyncResult *res = G_SIMPLE_ASYNC_RESULT (user_data); source_connect_closure *closure = g_simple_async_result_get_op_res_gpointer (res); SeahorseLDAPSource *self = SEAHORSE_LDAP_SOURCE (g_async_result_get_source_object (user_data)); LDAPServerInfo *sinfo; GError *error = NULL; char *message; int ldap_op; int code; int rc; g_return_val_if_fail (ldap_msgtype (result) == LDAP_RES_BIND, FALSE); /* The result of the bind operation */ rc = ldap_parse_result (closure->ldap, result, &code, NULL, &message, NULL, NULL, 0); g_return_val_if_fail (rc == LDAP_SUCCESS, FALSE); ldap_memfree (message); if (seahorse_ldap_source_propagate_error (self, rc, &error)) { g_simple_async_result_take_error (res, error); g_simple_async_result_complete_in_idle (res); return FALSE; /* don't call this callback again */ } /* Check if we need server info */ sinfo = get_ldap_server_info (self, FALSE); if (sinfo != NULL) { g_simple_async_result_complete_in_idle (res); seahorse_progress_end (closure->cancellable, res); return FALSE; /* don't call this callback again */ } /* Retrieve the server info */ rc = ldap_search_ext (closure->ldap, "cn=PGPServerInfo", LDAP_SCOPE_BASE, "(objectclass=*)", (char **)SERVER_ATTRIBUTES, 0, NULL, NULL, NULL, 0, &ldap_op); if (seahorse_ldap_source_propagate_error (self, rc, &error)) { g_simple_async_result_take_error (res, error); g_simple_async_result_complete_in_idle (res); return FALSE; /* don't call this callback again */ } else { GSource *gsource = seahorse_ldap_gsource_new (closure->ldap, ldap_op, closure->cancellable); g_source_set_callback (gsource, (GSourceFunc)on_connect_server_info_completed, g_object_ref (res), g_object_unref); g_source_attach (gsource, g_main_context_default ()); g_source_unref (gsource); } return FALSE; /* don't call this callback again */ }
/* ARGSUSED */ int _ns_ldap_search_ext(char *service, int flags, char *base, int scope, char *filter, char **attrs, int attrsonly, LDAPControl **serverctrls, LDAPControl **clientctrls, struct timeval *timeoutp, int sizelimit, int *msgidp) { LDAP *ld = __s_api_getLDAPconn(flags); return (ldap_search_ext(ld, base, scope, filter, attrs, attrsonly, serverctrls, clientctrls, timeoutp, sizelimit, msgidp)); }
void LdapSearch::search( const QString &search ) { if( !init() ) return; char *attrs[] = { const_cast<char*>("userCertificate;binary"), 0 }; int err = ldap_search_ext( d->ldap, "c=EE", LDAP_SCOPE_SUBTREE, const_cast<char*>(search.toLocal8Bit().constData()), attrs, 0, 0, 0, 0, 0, &d->msg_id ); if( err ) setLastError( tr("Failed to init ldap search"), err ); else startTimer( 1000 ); }
int l_search_ping(struct ldapsearch *s) { char *attrs[2]; struct timeval tv; LDAPMessage *result; int rc; int msgid; if (s->handle == NULL) { errno=ETIMEDOUT; /* Timeout previously */ return -1; } attrs[0]="objectClass"; attrs[1]=NULL; tv.tv_sec=60*60; tv.tv_usec=0; if (ldap_search_ext(s->handle, s->base, LDAP_SCOPE_BASE, "objectClass=*", attrs, 0, NULL, NULL, &tv, 1000000, &msgid) < 0) return -1; do { const char *timeout=getenv("LDAP_SEARCH_TIMEOUT"); tv.tv_sec=atoi(timeout ? timeout:"30"); tv.tv_usec=0; rc=ldap_result(s->handle, msgid, 0, &tv, &result); if (rc <= 0) { if (rc == 0) errno=ETIMEDOUT; ldap_unbind_ext(s->handle, NULL, NULL); s->handle=NULL; return -1; } ldap_msgfree(result); } while (rc != LDAP_RES_SEARCH_RESULT); return 0; }
static void on_search_connect_completed (GObject *source, GAsyncResult *result, gpointer user_data) { GSimpleAsyncResult *res = G_SIMPLE_ASYNC_RESULT (user_data); source_search_closure *closure = g_simple_async_result_get_op_res_gpointer (res); SeahorseLDAPSource *self = SEAHORSE_LDAP_SOURCE (source); GError *error = NULL; LDAPServerInfo *sinfo; int ldap_op; int rc; closure->ldap = seahorse_ldap_source_connect_finish (SEAHORSE_LDAP_SOURCE (source), result, &error); if (error != NULL) { g_simple_async_result_take_error (res, error); g_simple_async_result_complete (res); g_object_unref (res); return; } sinfo = get_ldap_server_info (self, TRUE); g_debug ("Searching Server ... base: %s, filter: %s", sinfo->base_dn, closure->filter); rc = ldap_search_ext (closure->ldap, sinfo->base_dn, LDAP_SCOPE_SUBTREE, closure->filter, (char **)PGP_ATTRIBUTES, 0, NULL, NULL, NULL, 0, &ldap_op); if (seahorse_ldap_source_propagate_error (self, rc, &error)) { g_simple_async_result_take_error (res, error); g_simple_async_result_complete (res); } else { GSource *gsource = seahorse_ldap_gsource_new (closure->ldap, ldap_op, closure->cancellable); g_source_set_callback (gsource, (GSourceFunc)on_search_search_completed, g_object_ref (res), g_object_unref); g_source_attach (gsource, g_main_context_default ()); g_source_unref (gsource); } g_object_unref (res); }
/*********************************************************************** * ldap_searchW (WLDAP32.@) * * Search a directory tree (asynchronous operation). * * PARAMS * ld [I] Pointer to an LDAP context. * base [I] Starting point for the search. * scope [I] Search scope. One of LDAP_SCOPE_BASE, * LDAP_SCOPE_ONELEVEL and LDAP_SCOPE_SUBTREE. * filter [I] Search filter. * attrs [I] Attributes to return. * attrsonly [I] Return no values, only attributes. * * RETURNS * Success: Message ID of the search operation. * Failure: ~0u * * NOTES * Call ldap_result with the message ID to get the result of * the operation. Cancel the operation by calling ldap_abandon * with the message ID. */ ULONG CDECL ldap_searchW( WLDAP32_LDAP *ld, PWCHAR base, ULONG scope, PWCHAR filter, PWCHAR attrs[], ULONG attrsonly ) { ULONG ret = WLDAP32_LDAP_NOT_SUPPORTED; #ifdef HAVE_LDAP char *baseU = NULL, *filterU = NULL, **attrsU = NULL; int msg; ret = WLDAP32_LDAP_NO_MEMORY; TRACE( "(%p, %s, 0x%08x, %s, %p, 0x%08x)\n", ld, debugstr_w(base), scope, debugstr_w(filter), attrs, attrsonly ); if (!ld) return ~0u; if (base) { baseU = strWtoU( base ); if (!baseU) goto exit; } if (filter) { filterU = strWtoU( filter ); if (!filterU) goto exit; } if (attrs) { attrsU = strarrayWtoU( attrs ); if (!attrsU) goto exit; } ret = ldap_search_ext( ld, baseU, scope, filterU, attrsU, attrsonly, NULL, NULL, NULL, 0, &msg ); if (ret == LDAP_SUCCESS) ret = msg; else ret = ~0u; exit: strfreeU( baseU ); strfreeU( filterU ); strarrayfreeU( attrsU ); #endif return ret; }
static CURLcode ldap_do(struct connectdata *conn, bool *done) { ldapconninfo *li = conn->proto.generic; ldapreqinfo *lr; CURLcode status = CURLE_OK; int rc = 0; LDAPURLDesc *ludp = NULL; int msgid; struct SessionHandle *data=conn->data; connkeep(conn, "OpenLDAP do"); infof(data, "LDAP local: %s\n", data->change.url); rc = ldap_url_parse(data->change.url, &ludp); if(rc != LDAP_URL_SUCCESS) { const char *msg = "url parsing problem"; status = CURLE_URL_MALFORMAT; if(rc > LDAP_URL_SUCCESS && rc <= LDAP_URL_ERR_BADEXTS) { if(rc == LDAP_URL_ERR_MEM) status = CURLE_OUT_OF_MEMORY; msg = url_errs[rc]; } failf(conn->data, "LDAP local: %s", msg); return status; } rc = ldap_search_ext(li->ld, ludp->lud_dn, ludp->lud_scope, ludp->lud_filter, ludp->lud_attrs, 0, NULL, NULL, NULL, 0, &msgid); ldap_free_urldesc(ludp); if(rc != LDAP_SUCCESS) { failf(data, "LDAP local: ldap_search_ext %s", ldap_err2string(rc)); return CURLE_LDAP_SEARCH_FAILED; } lr = calloc(1, sizeof(ldapreqinfo)); if(!lr) return CURLE_OUT_OF_MEMORY; lr->msgid = msgid; data->req.protop = lr; Curl_setup_transfer(conn, FIRSTSOCKET, -1, FALSE, NULL, -1, NULL); *done = TRUE; return CURLE_OK; }
/// connects and binds to LDAP server /// @param[in] ld refernce to LDAP socket data /// @param[in] cnf reference to common configuration struct int ldaputils_search(LDAP * ld, LdapUtilsConfig * cnf, LDAPMessage ** resp) { int rc; int err; int msgid; if ((err = ldap_search_ext(ld, cnf->basedn, cnf->scope, cnf->filter, cnf->attrs, 0, NULL, NULL, NULL, -1, &msgid))) { fprintf(stderr, "%s: ldap_search_ext_s(): %s\n", PROGRAM_NAME, ldap_err2string(err)); ldap_unbind_ext_s(ld, NULL, NULL); return(-1); }; switch((err = ldap_result(ld, msgid, LDAP_MSG_ALL, NULL, resp))) { case 0: break; case -1: fprintf(stderr, "%s: ldap_result(): %s\n", PROGRAM_NAME, ldap_err2string(err)); ldap_unbind_ext_s(ld, NULL, NULL); return(-1); default: break; }; rc = ldap_parse_result(ld, *resp, &err, NULL, NULL, NULL, NULL, 0); if (rc != LDAP_SUCCESS) { fprintf(stderr, "%s: ldap_parse_result(): %s\n", PROGRAM_NAME, ldap_err2string(rc)); ldap_unbind_ext_s(ld, NULL, NULL); return(-1); }; if (err != LDAP_SUCCESS) { fprintf(stderr, "%s: ldap_parse_result(): %s\n", PROGRAM_NAME, ldap_err2string(err)); ldap_unbind_ext_s(ld, NULL, NULL); return(-1); }; return(0); }
static LDAPMessage * _dico_ldap_search(struct _dico_ldap_handle *lp, const char *filter_pat, const char *attr, const char *user) { int rc; char *filter; LDAPMessage *res; ber_int_t msgid; char *attrs[2]; attrs[0] = (char*) attr; attrs[1] = NULL; if (filter_pat) { filter = _dico_ldap_expand_user(filter_pat, user); if (!filter) { dico_log(L_ERR, ENOMEM, "_dico_ldap_expand_user"); return NULL; } } else filter = NULL; rc = ldap_search_ext(lp->ldap, lp->base, LDAP_SCOPE_SUBTREE, filter, attrs, 0, NULL, NULL, NULL, -1, &msgid); if (filter) free(filter); if (rc != LDAP_SUCCESS) { dico_log(L_ERR, 0, "ldap_search_ext: %s", ldap_err2string(rc)); /*if (rc == LDAP_NO_SUCH_OBJECT)*/ return NULL; } rc = ldap_result(lp->ldap, msgid, LDAP_MSG_ALL, NULL, &res); if (rc < 0) { dico_log(L_ERR, 0, "ldap_result failed"); return NULL; } return res; }
/* * ldap_search - initiate an ldap search operation. Parameters: * * ld LDAP descriptor * base DN of the base object * scope the search scope - one of LDAP_SCOPE_BASE, * LDAP_SCOPE_ONELEVEL, LDAP_SCOPE_SUBTREE * filter a string containing the search filter * (e.g., "(|(cn=bob)(sn=bob))") * attrs list of attribute types to return for matches * attrsonly 1 => attributes only 0 => attributes and values * * Example: * char *attrs[] = { "mail", "title", 0 }; * msgid = ldap_search( ld, "c=us@o=UM", LDAP_SCOPE_SUBTREE, "cn~=bob", * attrs, attrsonly ); */ int LDAP_CALL ldap_search( LDAP *ld, const char *base, int scope, const char *filter, char **attrs, int attrsonly ) { int msgid; LDAPDebug( LDAP_DEBUG_TRACE, "ldap_search\n", 0, 0, 0 ); if ( ldap_search_ext( ld, base, scope, filter, attrs, attrsonly, NULL, NULL, NULL, -1, &msgid ) == LDAP_SUCCESS ) { return( msgid ); } else { return( -1 ); /* error is in ld handle */ } }
int ldap_search_ext_s( LDAP *ld, LDAP_CONST char *base, int scope, LDAP_CONST char *filter, char **attrs, int attrsonly, LDAPControl **sctrls, LDAPControl **cctrls, struct timeval *timeout, int sizelimit, LDAPMessage **res ) { int rc; int msgid; rc = ldap_search_ext( ld, base, scope, filter, attrs, attrsonly, sctrls, cctrls, timeout, sizelimit, &msgid ); if ( rc != LDAP_SUCCESS ) { return( rc ); } rc = ldap_result( ld, msgid, 1, timeout, res ); if( rc <= 0 ) { /* error(-1) or timeout(0) */ return( ld->ld_errno ); } if( rc == LDAP_RES_SEARCH_REFERENCE || rc == LDAP_RES_EXTENDED_PARTIAL ) { return( ld->ld_errno ); } return( ldap_result2error( ld, *res, 0 ) ); }
NS_IMETHODIMP nsLDAPOperation::SearchExt(const nsACString& aBaseDn, PRInt32 aScope, const nsACString& aFilter, const nsACString &aAttributes, PRIntervalTime aTimeOut, PRInt32 aSizeLimit) { if (!mMessageListener) { NS_ERROR("nsLDAPOperation::SearchExt(): mMessageListener not set"); return NS_ERROR_NOT_INITIALIZED; } // XXX add control logging PR_LOG(gLDAPLogModule, PR_LOG_DEBUG, ("nsLDAPOperation::SearchExt(): called with aBaseDn = '%s'; " "aFilter = '%s'; aAttributes = %s; aSizeLimit = %d", PromiseFlatCString(aBaseDn).get(), PromiseFlatCString(aFilter).get(), PromiseFlatCString(aAttributes).get(), aSizeLimit)); LDAPControl **serverctls = 0; nsresult rv; if (mServerControls) { rv = convertControlArray(mServerControls, &serverctls); if (NS_FAILED(rv)) { PR_LOG(gLDAPLogModule, PR_LOG_ERROR, ("nsLDAPOperation::SearchExt(): error converting server " "control array: %x", rv)); return rv; } } LDAPControl **clientctls = 0; if (mClientControls) { rv = convertControlArray(mClientControls, &clientctls); if (NS_FAILED(rv)) { PR_LOG(gLDAPLogModule, PR_LOG_ERROR, ("nsLDAPOperation::SearchExt(): error converting client " "control array: %x", rv)); ldap_controls_free(serverctls); return rv; } } // Convert our comma separated string to one that the C-SDK will like, i.e. // convert to a char array and add a last NULL element. nsTArray<nsCString> attrArray; ParseString(aAttributes, ',', attrArray); char **attrs = nsnull; PRUint32 origLength = attrArray.Length(); if (origLength) { attrs = static_cast<char **> (NS_Alloc((origLength + 1) * sizeof(char *))); if (!attrs) return NS_ERROR_OUT_OF_MEMORY; for (PRUint32 i = 0; i < origLength; ++i) attrs[i] = ToNewCString(attrArray[i]); attrs[origLength] = 0; } // XXX deal with timeout here int retVal = ldap_search_ext(mConnectionHandle, PromiseFlatCString(aBaseDn).get(), aScope, PromiseFlatCString(aFilter).get(), attrs, 0, serverctls, clientctls, 0, aSizeLimit, &mMsgID); // clean up ldap_controls_free(serverctls); ldap_controls_free(clientctls); // The last entry is null, so no need to free that. NS_FREE_XPCOM_ALLOCATED_POINTER_ARRAY(origLength, attrs); rv = TranslateLDAPErrorToNSError(retVal); NS_ENSURE_SUCCESS(rv, rv); // make sure the connection knows where to call back once the messages // for this operation start coming in // rv = mConnection->AddPendingOperation(mMsgID, this); if (NS_FAILED(rv)) { switch (rv) { case NS_ERROR_OUT_OF_MEMORY: (void)ldap_abandon_ext(mConnectionHandle, mMsgID, 0, 0); return NS_ERROR_OUT_OF_MEMORY; default: (void)ldap_abandon_ext(mConnectionHandle, mMsgID, 0, 0); NS_ERROR("nsLDAPOperation::SearchExt(): unexpected error in " "mConnection->AddPendingOperation"); return NS_ERROR_UNEXPECTED; } } return NS_OK; }
extern "C" void * openSource(Source * source) { URI u; ldap_handle * h; int version; int rc; int i; char * s; int msgid; std::string locfilter; struct berval passwd; struct timeval tv; if (!source->uri.length()) throw std::runtime_error("LDAP loader requires an LDAP URI"); // Create the handle. h = new ldap_handle(); h->source = source; // Extract the binddn:password from the URI and rebuild // an authentication-less URI. try { if (!u.parse(source->uri)) throw std::runtime_error("Cannot parse URI"); if (u.user().empty() && u.password().empty()) h->binddn = u.unescape(u.userinfo()); else { h->binddn = u.user(); h->password = u.password(); } u.userinfo(""); // Parse the LDAP URI. if ((rc = ldap_url_parse(std::string(u).c_str(), &h->uri)) != LDAP_SUCCESS) throw ldap_error(rc); if (!h->uri->lud_attrs[0]) throw std::runtime_error( "LDAP url should select at least one attribute"); // Connect to LDAP server. rc = ldap_initialize(&h->ldap, ((std::string(h->uri->lud_scheme? h->uri->lud_scheme: "ldap")) + "://" + (h->uri->lud_host? h->uri->lud_host: "") + (h->uri->lud_port? ":" + std::to_string(h->uri->lud_port): "")).c_str()); if (rc != LDAP_SUCCESS) throw ldap_error(rc); // Set a very low timeout: connection should be quick. tv.tv_sec = 5; tv.tv_usec = 0; ldap_set_option(h->ldap, LDAP_OPT_NETWORK_TIMEOUT, &tv); // Bind if needed. if (ldap_get_option(h->ldap, LDAP_OPT_PROTOCOL_VERSION, &version) != LDAP_SUCCESS) version = LDAP_VERSION2; // Bind is mandatory. rc = LDAP_SUCCESS; if (!h->binddn.length()) { if (version >= LDAP_VERSION2) { // Anonymous bind is mandatory for // version 2. rc = ldap_sasl_bind_s(h->ldap, "", LDAP_SASL_SIMPLE, NULL, NULL, NULL, NULL); } } else { passwd.bv_val = (char *) h->password.c_str(); passwd.bv_len = h->password.length(); rc = ldap_sasl_bind_s(h->ldap, h->binddn.c_str(), LDAP_SASL_SIMPLE, &passwd, NULL, NULL, NULL); } if (rc != LDAP_SUCCESS) throw ldap_error(rc); // Update the given filter to not select entries not // providing mail address attributes. locfilter = h->uri->lud_filter; if (locfilter.length()) { if (locfilter[0] != '(') locfilter = std::string("(") + locfilter + ")"; locfilter = std::string("(&") + locfilter; } if (h->uri->lud_attrs[1]) locfilter += "(|"; for (i = 0; (s = h->uri->lud_attrs[i]); i++) locfilter = locfilter + "(" + s + "=*)"; if (h->uri->lud_attrs[1]) locfilter += ')'; if (h->uri->lud_filter) locfilter += ')'; rc = ldap_search_ext(h->ldap, h->uri->lud_dn, h->uri->lud_scope, locfilter.c_str(), h->uri->lud_attrs, 0, NULL, NULL, NULL, 0x7FFFFFFF, &msgid); if (rc != LDAP_SUCCESS) throw ldap_error(rc); } catch (...) { delete h; throw; } return h; }
/* * initialize the sync */ int ldap_sync_init( ldap_sync_t *ls, int mode ) { LDAPControl ctrl = { 0 }, *ctrls[ 2 ]; BerElement *ber = NULL; int rc; struct timeval tv = { 0 }, *tvp = NULL; LDAPMessage *res = NULL; #ifdef LDAP_SYNC_TRACE fprintf( stderr, "ldap_sync_init(%s)...\n", mode == LDAP_SYNC_REFRESH_AND_PERSIST ? "LDAP_SYNC_REFRESH_AND_PERSIST" : ( mode == LDAP_SYNC_REFRESH_ONLY ? "LDAP_SYNC_REFRESH_ONLY" : "unknown" ) ); #endif /* LDAP_SYNC_TRACE */ assert( ls != NULL ); assert( ls->ls_ld != NULL ); /* support both refreshOnly and refreshAndPersist */ switch ( mode ) { case LDAP_SYNC_REFRESH_AND_PERSIST: case LDAP_SYNC_REFRESH_ONLY: break; default: fprintf( stderr, "ldap_sync_init: unknown mode=%d\n", mode ); return LDAP_PARAM_ERROR; } /* check consistency of cookie and reloadHint at initial refresh */ if ( ls->ls_cookie.bv_val == NULL && ls->ls_reloadHint != 0 ) { fprintf( stderr, "ldap_sync_init: inconsistent cookie/rhint\n" ); return LDAP_PARAM_ERROR; } ctrls[ 0 ] = &ctrl; ctrls[ 1 ] = NULL; /* prepare the Sync Request control */ ber = ber_alloc_t( LBER_USE_DER ); #ifdef LDAP_SYNC_TRACE fprintf( stderr, "%sber_alloc_t() %s= NULL\n", ber == NULL ? "!!! " : "", ber == NULL ? "=" : "!" ); #endif /* LDAP_SYNC_TRACE */ if ( ber == NULL ) { rc = LDAP_NO_MEMORY; goto done; } ls->ls_refreshPhase = LDAP_SYNC_CAPI_NONE; if ( ls->ls_cookie.bv_val != NULL ) { ber_printf( ber, "{eOb}", mode, &ls->ls_cookie, ls->ls_reloadHint ); } else { ber_printf( ber, "{eb}", mode, ls->ls_reloadHint ); } rc = ber_flatten2( ber, &ctrl.ldctl_value, 0 ); #ifdef LDAP_SYNC_TRACE fprintf( stderr, "%sber_flatten2() == %d\n", rc ? "!!! " : "", rc ); #endif /* LDAP_SYNC_TRACE */ if ( rc < 0 ) { rc = LDAP_OTHER; goto done; } /* make the control critical, as we cannot proceed without */ ctrl.ldctl_oid = LDAP_CONTROL_SYNC; ctrl.ldctl_iscritical = 1; /* timelimit? */ if ( ls->ls_timelimit ) { tv.tv_sec = ls->ls_timelimit; tvp = &tv; } /* actually run the search */ rc = ldap_search_ext( ls->ls_ld, ls->ls_base, ls->ls_scope, ls->ls_filter, ls->ls_attrs, 0, ctrls, NULL, tvp, ls->ls_sizelimit, &ls->ls_msgid ); #ifdef LDAP_SYNC_TRACE fprintf( stderr, "%sldap_search_ext(\"%s\", %d, \"%s\") == %d\n", rc ? "!!! " : "", ls->ls_base, ls->ls_scope, ls->ls_filter, rc ); #endif /* LDAP_SYNC_TRACE */ if ( rc != LDAP_SUCCESS ) { goto done; } /* initial content/content update phase */ for ( ; ; ) { LDAPMessage *msg = NULL; /* NOTE: this very short timeout is just to let * ldap_result() yield long enough to get something */ tv.tv_sec = 0; tv.tv_usec = 100000; rc = ldap_result( ls->ls_ld, ls->ls_msgid, LDAP_MSG_RECEIVED, &tv, &res ); #ifdef LDAP_SYNC_TRACE fprintf( stderr, "\t%sldap_result(%d) == %d\n", rc == -1 ? "!!! " : "", ls->ls_msgid, rc ); #endif /* LDAP_SYNC_TRACE */ switch ( rc ) { case 0: /* * timeout * * TODO: can do something else in the meanwhile) */ break; case -1: /* smtg bad! */ goto done; default: for ( msg = ldap_first_message( ls->ls_ld, res ); msg != NULL; msg = ldap_next_message( ls->ls_ld, msg ) ) { int refreshDone; switch ( ldap_msgtype( msg ) ) { case LDAP_RES_SEARCH_ENTRY: rc = ldap_sync_search_entry( ls, res ); break; case LDAP_RES_SEARCH_REFERENCE: rc = ldap_sync_search_reference( ls, res ); break; case LDAP_RES_SEARCH_RESULT: rc = ldap_sync_search_result( ls, res ); goto done_search; case LDAP_RES_INTERMEDIATE: rc = ldap_sync_search_intermediate( ls, res, &refreshDone ); if ( rc != LDAP_SUCCESS || refreshDone ) { goto done_search; } break; default: #ifdef LDAP_SYNC_TRACE fprintf( stderr, "\tgot something unexpected...\n" ); #endif /* LDAP_SYNC_TRACE */ ldap_msgfree( res ); rc = LDAP_OTHER; goto done; } } ldap_msgfree( res ); res = NULL; break; } } done_search:; ldap_msgfree( res ); done:; if ( ber != NULL ) { ber_free( ber, 1 ); } return rc; }
/* * Returns an LDAP error code. */ static int docompare( LDAP *ld1, LDAP *ld2, char *base ) { int rc, msgid; LDAPMessage *res, *e; LDAPControl *ctrls[2], **serverctrls; if ( ldaptool_verbose ) { printf( "Base: %s\n\n", base ); } if ( ldaptool_not ) { return( LDAP_SUCCESS ); } if (( ctrls[0] = ldaptool_create_manage_dsait_control()) != NULL ) { ctrls[1] = NULL; serverctrls = ctrls; } else { serverctrls = NULL; } if ( ldap_search_ext( ld1, base, scope, "objectClass=*", NULL, 0, serverctrls, NULL, NULL, -1, &msgid ) != LDAP_SUCCESS ) { return( ldaptool_print_lderror( ld1, "ldap_search", LDAPTOOL_CHECK4SSL_IF_APPROP )); } /* XXXmcs: this code should be modified to display referrals and references */ while ( (rc = ldap_result( ld1, LDAP_RES_ANY, 0, NULL, &res )) == LDAP_RES_SEARCH_ENTRY ) { e = ldap_first_entry( ld1, res ); rc = cmp2( ld1, ld2, e , 0); ldap_msgfree( res ); } if ( rc == -1 ) { return( ldaptool_print_lderror( ld1, "ldap_result", LDAPTOOL_CHECK4SSL_IF_APPROP )); } if (( rc = ldap_result2error( ld1, res, 0 )) != LDAP_SUCCESS ) { (void)ldaptool_print_lderror( ld1, "ldap_search", LDAPTOOL_CHECK4SSL_IF_APPROP ); } ldap_msgfree( res ); if ( ldap_search_ext( ld2, base, scope, "objectClass=*", NULL, 0, serverctrls, NULL, NULL, -1, &msgid ) == -1 ) { return( ldaptool_print_lderror( ld2, "ldap_search", LDAPTOOL_CHECK4SSL_IF_APPROP )); } /* XXXmcs: this code should be modified to display referrals and references */ while ( (rc = ldap_result( ld2, LDAP_RES_ANY, 0, NULL, &res )) == LDAP_RES_SEARCH_ENTRY ) { e = ldap_first_entry( ld2, res ); rc = cmp2( ld2, ld1, e , 1); ldap_msgfree( res ); } if ( rc == -1 ) { return( ldaptool_print_lderror( ld2, "ldap_result", LDAPTOOL_CHECK4SSL_IF_APPROP )); } if (( rc = ldap_result2error( ld1, res, 0 )) != LDAP_SUCCESS ) { (void)ldaptool_print_lderror( ld1, "ldap_search", LDAPTOOL_CHECK4SSL_IF_APPROP ); } ldap_msgfree( res ); return( rc ); }
static DWORD LWNetSrvPingCLdapBegin( IN PLWNET_CLDAP_CONNECTION_CONTEXT pContext, IN PDNS_SERVER_INFO pServerInfo, IN PCSTR pszDnsDomainName, IN DWORD dwTimeout ) { DWORD dwError = 0; PSTR pszQuery = NULL; PSTR szAttributeList[] = { NETLOGON_LDAP_ATTRIBUTE_NAME, NULL }; struct timeval timeout = {0}; LDAP *ld = NULL; pContext->hDirectory = NULL; pContext->pServerInfo = pServerInfo; dwError = LwAllocateStringPrintf(&pszQuery, "(&(DnsDomain=%s)(NtVer=\\06\\00\\00\\80))", pszDnsDomainName); BAIL_ON_LWNET_ERROR(dwError); dwError = LwCLdapOpenDirectory(pServerInfo->pszAddress, &pContext->hDirectory); BAIL_ON_LWNET_ERROR(dwError); dwError = LwLdapBindDirectoryAnonymous(pContext->hDirectory); BAIL_ON_LWNET_ERROR(dwError); timeout.tv_sec = 0; timeout.tv_usec = dwTimeout; dwError = LWNetGetSystemTimeInMs(&pContext->StartTime); BAIL_ON_LWNET_ERROR(dwError); ld = LwLdapGetSession(pContext->hDirectory); dwError = ldap_search_ext( ld, "", LDAP_SCOPE_BASE, pszQuery, szAttributeList, 0, NULL, NULL, &timeout, 0, &pContext->msgid); dwError = LwMapLdapErrorToLwError(dwError); BAIL_ON_LWNET_ERROR(dwError); dwError = ldap_get_option( ld, LDAP_OPT_DESC, &pContext->fd); dwError = LwMapLdapErrorToLwError(dwError); BAIL_ON_LWNET_ERROR(dwError); error: if (dwError) { if (pContext->hDirectory) { LWNetSrvPingCLdapEnd(pContext); } } LWNET_SAFE_FREE_STRING(pszQuery); return dwError; }
/** Search for something in the LDAP directory * * Binds as the administrative user and performs a search, dealing with any errors. * * @param[out] result Where to store the result. Must be freed with ldap_msgfree * if LDAP_PROC_SUCCESS is returned. * May be NULL in which case result will be automatically freed after use. * @param[in] request Current request. * @param[in,out] pconn to use. May change as this function calls functions which auto re-connect. * @param[in] dn to use as base for the search. * @param[in] scope to use (LDAP_SCOPE_BASE, LDAP_SCOPE_ONE, LDAP_SCOPE_SUB). * @param[in] filter to use, should be pre-escaped. * @param[in] attrs to retrieve. * @param[in] serverctrls Search controls to pass to the server. May be NULL. * @param[in] clientctrls Search controls for ldap_search. May be NULL. * @return One of the LDAP_PROC_* (#fr_ldap_rcode_t) values. */ fr_ldap_rcode_t fr_ldap_search(LDAPMessage **result, REQUEST *request, fr_ldap_connection_t **pconn, char const *dn, int scope, char const *filter, char const * const *attrs, LDAPControl **serverctrls, LDAPControl **clientctrls) { fr_ldap_rcode_t status = LDAP_PROC_ERROR; LDAPMessage *our_result = NULL; fr_ldap_config_t const *handle_config = (*pconn)->config; int msgid; // Message id returned by // ldap_search_ext. int count = 0; // Number of results we got. struct timeval tv; // Holds timeout values. LDAPControl *our_serverctrls[LDAP_MAX_CONTROLS]; LDAPControl *our_clientctrls[LDAP_MAX_CONTROLS]; fr_ldap_control_merge(our_serverctrls, our_clientctrls, sizeof(our_serverctrls) / sizeof(*our_serverctrls), sizeof(our_clientctrls) / sizeof(*our_clientctrls), *pconn, serverctrls, clientctrls); rad_assert(*pconn && (*pconn)->handle); if (DEBUG_ENABLED4 || (request && RDEBUG_ENABLED4)) { fr_ldap_timeout_debug(request, *pconn, NULL, __FUNCTION__); } /* * OpenLDAP library doesn't declare attrs array as const, but * it really should be *sigh*. */ char **search_attrs; memcpy(&search_attrs, &attrs, sizeof(attrs)); /* * Do all searches as the admin user. */ if ((*pconn)->rebound) { status = fr_ldap_bind(request, pconn, (*pconn)->config->admin_identity, (*pconn)->config->admin_password, &(*pconn)->config->admin_sasl, NULL, NULL, NULL); if (status != LDAP_PROC_SUCCESS) return LDAP_PROC_ERROR; rad_assert(*pconn); (*pconn)->rebound = false; } if (filter) { ROPTIONAL(RDEBUG2, DEBUG2, "Performing search in \"%s\" with filter \"%s\", scope \"%s\"", dn, filter, fr_int2str(fr_ldap_scope, scope, "<INVALID>")); } else { ROPTIONAL(RDEBUG2, DEBUG2, "Performing unfiltered search in \"%s\", scope \"%s\"", dn, fr_int2str(fr_ldap_scope, scope, "<INVALID>")); } /* * If LDAP search produced an error it should also be logged * to the ld. result should pick it up without us * having to pass it explicitly. */ memset(&tv, 0, sizeof(tv)); (void) ldap_search_ext((*pconn)->handle, dn, scope, filter, search_attrs, 0, our_serverctrls, our_clientctrls, NULL, 0, &msgid); ROPTIONAL(RDEBUG2, DEBUG2, "Waiting for search result..."); status = fr_ldap_result(&our_result, NULL, *pconn, msgid, 1, dn, NULL); switch (status) { case LDAP_PROC_SUCCESS: break; default: ROPTIONAL(RPEDEBUG, PERROR, "Failed performing search"); goto finish; } count = ldap_count_entries((*pconn)->handle, our_result); if (count < 0) { ROPTIONAL(REDEBUG, ERROR, "Error counting results: %s", fr_ldap_error_str(*pconn)); status = LDAP_PROC_ERROR; ldap_msgfree(our_result); our_result = NULL; } else if (count == 0) { ROPTIONAL(RDEBUG2, DEBUG2, "Search returned no results"); status = LDAP_PROC_NO_RESULT; ldap_msgfree(our_result); our_result = NULL; } finish: /* * We always need to get the result to count entries, but the caller * may not of requested one. If that's the case, free it, else write * it to where our caller said. */ if (!result) { if (our_result) ldap_msgfree(our_result); } else { *result = our_result; } return status; }
/** Search for something in the LDAP directory * * Binds as the administrative user and performs a search, dealing with any errors. * * @param[out] msgid to match response to request. * @param[in] request Current request. * @param[in,out] pconn to use. May change as this function calls functions which auto re-connect. * @param[in] dn to use as base for the search. * @param[in] scope to use (LDAP_SCOPE_BASE, LDAP_SCOPE_ONE, LDAP_SCOPE_SUB). * @param[in] filter to use, should be pre-escaped. * @param[in] attrs to retrieve. * @param[in] serverctrls Search controls to pass to the server. May be NULL. * @param[in] clientctrls Search controls for ldap_search. May be NULL. * @return One of the LDAP_PROC_* (#fr_ldap_rcode_t) values. */ fr_ldap_rcode_t fr_ldap_search_async(int *msgid, REQUEST *request, fr_ldap_connection_t **pconn, char const *dn, int scope, char const *filter, char const * const *attrs, LDAPControl **serverctrls, LDAPControl **clientctrls) { fr_ldap_rcode_t status = LDAP_PROC_ERROR; fr_ldap_config_t const *handle_config = (*pconn)->config; struct timeval tv; // Holds timeout values. LDAPControl *our_serverctrls[LDAP_MAX_CONTROLS]; LDAPControl *our_clientctrls[LDAP_MAX_CONTROLS]; fr_ldap_control_merge(our_serverctrls, our_clientctrls, sizeof(our_serverctrls) / sizeof(*our_serverctrls), sizeof(our_clientctrls) / sizeof(*our_clientctrls), *pconn, serverctrls, clientctrls); rad_assert(*pconn && (*pconn)->handle); if (DEBUG_ENABLED4 || (request && RDEBUG_ENABLED4)) fr_ldap_timeout_debug(request, *pconn, NULL, __FUNCTION__); /* * OpenLDAP library doesn't declare attrs array as const, but * it really should be *sigh*. */ char **search_attrs; memcpy(&search_attrs, &attrs, sizeof(attrs)); /* * Do all searches as the admin user. */ if ((*pconn)->rebound) { status = fr_ldap_bind(request, pconn, (*pconn)->config->admin_identity, (*pconn)->config->admin_password, &(*pconn)->config->admin_sasl, NULL, NULL, NULL); if (status != LDAP_PROC_SUCCESS) return LDAP_PROC_ERROR; rad_assert(*pconn); (*pconn)->rebound = false; } if (filter) { ROPTIONAL(RDEBUG2, DEBUG2, "Performing search in \"%s\" with filter \"%s\", scope \"%s\"", dn, filter, fr_int2str(fr_ldap_scope, scope, "<INVALID>")); } else { ROPTIONAL(RDEBUG2, DEBUG2, "Performing unfiltered search in \"%s\", scope \"%s\"", dn, fr_int2str(fr_ldap_scope, scope, "<INVALID>")); } /* * If LDAP search produced an error it should also be logged * to the ld. result should pick it up without us * having to pass it explicitly. */ memset(&tv, 0, sizeof(tv)); if (ldap_search_ext((*pconn)->handle, dn, scope, filter, search_attrs, 0, our_serverctrls, our_clientctrls, NULL, 0, msgid) != LDAP_SUCCESS) { int ldap_errno; ldap_get_option((*pconn)->handle, LDAP_OPT_ERROR_NUMBER, &ldap_errno); ERROR("Failed performing search: %s", ldap_err2string(ldap_errno)); return LDAP_PROC_ERROR; } return LDAP_PROC_SUCCESS; }
void OPENLDAP::Book::refresh_bound () { int result = LDAP_SUCCESS; struct timeval timeout = { 1, 0}; /* block 1s */ LDAPMessage *msg_entry = NULL; int msgid; std::string filter, fterm; const char *fstr; size_t pos; if (bookinfo.sasl) goto sasl_bound; result = ldap_result (ldap_context, LDAP_RES_ANY, LDAP_MSG_ALL, &timeout, &msg_entry); if (result <= 0) { if (patience == 3) { patience--; Ekiga::Runtime::run_in_main (boost::bind (&OPENLDAP::Book::refresh_bound, this), 12); } else if (patience == 2) { patience--; Ekiga::Runtime::run_in_main (boost::bind (&OPENLDAP::Book::refresh_bound, this), 21); } else if (patience == 1) { patience--; Ekiga::Runtime::run_in_main (boost::bind (&OPENLDAP::Book::refresh_bound, this), 30); } else { // patience == 0 status = std::string (_("Could not connect to server")); updated (this->shared_from_this ()); ldap_unbind_ext (ldap_context, NULL, NULL); ldap_context = NULL; } if (msg_entry != NULL) ldap_msgfree (msg_entry); return; } (void) ldap_msgfree (msg_entry); sasl_bound: if (!search_filter.empty ()) { if (search_filter[0] == '(' && search_filter[search_filter.length()-1] == ')') { fstr = search_filter.c_str(); goto do_search; } fterm = "*" + search_filter + "*"; } else { fterm = "*"; } if (bookinfo.urld->lud_filter != NULL) filter = std::string (bookinfo.urld->lud_filter); else filter=""; pos = 0; while ((pos=filter.find('$', pos)) != std::string::npos) { filter.replace (pos, 1, fterm); pos += fterm.length(); } fstr = filter.c_str(); do_search: msgid = ldap_search_ext (ldap_context, bookinfo.urld->lud_dn, bookinfo.urld->lud_scope, fstr, bookinfo.urld->lud_attrs, 0, /* attrsonly */ NULL, NULL, NULL, 0, &msgid); if (msgid == -1) { status = std::string (_("Could not search")); updated (this->shared_from_this ()); ldap_unbind_ext (ldap_context, NULL, NULL); ldap_context = NULL; return; } else { status = std::string (_("Waiting for search results")); updated (this->shared_from_this ()); } patience = 3; refresh_result (); }
int main( int argc, char **argv ) { LDAP *ld; LDAPMessage *result, *e; BerElement *ber; char *a, *dn; char **vals; int i; int rc; int finished; int msgid; int num_entries = 0; int version = LDAP_VERSION3; LDAPControl *ctrls[2], *psctrl, **ectrls; /* arrange to use LDAP version 3 */ if ( ldap_set_option( NULL, LDAP_OPT_PROTOCOL_VERSION, &version ) != 0 ) { perror( "ldap_set_option" ); return( 1 ); } /* get a handle to an LDAP connection */ if ( (ld = ldap_init( MY_HOST, MY_PORT )) == NULL ) { perror( "ldap_init" ); 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" ); ldap_unbind( ld ); return( 1 ); } /* construct the Persistent Search control */ if ( ldap_create_persistentsearch_control( ld, LDAP_CHANGETYPE_ANY, 1 /* changesOnly */, 1 /* request entry change controls */, 1 /* critical */, &psctrl ) != LDAP_SUCCESS ) { ldap_perror( ld, "ldap_create_persistentsearch_control" ); ldap_unbind( ld ); return( 1 ); } ctrls[0] = psctrl; ctrls[1] = NULL; /* issue a persistent search for all entries with surname of Jensen */ if ( LDAP_SUCCESS != ldap_search_ext( ld, MY_SEARCHBASE, LDAP_SCOPE_SUBTREE, MY_FILTER, NULL /* all attrs */, 0 /* get attrs and values */, ctrls, NULL /* no client ctrls */, NULL /* no timeout */, 0 /* no sizelimit */, &msgid )) { ldap_perror( ld, "ldap_search_ext" ); ldap_unbind( ld ); return( 1 ); } ldap_control_free( psctrl ); /* no longer needed */ /* * Loop, polling for results until finished. * Since this is a persistent search, this loop won't end until the * server shuts down or we lose the connection for some other reason. * We could abandon the persistent search or close the connection of * course, but we don't in this example. */ 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, NULL /* no timeout */, &result ); switch ( rc ) { case -1: /* some error occurred */ ldap_perror( ld, "ldap_result" ); ldap_unbind( ld ); 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; } num_entries++; /* for each entry print out name */ if (( dn = ldap_get_dn( ld, e )) != NULL ) { printf( "dn: %s\n", dn ); ldap_memfree( dn ); } /* print entry change info. if it was returned */ if ( LDAP_SUCCESS == ldap_get_entry_controls( ld, e, &ectrls )) { int chgnumpresent; ber_int_t chgtype; ber_int_t chgnum; char *prevdn; if ( LDAP_SUCCESS == ldap_parse_entrychange_control( ld, ectrls, &chgtype, &prevdn, &chgnumpresent, &chgnum )) { printf( "changeType: %s\n", changetype_num2string( chgtype )); if ( prevdn != NULL ) { printf( "previousDN: %s\n", prevdn ); ldap_memfree( prevdn ); } if ( chgnumpresent ) { printf( "changeNumber: %d\n", chgnum ); } ldap_controls_free( ectrls ); } } /* print out all attrs and values */ 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 ); } } /* All done. Print a summary. */ printf( "%d entries retrieved.\n", num_entries ); ldap_unbind( ld ); return( 0 ); }
/* * ldap_load: * opens the connection only if needed. */ static LibBalsaABErr libbalsa_address_book_ldap_load(LibBalsaAddressBook * ab, const gchar *filter, LibBalsaAddressBookLoadFunc callback, gpointer closure) { LibBalsaAddressBookLdap *ldap_ab; LibBalsaAddress *address; LDAPMessage *msg, *result; int msgid, rc, attempt; gchar *ldap_filter; g_return_val_if_fail ( LIBBALSA_IS_ADDRESS_BOOK_LDAP(ab), LBABERR_OK); if (callback == NULL) return LBABERR_OK; ldap_ab = LIBBALSA_ADDRESS_BOOK_LDAP(ab); /* * Connect to the server. */ for(attempt=0; attempt<2; attempt++) { if (ldap_ab->directory == NULL) { if ((rc=libbalsa_address_book_ldap_open_connection(ldap_ab)) != LDAP_SUCCESS) return LBABERR_CANNOT_CONNECT; } /* * Attempt to search for e-mail addresses. It returns success * or failure, but not all the matches. * we use the asynchronous lookup to fetch the results in chunks * in case we exceed administrative limits. */ /* g_print("Performing full lookup…\n"); */ ldap_filter = filter ? g_strdup_printf("(&(objectClass=organizationalPerson)(mail=*)" "(|(cn=%s*)(sn=%s*)(mail=%s*@*)))", filter, filter, filter) : g_strdup("(&(objectClass=organizationalPerson)(mail=*))"); if(DEBUG_LDAP) g_print("Send LDAP request: %s (basedn=%s)\n", ldap_filter, ldap_ab->base_dn); if(ldap_search_ext(ldap_ab->directory, ldap_ab->base_dn, LDAP_SCOPE_SUBTREE, ldap_filter, book_attrs, 0, NULL, NULL, NULL, ABL_SIZE_LIMIT, &msgid) != LDAP_SUCCESS) { libbalsa_address_book_ldap_close_connection(ldap_ab); continue; /* try again */ } /* * Now loop over all the results, and spit out the output. */ while((rc=ldap_result(ldap_ab->directory, msgid, LDAP_MSG_ONE, NULL, &result))>0) { msg = ldap_first_entry(ldap_ab->directory, result); if (!msg || ldap_msgtype( msg ) == LDAP_RES_SEARCH_RESULT) break; address = libbalsa_address_book_ldap_get_address(ab, msg); callback(ab, address, closure); g_object_unref(address); } if(rc == -1) { /* try again */ libbalsa_address_book_ldap_close_connection(ldap_ab); continue; } callback(ab, NULL, closure); ldap_msgfree(result); libbalsa_address_book_set_status(ab, NULL); return LBABERR_OK; } /* we have tried and failed... */ /* extended status? */ return LBABERR_CANNOT_SEARCH; }
static void do_search( char *uri, char *manager, struct berval *passwd, char *sbase, int scope, char *filter, LDAP **ldp, char **attrs, int noattrs, int nobind, int innerloop, int maxretries, int delay, int force, int chaserefs ) { LDAP *ld = ldp ? *ldp : NULL; int i = 0, do_retry = maxretries; int rc = LDAP_SUCCESS; int version = LDAP_VERSION3; char buf[ BUFSIZ ]; int *msgids = NULL, active = 0; /* make room for msgid */ if ( swamp > 1 ) { msgids = (int *)calloc( sizeof(int), innerloop ); } retry:; if ( ld == NULL ) { ldap_initialize( &ld, uri ); if ( ld == NULL ) { tester_perror( "ldap_initialize", NULL ); exit( EXIT_FAILURE ); } (void) ldap_set_option( ld, LDAP_OPT_PROTOCOL_VERSION, &version ); (void) ldap_set_option( ld, LDAP_OPT_REFERRALS, chaserefs ? LDAP_OPT_ON : LDAP_OPT_OFF ); if ( do_retry == maxretries ) { fprintf( stderr, "PID=%ld - Search(%d): " "base=\"%s\" scope=%s filter=\"%s\" " "attrs=%s%s.\n", (long) pid, innerloop, sbase, ldap_pvt_scope2str( scope ), filter, attrs[0], attrs[1] ? " (more...)" : "" ); } if ( nobind == 0 ) { rc = ldap_sasl_bind_s( ld, manager, LDAP_SASL_SIMPLE, passwd, NULL, NULL, NULL ); if ( rc != LDAP_SUCCESS ) { snprintf( buf, sizeof( buf ), "bindDN=\"%s\"", manager ); tester_ldap_error( ld, "ldap_sasl_bind_s", buf ); switch ( rc ) { case LDAP_BUSY: case LDAP_UNAVAILABLE: if ( do_retry > 0 ) { ldap_unbind_ext( ld, NULL, NULL ); ld = NULL; do_retry--; if ( delay != 0 ) { sleep( delay ); } goto retry; } /* fallthru */ default: break; } exit( EXIT_FAILURE ); } } } if ( swamp > 1 ) { do { LDAPMessage *res = NULL; int j, msgid; if ( i < innerloop ) { rc = ldap_search_ext( ld, sbase, scope, filter, NULL, noattrs, NULL, NULL, NULL, LDAP_NO_LIMIT, &msgids[i] ); active++; #if 0 fprintf( stderr, ">>> PID=%ld - Search maxloop=%d cnt=%d active=%d msgid=%d: " "base=\"%s\" scope=%s filter=\"%s\"\n", (long) pid, innerloop, i, active, msgids[i], sbase, ldap_pvt_scope2str( scope ), filter ); #endif i++; if ( rc ) { int first = tester_ignore_err( rc ); /* if ignore.. */ if ( first ) { /* only log if first occurrence */ if ( ( force < 2 && first > 0 ) || abs(first) == 1 ) { tester_ldap_error( ld, "ldap_search_ext", NULL ); } continue; } /* busy needs special handling */ snprintf( buf, sizeof( buf ), "base=\"%s\" filter=\"%s\"\n", sbase, filter ); tester_ldap_error( ld, "ldap_search_ext", buf ); if ( rc == LDAP_BUSY && do_retry > 0 ) { ldap_unbind_ext( ld, NULL, NULL ); ld = NULL; do_retry--; goto retry; } break; } if ( swamp > 2 ) { continue; } } rc = ldap_result( ld, LDAP_RES_ANY, 0, NULL, &res ); switch ( rc ) { case -1: /* gone really bad */ goto cleanup; case 0: /* timeout (impossible) */ break; case LDAP_RES_SEARCH_ENTRY: case LDAP_RES_SEARCH_REFERENCE: /* ignore */ break; case LDAP_RES_SEARCH_RESULT: /* just remove, no error checking (TODO?) */ msgid = ldap_msgid( res ); ldap_parse_result( ld, res, &rc, NULL, NULL, NULL, NULL, 1 ); res = NULL; /* linear search, bah */ for ( j = 0; j < i; j++ ) { if ( msgids[ j ] == msgid ) { msgids[ j ] = -1; active--; #if 0 fprintf( stderr, "<<< PID=%ld - SearchDone maxloop=%d cnt=%d active=%d msgid=%d: " "base=\"%s\" scope=%s filter=\"%s\"\n", (long) pid, innerloop, j, active, msgid, sbase, ldap_pvt_scope2str( scope ), filter ); #endif break; } } break; default: /* other messages unexpected */ fprintf( stderr, "### PID=%ld - Search(%d): " "base=\"%s\" scope=%s filter=\"%s\" " "attrs=%s%s. unexpected response tag=%d\n", (long) pid, innerloop, sbase, ldap_pvt_scope2str( scope ), filter, attrs[0], attrs[1] ? " (more...)" : "", rc ); break; } if ( res != NULL ) { ldap_msgfree( res ); } } while ( i < innerloop || active > 0 ); } else { for ( ; i < innerloop; i++ ) { LDAPMessage *res = NULL; if (swamp) { int msgid; rc = ldap_search_ext( ld, sbase, scope, filter, NULL, noattrs, NULL, NULL, NULL, LDAP_NO_LIMIT, &msgid ); if ( rc == LDAP_SUCCESS ) continue; else break; } rc = ldap_search_ext_s( ld, sbase, scope, filter, attrs, noattrs, NULL, NULL, NULL, LDAP_NO_LIMIT, &res ); if ( res != NULL ) { ldap_msgfree( res ); } if ( rc ) { int first = tester_ignore_err( rc ); /* if ignore.. */ if ( first ) { /* only log if first occurrence */ if ( ( force < 2 && first > 0 ) || abs(first) == 1 ) { tester_ldap_error( ld, "ldap_search_ext_s", NULL ); } continue; } /* busy needs special handling */ snprintf( buf, sizeof( buf ), "base=\"%s\" filter=\"%s\"\n", sbase, filter ); tester_ldap_error( ld, "ldap_search_ext_s", buf ); if ( rc == LDAP_BUSY && do_retry > 0 ) { ldap_unbind_ext( ld, NULL, NULL ); ld = NULL; do_retry--; goto retry; } break; } } } cleanup:; if ( msgids != NULL ) { free( msgids ); } if ( ldp != NULL ) { *ldp = ld; } else { fprintf( stderr, " PID=%ld - Search done (%d).\n", (long) pid, rc ); if ( ld != NULL ) { ldap_unbind_ext( ld, NULL, NULL ); } } }
static int do_base( char *uri, char *dn, struct berval *pass, char *base, char *filter, char *pwattr, int maxloop, int force, int chaserefs, int noinit, int delay, int action_type, void *action ) { LDAP *ld = NULL; int i = 0; int rc = LDAP_SUCCESS; ber_int_t msgid; LDAPMessage *res, *msg; char **dns = NULL; struct berval *creds = NULL; char *attrs[] = { LDAP_NO_ATTRS, NULL }; int ndns = 0; #ifdef _WIN32 DWORD beg, end; #else struct timeval beg, end; #endif int version = LDAP_VERSION3; char *nullstr = ""; ldap_initialize( &ld, uri ); if ( ld == NULL ) { tester_perror( "ldap_initialize", NULL ); exit( EXIT_FAILURE ); } (void) ldap_set_option( ld, LDAP_OPT_PROTOCOL_VERSION, &version ); (void) ldap_set_option( ld, LDAP_OPT_REFERRALS, chaserefs ? LDAP_OPT_ON: LDAP_OPT_OFF ); rc = ldap_sasl_bind_s( ld, dn, LDAP_SASL_SIMPLE, pass, NULL, NULL, NULL ); if ( rc != LDAP_SUCCESS ) { tester_ldap_error( ld, "ldap_sasl_bind_s", NULL ); exit( EXIT_FAILURE ); } fprintf( stderr, "PID=%ld - Bind(%d): base=\"%s\", filter=\"%s\" attr=\"%s\".\n", (long) pid, maxloop, base, filter, pwattr ); if ( pwattr != NULL ) { attrs[ 0 ] = pwattr; } rc = ldap_search_ext( ld, base, LDAP_SCOPE_SUBTREE, filter, attrs, 0, NULL, NULL, 0, 0, &msgid ); if ( rc != LDAP_SUCCESS ) { tester_ldap_error( ld, "ldap_search_ext", NULL ); exit( EXIT_FAILURE ); } while ( ( rc = ldap_result( ld, LDAP_RES_ANY, LDAP_MSG_ONE, NULL, &res ) ) > 0 ) { BerElement *ber; struct berval bv; int done = 0; for ( msg = ldap_first_message( ld, res ); msg; msg = ldap_next_message( ld, msg ) ) { switch ( ldap_msgtype( msg ) ) { case LDAP_RES_SEARCH_ENTRY: rc = ldap_get_dn_ber( ld, msg, &ber, &bv ); dns = realloc( dns, (ndns + 1)*sizeof(char *) ); dns[ndns] = ber_strdup( bv.bv_val ); if ( pwattr != NULL ) { struct berval **values = ldap_get_values_len( ld, msg, pwattr ); creds = realloc( creds, (ndns + 1)*sizeof(struct berval) ); if ( values == NULL ) { novals:; creds[ndns].bv_len = 0; creds[ndns].bv_val = nullstr; } else { static struct berval cleartext = BER_BVC( "{CLEARTEXT} " ); struct berval value = *values[ 0 ]; if ( value.bv_val[ 0 ] == '{' ) { char *end = ber_bvchr( &value, '}' ); if ( end ) { if ( ber_bvcmp( &value, &cleartext ) == 0 ) { value.bv_val += cleartext.bv_len; value.bv_len -= cleartext.bv_len; } else { ldap_value_free_len( values ); goto novals; } } } ber_dupbv( &creds[ndns], &value ); ldap_value_free_len( values ); } } ndns++; ber_free( ber, 0 ); break; case LDAP_RES_SEARCH_RESULT: done = 1; break; } if ( done ) break; } ldap_msgfree( res ); if ( done ) break; } #ifdef _WIN32 beg = GetTickCount(); #else gettimeofday( &beg, NULL ); #endif if ( ndns == 0 ) { tester_error( "No DNs" ); return 1; } fprintf( stderr, " PID=%ld - Bind base=\"%s\" filter=\"%s\" got %d values.\n", (long) pid, base, filter, ndns ); /* Ok, got list of DNs, now start binding to each */ for ( i = 0; i < maxloop; i++ ) { int j; struct berval cred = { 0, NULL }; #if 0 /* use high-order bits for better randomness (Numerical Recipes in "C") */ j = rand() % ndns; #endif j = ((double)ndns)*rand()/(RAND_MAX + 1.0); if ( creds && !BER_BVISEMPTY( &creds[j] ) ) { cred = creds[j]; } if ( do_bind( uri, dns[j], &cred, 1, force, chaserefs, noinit, &ld, action_type, action ) && !force ) { break; } if ( delay ) { sleep( delay ); } } if ( ld != NULL ) { ldap_unbind_ext( ld, NULL, NULL ); ld = NULL; } #ifdef _WIN32 end = GetTickCount(); end -= beg; fprintf( stderr, " PID=%ld - Bind done %d in %d.%03d seconds.\n", (long) pid, i, end / 1000, end % 1000 ); #else gettimeofday( &end, NULL ); end.tv_usec -= beg.tv_usec; if (end.tv_usec < 0 ) { end.tv_usec += 1000000; end.tv_sec -= 1; } end.tv_sec -= beg.tv_sec; fprintf( stderr, " PID=%ld - Bind done %d in %ld.%06ld seconds.\n", (long) pid, i, (long) end.tv_sec, (long) end.tv_usec ); #endif if ( dns ) { for ( i = 0; i < ndns; i++ ) { ber_memfree( dns[i] ); } free( dns ); } if ( creds ) { for ( i = 0; i < ndns; i++ ) { if ( creds[i].bv_val != nullstr ) { ber_memfree( creds[i].bv_val ); } } free( creds ); } return 0; }
static int _mu_ldap_search (LDAP *ld, const char *filter_pat, const char *key, struct mu_auth_data **return_data) { int rc; char **attrs; size_t nattrs; LDAPMessage *res, *msg; ber_int_t msgid; const char *env[3]; struct mu_wordsplit ws; rc = _construct_attr_array (&nattrs, &attrs); if (rc) return rc; env[0] = "user"; env[1] = key; env[2] = NULL; ws.ws_env = env; if (mu_wordsplit (filter_pat, &ws, MU_WRDSF_NOSPLIT | MU_WRDSF_NOCMD | MU_WRDSF_ENV | MU_WRDSF_ENV_KV)) { mu_error (_("cannot expand line `%s': %s"), filter_pat, mu_wordsplit_strerror (&ws)); return MU_ERR_FAILURE; } else if (ws.ws_wordc == 0) { mu_error (_("expanding %s yields empty string"), filter_pat); mu_wordsplit_free (&ws); mu_argcv_free (nattrs, attrs); return MU_ERR_FAILURE; } rc = ldap_search_ext (ld, ldap_param.base, LDAP_SCOPE_SUBTREE, ws.ws_wordv[0], attrs, 0, NULL, NULL, NULL, -1, &msgid); mu_wordsplit_free (&ws); mu_argcv_free (nattrs, attrs); if (rc != LDAP_SUCCESS) { mu_error ("ldap_search_ext: %s", ldap_err2string (rc)); if (rc == LDAP_NO_SUCH_OBJECT) return MU_ERR_NOENT; else return MU_ERR_FAILURE; } rc = ldap_result (ld, msgid, LDAP_MSG_ALL, NULL, &res ); if (rc < 0) { mu_error ("ldap_result failed"); return MU_ERR_FAILURE; } rc = ldap_count_entries (ld, res); if (rc == 0) { mu_error ("not enough entires"); return MU_ERR_NOENT; } if (rc > 1) mu_error ("LDAP: too many entries for key %s", key); msg = ldap_first_entry (ld, res); rc = _mu_entry_to_auth_data (ld, msg, return_data); ldap_msgfree (res); return rc; }
int ld_cmd_exec(db_res_t* res, db_cmd_t* cmd) { db_con_t* con; struct ld_res* lres; struct ld_cmd* lcmd; struct ld_con* lcon; char* filter, *err_desc; int ret, err; LDAPMessage *msg, *resmsg; int reconn_cnt; int msgid; char *oid; struct berval *data; struct timeval restimeout; filter = NULL; err_desc = NULL; resmsg = NULL; /* First things first: retrieve connection info from the currently active * connection and also mysql payload from the database command */ con = cmd->ctx->con[db_payload_idx]; lcmd = DB_GET_PAYLOAD(cmd); lcon = DB_GET_PAYLOAD(con); reconn_cnt = ld_reconnect_attempt; if (ld_prepare_ldap_filter(&filter, cmd, &lcmd->filter) < 0) { ERR("ldap: Error while building LDAP search filter\n"); goto error; } DBG("ldap: ldap_search(base:'%s', filter:'%s')\n", lcmd->base, filter); do { if (lcon->flags & LD_CONNECTED) { ldap_set_option(lcon->con, LDAP_OPT_DEREF, ((void *)&lcmd->chase_references)); /* there is alternative method using LDAP_CONTROL_REFERRALS per request but is not well documented */ ldap_set_option(lcon->con, LDAP_OPT_REFERRALS, lcmd->chase_referrals?LDAP_OPT_ON:LDAP_OPT_OFF); ret = ldap_search_ext(lcon->con, lcmd->base, lcmd->scope, filter, lcmd->result, 0, NULL, NULL, lcmd->timelimit.tv_sec ? &lcmd->timelimit : NULL, lcmd->sizelimit, &msgid); if (ret != LDAP_SUCCESS) { ERR("ldap: Error while searching: %s\n", ldap_err2string(ret)); goto error; } /* openldap v2.3 library workaround for unsolicited messages: if only unsolicited messages are available then ldap_result of v2.3 library waits forever */ memset(&restimeout, 0, sizeof(restimeout)); restimeout.tv_sec = 5; ret = ldap_result(lcon->con, LDAP_RES_ANY, LDAP_MSG_ALL, &restimeout, &resmsg); } else { /* force it to reconnect */ ret = -1; } if (ret <= 0) { ERR("ldap: Error in ldap_search: %s\n", ret < 0 ? ldap_err2string(ret) : "timeout"); if (ret == LDAP_SERVER_DOWN) { lcon->flags &= ~LD_CONNECTED; do { if (!reconn_cnt) { ERR("ldap: maximum reconnection attempt reached! giving up\n"); goto error; } reconn_cnt--; err = ld_con_connect(con); } while (err != 0); } else { goto error; } } } while (ret <= 0); /* looking for unsolicited messages */ for (msg = ldap_first_message(lcon->con, resmsg); msg != NULL; msg = ldap_next_message(lcon->con, msg)) { if (ldap_msgtype(msg) == LDAP_RES_EXTENDED) { if (ldap_parse_extended_result(lcon->con, msg, &oid, &data, 0) != LDAP_SUCCESS) { ERR("ldap: Error while parsing extended result\n"); goto error; } if (oid != NULL) { if (strcmp(oid, LDAP_NOTICE_OF_DISCONNECTION) == 0) { WARN("ldap: Notice of Disconnection (OID: %s)\n", oid); } else { WARN("ldap: Unsolicited message received. OID: %s\n", oid); } ldap_memfree(oid); } if (data != NULL) { WARN("ldap: Unsolicited message data: %.*s\n", (int)data->bv_len, data->bv_val); ber_bvfree(data); } } } ret = ldap_parse_result(lcon->con, resmsg, &err, NULL, &err_desc, NULL, NULL, 0); if (ret != LDAP_SUCCESS) { ERR("ldap: Error while reading result status: %s\n", ldap_err2string(ret)); goto error; } if (err != LDAP_SUCCESS) { ERR("ldap: LDAP server reports error: %s\n", ldap_err2string(err)); goto error; } if (res) { lres = DB_GET_PAYLOAD(res); lres->msg = resmsg; } else if (resmsg) { ldap_msgfree(resmsg); } if (filter) pkg_free(filter); if (err_desc) ldap_memfree(err_desc); return 0; error: if (filter) pkg_free(filter); if (resmsg) ldap_msgfree(resmsg); if (err_desc) ldap_memfree(err_desc); return -1; }