/* parses a message to construct a nice contact */ OPENLDAP::ContactPtr OPENLDAP::Book::parse_result (LDAPMessage* message) { ContactPtr result; BerElement *ber = NULL; struct berval bv, *bvals; std::string username; std::map<std::string, std::string> call_addresses; char **attributes = bookinfo.urld->lud_attrs; int i, rc; /* skip past entry DN */ rc = ldap_get_dn_ber (ldap_context, message, &ber, &bv); while (rc == LDAP_SUCCESS) { rc = ldap_get_attribute_ber (ldap_context, message, ber, &bv, &bvals); if (bv.bv_val == NULL) break; if (attributes[0] == NULL || !g_ascii_strcasecmp(bv.bv_val, attributes[0])) { username = std::string (bvals[0].bv_val, bvals[0].bv_len); } else { for (i=1; attributes[i]; i++) { if (!g_ascii_strcasecmp(bv.bv_val,attributes[i]) && bvals && bvals[0].bv_val ) { /* FIXME: this is annoying. Assume if a colon is present that * the value is already in URI form, otherwise add a sip: prefix. */ if (strchr(bvals[0].bv_val, ':')) call_addresses[attributes[i]] = std::string (bvals[0].bv_val, bvals[0].bv_len); else call_addresses[attributes[i]] = std::string ("sip:") + std::string (bvals[0].bv_val, bvals[0].bv_len); } } } if (bvals) ber_memfree(bvals); } ber_free (ber, 0); if (!username.empty () && !call_addresses.empty()) { result = OPENLDAP::Contact::create (core, fix_to_utf8 (username), call_addresses); } return result; }
static int _mu_entry_to_auth_data (LDAP *ld, LDAPMessage *msg, struct mu_auth_data **return_data) { int rc; BerElement *ber = NULL; struct berval bv; char *ufn = NULL; struct mu_auth_data d; mu_iterator_t itr = NULL; memset (&d, 0, sizeof d); rc = ldap_get_dn_ber (ld, msg, &ber, &bv); ufn = ldap_dn2ufn (bv.bv_val); /* FIXME: Use debug or diag functions */ mu_error ("INFO: %s", ufn); ldap_memfree (ufn); mu_assoc_get_iterator (ldap_param.field_map, &itr); for (mu_iterator_first (itr); !mu_iterator_is_done (itr); mu_iterator_next (itr)) { char *key; char **pattr; char *attr; struct berval **values; mu_iterator_current_kv (itr, (const void **)&key, (void**) &pattr); attr = *pattr; values = ldap_get_values_len (ld, msg, attr); if (!values || !values[0]) { mu_error ("LDAP field `%s' (`%s') has NULL value", key, *pattr); _free_partial_auth_data (&d); return MU_ERR_READ; } rc = _assign_partial_auth_data (&d, key, values[0]->bv_val); ldap_value_free_len (values); if (rc) { _free_partial_auth_data (&d); return rc; } } rc = mu_auth_data_alloc (return_data, d.name, d.passwd, d.uid, d.gid, d.gecos, d.dir, d.shell, d.mailbox, 1); if (rc == 0) mu_auth_data_set_quota (*return_data, d.quota); _free_partial_auth_data (&d); return rc; }
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; }
extern "C" std::string getRecipient(void * vh, Source * source) { ldap_handle * h = (ldap_handle *) vh; int msgtype; int code; int rc; struct berval bv; std::string result; if (!h) return ""; for (;;) { if (h->value && h->value->bv_val) { result = std::string(h->value->bv_val, h->value->bv_len); h->value++; if (result.length() > 5 && !strncasecmp(result.c_str(), "smtp:", 5)) result = result.substr(5); if (result.find_first_not_of(mailchars) != std::string::npos) continue; return result; } if (h->ber) { rc = ldap_get_attribute_ber(h->ldap, h->msg, h->ber, &bv, &h->values); h->value = h->values; if (rc == LDAP_SUCCESS && bv.bv_val) continue; } h->release_message(); rc = ldap_result(h->ldap, LDAP_RES_ANY, LDAP_MSG_ONE, NULL, &h->msg); if (!h->msg) throw ldap_error(rc); msgtype = ldap_msgtype(h->msg); switch (msgtype) { case LDAP_RES_SEARCH_RESULT: rc = ldap_parse_result(h->ldap, h->msg, &code, NULL, NULL, NULL, NULL, 0); if (rc != LDAP_SUCCESS) throw ldap_error(rc); if (code != LDAP_SUCCESS) throw ldap_error(code); return ""; case LDAP_RES_SEARCH_ENTRY: break; default: continue; } rc = ldap_get_dn_ber(h->ldap, h->msg, &h->ber, &bv); if (rc != LDAP_SUCCESS) throw ldap_error(rc); } return ""; }
static ssize_t ldap_recv(struct connectdata *conn, int sockindex, char *buf, size_t len, CURLcode *err) { ldapconninfo *li = conn->proto.generic; struct SessionHandle *data = conn->data; ldapreqinfo *lr = data->req.protop; int rc, ret; LDAPMessage *msg = NULL; LDAPMessage *ent; BerElement *ber = NULL; struct timeval tv = {0, 1}; (void)len; (void)buf; (void)sockindex; rc = ldap_result(li->ld, lr->msgid, LDAP_MSG_RECEIVED, &tv, &msg); if(rc < 0) { failf(data, "LDAP local: search ldap_result %s", ldap_err2string(rc)); *err = CURLE_RECV_ERROR; return -1; } *err = CURLE_AGAIN; ret = -1; /* timed out */ if(!msg) return ret; for(ent = ldap_first_message(li->ld, msg); ent; ent = ldap_next_message(li->ld, ent)) { struct berval bv, *bvals, **bvp = &bvals; int binary = 0, msgtype; msgtype = ldap_msgtype(ent); if(msgtype == LDAP_RES_SEARCH_RESULT) { int code; char *info = NULL; rc = ldap_parse_result(li->ld, ent, &code, NULL, &info, NULL, NULL, 0); if(rc) { failf(data, "LDAP local: search ldap_parse_result %s", ldap_err2string(rc)); *err = CURLE_LDAP_SEARCH_FAILED; } else if(code && code != LDAP_SIZELIMIT_EXCEEDED) { failf(data, "LDAP remote: search failed %s %s", ldap_err2string(rc), info ? info : ""); *err = CURLE_LDAP_SEARCH_FAILED; } else { /* successful */ if(code == LDAP_SIZELIMIT_EXCEEDED) infof(data, "There are more than %d entries\n", lr->nument); data->req.size = data->req.bytecount; *err = CURLE_OK; ret = 0; } lr->msgid = 0; ldap_memfree(info); break; } else if(msgtype != LDAP_RES_SEARCH_ENTRY) continue; lr->nument++; rc = ldap_get_dn_ber(li->ld, ent, &ber, &bv); if(rc < 0) { /* TODO: verify that this is really how this return code should be handled */ *err = CURLE_RECV_ERROR; return -1; } *err = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"DN: ", 4); if(*err) return -1; *err = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)bv.bv_val, bv.bv_len); if(*err) return -1; *err = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"\n", 1); if(*err) return -1; data->req.bytecount += bv.bv_len + 5; for(rc = ldap_get_attribute_ber(li->ld, ent, ber, &bv, bvp); rc == LDAP_SUCCESS; rc = ldap_get_attribute_ber(li->ld, ent, ber, &bv, bvp)) { int i; if(bv.bv_val == NULL) break; if(bv.bv_len > 7 && !strncmp(bv.bv_val + bv.bv_len - 7, ";binary", 7)) binary = 1; else binary = 0; for(i=0; bvals[i].bv_val != NULL; i++) { int binval = 0; *err = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"\t", 1); if(*err) return -1; *err = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)bv.bv_val, bv.bv_len); if(*err) return -1; *err = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)":", 1); if(*err) return -1; data->req.bytecount += bv.bv_len + 2; if(!binary) { /* check for leading or trailing whitespace */ if(ISSPACE(bvals[i].bv_val[0]) || ISSPACE(bvals[i].bv_val[bvals[i].bv_len-1])) binval = 1; else { /* check for unprintable characters */ unsigned int j; for(j=0; j<bvals[i].bv_len; j++) if(!ISPRINT(bvals[i].bv_val[j])) { binval = 1; break; } } } if(binary || binval) { char *val_b64 = NULL; size_t val_b64_sz = 0; /* Binary value, encode to base64. */ CURLcode error = Curl_base64_encode(data, bvals[i].bv_val, bvals[i].bv_len, &val_b64, &val_b64_sz); if(error) { ber_memfree(bvals); ber_free(ber, 0); ldap_msgfree(msg); *err = error; return -1; } *err = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)": ", 2); if(*err) return -1; data->req.bytecount += 2; if(val_b64_sz > 0) { *err = Curl_client_write(conn, CLIENTWRITE_BODY, val_b64, val_b64_sz); if(*err) return -1; free(val_b64); data->req.bytecount += val_b64_sz; } } else { *err = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)" ", 1); if(*err) return -1; *err = Curl_client_write(conn, CLIENTWRITE_BODY, bvals[i].bv_val, bvals[i].bv_len); if(*err) return -1; data->req.bytecount += bvals[i].bv_len + 1; } *err = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"\n", 0); if(*err) return -1; data->req.bytecount++; } ber_memfree(bvals); *err = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"\n", 0); if(*err) return -1; data->req.bytecount++; } *err = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"\n", 0); if(*err) return -1; data->req.bytecount++; ber_free(ber, 0); } ldap_msgfree(msg); return ret; }
static void * my_task( void *my_num ) { LDAP *ld = NULL, *sld = NULL; ber_int_t msgid; LDAPMessage *res, *msg; char *attrs[] = { "1.1", NULL }; int rc = LDAP_SUCCESS; int tid = *(int *)my_num; ldap_initialize( &ld, uri ); if ( ld == NULL ) { perror( "ldap_initialize" ); return NULL; } { int version = LDAP_VERSION3; (void) ldap_set_option( ld, LDAP_OPT_PROTOCOL_VERSION, &version ); } (void) ldap_set_option( ld, LDAP_OPT_REFERRALS, LDAP_OPT_OFF ); ldap_initialize( &sld, uri ); if ( sld == NULL ) { perror( "ldap_initialize" ); return NULL; } { int version = LDAP_VERSION3; (void) ldap_set_option( sld, LDAP_OPT_PROTOCOL_VERSION, &version ); } (void) ldap_set_option( sld, LDAP_OPT_REFERRALS, LDAP_OPT_OFF ); if ( binder ) { rc = ldap_bind_s( sld, binder, pass, LDAP_AUTH_SIMPLE ); if ( rc != LDAP_SUCCESS ) { ldap_perror( sld, "ldap_bind" ); } } r1binds[tid] = 0; for (;;) { char dn[BUFSIZ], *ptr, fstr[256]; int j, isr1; if ( finish ) break; j = rand() % 100; if ( j < r1per ) { j = rand() % r1hi; isr1 = 1; } else { j = rand() % (r2hi - r2lo + 1 ); j += r2lo; isr1 = 0; } sprintf(fstr, filter, j); rc = ldap_search_ext( sld, base, LDAP_SCOPE_SUB, fstr, attrs, 0, NULL, NULL, 0, 0, &msgid ); if ( rc != LDAP_SUCCESS ) { ldap_perror( sld, "ldap_search_ex" ); return NULL; } while (( rc=ldap_result( sld, LDAP_RES_ANY, LDAP_MSG_ONE, NULL, &res )) >0){ BerElement *ber; struct berval bv; char *ptr; int done = 0; for (msg = ldap_first_message( sld, res ); msg; msg = ldap_next_message( sld, msg )) { switch ( ldap_msgtype( msg )) { case LDAP_RES_SEARCH_ENTRY: rc = ldap_get_dn_ber( sld, msg, &ber, &bv ); strcpy(dn, bv.bv_val ); ber_free( ber, 0 ); break; case LDAP_RES_SEARCH_RESULT: done = 1; break; } if ( done ) break; } ldap_msgfree( res ); if ( done ) break; } rc = ldap_bind_s( ld, dn, pass, LDAP_AUTH_SIMPLE ); if ( rc != LDAP_SUCCESS ) { ldap_perror( ld, "ldap_bind" ); } if ( isr1 ) r1binds[tid]++; else r2binds[tid]++; } ldap_unbind( sld ); ldap_unbind( ld ); return NULL; }