int main( int argc, char **argv ) { LDAP *ld; LDAPMessage *result, *e; BerElement *ber; char *a, *dn; char **vals; int i; /* Initialize the client */ if ( ldapssl_client_init( MY_CERTDB_PATH, NULL ) < 0 ) { perror( "ldapssl_client_init" ); return( 1 ); } /* set the max I/O timeout option to 10 seconds */ if ( prldap_set_session_option( NULL, NULL, PRLDAP_OPT_IO_MAX_TIMEOUT, 10000 /* 10 secs */ ) != LDAP_SUCCESS ) { ldap_perror( NULL, "prldap_set_session_option PRLDAP_OPT_IO_MAX_TIMEOUT" ); exit( 1 ); } /* get a handle to an LDAP connection */ if ( (ld = ldapssl_init( MY_HOST, MY_SSL_PORT, 1 )) == NULL ) { perror( "ldapssl_init" ); return( 1 ); } /* use LDAPv3 */ i = LDAP_VERSION3; if ( ldap_set_option( ld, LDAP_OPT_PROTOCOL_VERSION, &i ) < 0 ) { ldap_perror( ld, "ldap_set_option LDAPv3" ); ldap_unbind( ld ); return( 1 ); } /* search for all entries with surname of Jensen */ if ( ldap_search_s( ld, PEOPLE_BASE, LDAP_SCOPE_SUBTREE, "(sn=jensen)", NULL, 0, &result ) != LDAP_SUCCESS ) { ldap_perror( ld, "ldap_search_s" ); if ( result == NULL ) { 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 ( (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 ); ldap_unbind( ld ); return( 0 ); }
/* * Converts an LDAP message into a Python structure. * * On success, returns a list of dictionaries. * On failure, returns NULL, and sets an error. * * The message m is always freed, regardless of return value. */ PyObject * LDAPmessage_to_python(LDAP *ld, LDAPMessage *m) { /* we convert an LDAP message into a python structure. * It is always a list of dictionaries. * We always free m. */ PyObject* result; LDAPMessage* entry; result = PyList_New(0); if (result == NULL) { ldap_msgfree( m ); return NULL; } for(entry = ldap_first_entry(ld,m); entry != NULL; entry = ldap_next_entry(ld,entry)) { char *dn; char *attr; BerElement *ber = NULL; PyObject* entrytuple; PyObject* attrdict; dn = ldap_get_dn( ld, entry ); if (dn == NULL) { Py_DECREF(result); ldap_msgfree( m ); return LDAPerror( ld, "ldap_get_dn" ); } attrdict = PyDict_New(); if (attrdict == NULL) { Py_DECREF(result); ldap_msgfree( m ); ldap_memfree(dn); return NULL; } /* Fill attrdict with lists */ for( attr = ldap_first_attribute( ld, entry, &ber ); attr != NULL; attr = ldap_next_attribute( ld, entry, ber ) ) { PyObject* valuelist; struct berval ** bvals = ldap_get_values_len( ld, entry, attr ); /* Find which list to append to */ if ( PyMapping_HasKeyString( attrdict, attr ) ) { valuelist = PyMapping_GetItemString( attrdict, attr ); } else { valuelist = PyList_New(0); if (valuelist != NULL && PyMapping_SetItemString(attrdict, attr, valuelist) == -1) { Py_DECREF(valuelist); valuelist = NULL; /* catch error later */ } } if (valuelist == NULL) { Py_DECREF(attrdict); Py_DECREF(result); if (ber != NULL) ber_free(ber, 0); ldap_msgfree( m ); ldap_memfree(attr); ldap_memfree(dn); return NULL; } if (bvals != NULL) { Py_ssize_t i; for (i=0; bvals[i]; i++) { PyObject *valuestr; valuestr = LDAPberval_to_object(bvals[i]); if (PyList_Append( valuelist, valuestr ) == -1) { Py_DECREF(attrdict); Py_DECREF(result); Py_DECREF(valuestr); Py_DECREF(valuelist); if (ber != NULL) ber_free(ber, 0); ldap_msgfree( m ); ldap_memfree(attr); ldap_memfree(dn); return NULL; } Py_DECREF(valuestr); } ldap_value_free_len(bvals); } Py_DECREF( valuelist ); ldap_memfree(attr); } entrytuple = Py_BuildValue("(sO)", dn, attrdict); ldap_memfree(dn); Py_DECREF(attrdict); PyList_Append(result, entrytuple); Py_DECREF(entrytuple); if (ber != NULL) ber_free(ber, 0); } for(entry = ldap_first_reference(ld,m); entry != NULL; entry = ldap_next_reference(ld,entry)) { char **refs = NULL; PyObject* entrytuple; PyObject* reflist = PyList_New(0); if (reflist == NULL) { Py_DECREF(result); ldap_msgfree( m ); return NULL; } if (ldap_parse_reference(ld, entry, &refs, NULL, 0) != LDAP_SUCCESS) { Py_DECREF(result); ldap_msgfree( m ); return LDAPerror( ld, "ldap_parse_reference" ); } if (refs) { Py_ssize_t i; for (i=0; refs[i] != NULL; i++) { PyObject *refstr = PyString_FromString(refs[i]); PyList_Append(reflist, refstr); Py_DECREF(refstr); } ber_memvfree( (void **) refs ); } entrytuple = Py_BuildValue("(sO)", NULL, reflist); Py_DECREF(reflist); PyList_Append(result, entrytuple); Py_DECREF(entrytuple); } ldap_msgfree( m ); return result; }
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 ); }
/* * handle the LDAP_RES_SEARCH_RESULT response */ static int ldap_sync_search_result( ldap_sync_t *ls, LDAPMessage *res ) { int err; char *matched = NULL, *msg = NULL; LDAPControl **ctrls = NULL; int rc; int refreshDeletes = -1; #ifdef LDAP_SYNC_TRACE fprintf( stderr, "\tgot LDAP_RES_SEARCH_RESULT\n" ); #endif /* LDAP_SYNC_TRACE */ assert( ls != NULL ); assert( res != NULL ); /* should not happen in refreshAndPersist... */ rc = ldap_parse_result( ls->ls_ld, res, &err, &matched, &msg, NULL, &ctrls, 0 ); #ifdef LDAP_SYNC_TRACE fprintf( stderr, "\tldap_parse_result(%d, \"%s\", \"%s\") == %d\n", err, matched ? matched : "", msg ? msg : "", rc ); #endif /* LDAP_SYNC_TRACE */ if ( rc == LDAP_SUCCESS ) { rc = err; } ls->ls_refreshPhase = LDAP_SYNC_CAPI_DONE; switch ( rc ) { case LDAP_SUCCESS: { int i; BerElement *ber = NULL; ber_len_t len; struct berval cookie = { 0 }; rc = LDAP_OTHER; /* deal with control; then fallthru to handler */ if ( ctrls == NULL ) { goto done; } /* lookup the sync state control */ for ( i = 0; ctrls[ i ] != NULL; i++ ) { if ( strcmp( ctrls[ i ]->ldctl_oid, LDAP_CONTROL_SYNC_DONE ) == 0 ) { break; } } /* control must be present; there might be other... */ if ( ctrls[ i ] == NULL ) { goto done; } /* extract data */ ber = ber_init( &ctrls[ i ]->ldctl_value ); if ( ber == NULL ) { goto done; } if ( ber_scanf( ber, "{" /*"}"*/) == LBER_ERROR ) { goto ber_done; } if ( ber_peek_tag( ber, &len ) == LDAP_TAG_SYNC_COOKIE ) { if ( ber_scanf( ber, "m", &cookie ) == LBER_ERROR ) { goto ber_done; } if ( cookie.bv_val != NULL ) { ber_bvreplace( &ls->ls_cookie, &cookie ); } #ifdef LDAP_SYNC_TRACE fprintf( stderr, "\t\tgot cookie=%s\n", cookie.bv_val ? cookie.bv_val : "(null)" ); #endif /* LDAP_SYNC_TRACE */ } refreshDeletes = 0; if ( ber_peek_tag( ber, &len ) == LDAP_TAG_REFRESHDELETES ) { if ( ber_scanf( ber, "b", &refreshDeletes ) == LBER_ERROR ) { goto ber_done; } if ( refreshDeletes ) { refreshDeletes = 1; } } if ( ber_scanf( ber, /*"{"*/ "}" ) != LBER_ERROR ) { rc = LDAP_SUCCESS; } ber_done:; ber_free( ber, 1 ); if ( rc != LDAP_SUCCESS ) { break; } #ifdef LDAP_SYNC_TRACE fprintf( stderr, "\t\tgot refreshDeletes=%s\n", refreshDeletes ? "TRUE" : "FALSE" ); #endif /* LDAP_SYNC_TRACE */ /* FIXME: what should we do with the refreshDelete? */ switch ( refreshDeletes ) { case 0: ls->ls_refreshPhase = LDAP_SYNC_CAPI_PRESENTS; break; default: ls->ls_refreshPhase = LDAP_SYNC_CAPI_DELETES; break; } } /* fallthru */ case LDAP_SYNC_REFRESH_REQUIRED: /* TODO: check for Sync Done Control */ /* FIXME: perhaps the handler should be called * also in case of failure; we'll deal with this * later when implementing refreshOnly */ if ( ls->ls_search_result ) { err = ls->ls_search_result( ls, res, refreshDeletes ); } break; } done:; if ( matched != NULL ) { ldap_memfree( matched ); } if ( msg != NULL ) { ldap_memfree( msg ); } if ( ctrls != NULL ) { ldap_controls_free( ctrls ); } ls->ls_refreshPhase = LDAP_SYNC_CAPI_DONE; return rc; }
int asyncmeta_handle_common_result(LDAPMessage *msg, a_metaconn_t *mc, bm_context_t *bc, int candidate) { a_metainfo_t *mi; a_metatarget_t *mt; a_metasingleconn_t *msc; const char *save_text = NULL, *save_matched = NULL; BerVarray save_ref = NULL; LDAPControl **save_ctrls = NULL; void *matched_ctx = NULL; char *matched = NULL; char *text = NULL; char **refs = NULL; LDAPControl **ctrls = NULL; Operation *op; SlapReply *rs; int rc; mi = mc->mc_info; mt = mi->mi_targets[ candidate ]; msc = &mc->mc_conns[ candidate ]; op = bc->op; rs = &bc->rs; save_text = rs->sr_text, save_matched = rs->sr_matched; save_ref = rs->sr_ref; save_ctrls = rs->sr_ctrls; rs->sr_text = NULL; rs->sr_matched = NULL; rs->sr_ref = NULL; rs->sr_ctrls = NULL; /* only touch when activity actually took place... */ if ( mi->mi_idle_timeout != 0 ) { asyncmeta_set_msc_time(msc); } rc = ldap_parse_result( msc->msc_ldr, msg, &rs->sr_err, &matched, &text, &refs, &ctrls, 0 ); if ( rc == LDAP_SUCCESS ) { rs->sr_text = text; } else { rs->sr_err = rc; } rs->sr_err = slap_map_api2result( rs ); /* RFC 4511: referrals can only appear * if result code is LDAP_REFERRAL */ if ( refs != NULL && refs[ 0 ] != NULL && refs[ 0 ][ 0 ] != '\0' ) { if ( rs->sr_err != LDAP_REFERRAL ) { Debug( LDAP_DEBUG_ANY, "%s asyncmeta_handle_common_result[%d]: " "got referrals with err=%d\n", op->o_log_prefix, candidate, rs->sr_err ); } else { int i; for ( i = 0; refs[ i ] != NULL; i++ ) /* count */ ; rs->sr_ref = op->o_tmpalloc( sizeof( struct berval ) * ( i + 1 ), op->o_tmpmemctx ); for ( i = 0; refs[ i ] != NULL; i++ ) { ber_str2bv( refs[ i ], 0, 0, &rs->sr_ref[ i ] ); } BER_BVZERO( &rs->sr_ref[ i ] ); } } else if ( rs->sr_err == LDAP_REFERRAL ) { Debug( LDAP_DEBUG_ANY, "%s asyncmeta_handle_common_result[%d]: " "got err=%d with null " "or empty referrals\n", op->o_log_prefix, candidate, rs->sr_err ); rs->sr_err = LDAP_NO_SUCH_OBJECT; } if ( ctrls != NULL ) { rs->sr_ctrls = ctrls; } /* if the error in the reply structure is not * LDAP_SUCCESS, try to map it from client * to server error */ if ( !LDAP_ERR_OK( rs->sr_err ) ) { rs->sr_err = slap_map_api2result( rs ); /* internal ops ( op->o_conn == NULL ) * must not reply to client */ if ( op->o_conn && !op->o_do_not_cache && matched ) { /* record the (massaged) matched * DN into the reply structure */ rs->sr_matched = matched; } } if ( META_BACK_TGT_QUARANTINE( mt ) ) { asyncmeta_quarantine( op, mi, rs, candidate ); } if ( matched != NULL ) { struct berval dn, pdn; ber_str2bv( matched, 0, 0, &dn ); if ( dnPretty( NULL, &dn, &pdn, op->o_tmpmemctx ) == LDAP_SUCCESS ) { ldap_memfree( matched ); matched_ctx = op->o_tmpmemctx; matched = pdn.bv_val; } rs->sr_matched = matched; } if ( rs->sr_err == LDAP_UNAVAILABLE || rs->sr_err == LDAP_SERVER_DOWN ) { if ( rs->sr_text == NULL ) { rs->sr_text = "Target is unavailable"; } } ldap_pvt_thread_mutex_lock( &mc->mc_om_mutex ); asyncmeta_drop_bc( mc, bc); ldap_pvt_thread_mutex_unlock( &mc->mc_om_mutex ); if ( op->o_conn ) { asyncmeta_send_ldap_result(bc, op, rs); } if ( matched ) { op->o_tmpfree( (char *)rs->sr_matched, matched_ctx ); } if ( text ) { ldap_memfree( text ); } if ( rs->sr_ref ) { op->o_tmpfree( rs->sr_ref, op->o_tmpmemctx ); rs->sr_ref = NULL; } if ( refs ) { ber_memvfree( (void **)refs ); } if ( ctrls ) { assert( rs->sr_ctrls != NULL ); ldap_controls_free( ctrls ); } rs->sr_text = save_text; rs->sr_matched = save_matched; rs->sr_ref = save_ref; rs->sr_ctrls = save_ctrls; rc = (LDAP_ERR_OK( rs->sr_err ) ? LDAP_SUCCESS : rs->sr_err); ldap_pvt_thread_mutex_lock( &mc->mc_om_mutex ); asyncmeta_clear_bm_context(bc); ldap_pvt_thread_mutex_unlock( &mc->mc_om_mutex ); return rc; }
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; }
/* * 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 GdaLdapEntry * worker_gdaprov_ldap_describe_entry (WorkerLdapDescrEntryData *data, GError **error) { if (! gda_ldap_ensure_bound (data->cnc, error)) return NULL; gda_ldap_execution_slowdown (data->cnc); int res; LDAPMessage *msg = NULL; const gchar *real_dn; real_dn = data->dn ? data->dn : data->cdata->base_dn; retry: res = ldap_search_ext_s (data->cdata->handle, real_dn, LDAP_SCOPE_BASE, "(objectClass=*)", NULL, 0, NULL, NULL, NULL, -1, &msg); switch (res) { case LDAP_SUCCESS: case LDAP_NO_SUCH_OBJECT: { gint nb_entries; LDAPMessage *ldap_row; char *attr; BerElement* ber; GdaLdapEntry *lentry; GArray *array = NULL; nb_entries = ldap_count_entries (data->cdata->handle, msg); if (nb_entries == 0) { ldap_msgfree (msg); gda_ldap_may_unbind (data->cnc); return NULL; } else if (nb_entries > 1) { g_set_error (error, GDA_SERVER_PROVIDER_ERROR, GDA_SERVER_PROVIDER_INTERNAL_ERROR, _("LDAP server returned more than one entry with DN '%s'"), real_dn); gda_ldap_may_unbind (data->cnc); return NULL; } lentry = g_new0 (GdaLdapEntry, 1); lentry->dn = g_strdup (real_dn); lentry->attributes_hash = g_hash_table_new (g_str_hash, g_str_equal); array = g_array_new (TRUE, FALSE, sizeof (GdaLdapAttribute*)); ldap_row = ldap_first_entry (data->cdata->handle, msg); for (attr = ldap_first_attribute (data->cdata->handle, ldap_row, &ber); attr; attr = ldap_next_attribute (data->cdata->handle, ldap_row, ber)) { BerValue **bvals; GArray *varray = NULL; bvals = ldap_get_values_len (data->cdata->handle, ldap_row, attr); if (bvals) { gint i; for (i = 0; bvals [i]; i++) { if (!varray) varray = g_array_new (TRUE, FALSE, sizeof (GValue *)); GValue *value; GType type; type = gda_ldap_get_g_type (data->cnc, data->cdata, attr, NULL); /*g_print ("Type for attr %s is %s\n", attr, gda_g_type_to_string (type)); */ value = gda_ldap_attr_value_to_g_value (data->cdata, type, bvals[i]); g_array_append_val (varray, value); } ldap_value_free_len (bvals); } if (varray) { GdaLdapAttribute *lattr = NULL; lattr = g_new0 (GdaLdapAttribute, 1); lattr->attr_name = g_strdup (attr); lattr->values = (GValue**) varray->data; lattr->nb_values = varray->len; g_array_free (varray, FALSE); g_array_append_val (array, lattr); g_hash_table_insert (lentry->attributes_hash, lattr->attr_name, lattr); } ldap_memfree (attr); } if (ber) ber_free (ber, 0); ldap_msgfree (msg); if (array) { g_array_sort (array, (GCompareFunc) attr_array_sort_func); lentry->attributes = (GdaLdapAttribute**) array->data; lentry->nb_attributes = array->len; g_array_free (array, FALSE); } gda_ldap_may_unbind (data->cnc); return lentry; } case LDAP_SERVER_DOWN: default: { if (res == LDAP_SERVER_DOWN) { gint i; for (i = 0; i < 5; i++) { if (gda_ldap_rebind (data->cnc, NULL)) goto retry; g_usleep (G_USEC_PER_SEC * 2); } } /* error */ int ldap_errno; ldap_get_option (data->cdata->handle, LDAP_OPT_ERROR_NUMBER, &ldap_errno); g_set_error (error, GDA_DATA_MODEL_ERROR, GDA_DATA_MODEL_OTHER_ERROR, "%s", ldap_err2string(ldap_errno)); gda_ldap_may_unbind (data->cnc); return NULL; } } }
static LdapAttribute * worker_gda_ldap_get_attr_info (WorkerLdapAttrInfoData *data, GError **error) { LdapAttribute *retval = NULL; if (data->cdata->attributes_hash) return g_hash_table_lookup (data->cdata->attributes_hash, data->attribute); /* initialize known types */ data->cdata->attributes_hash = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, (GDestroyNotify) ldap_attribute_free); if (data->cdata->attributes_cache_file) { /* try to load from cache file, which must contain one line per attribute: * <syntax oid>,0|1,<attribute name> */ gchar *fdata; if (g_file_get_contents (data->cdata->attributes_cache_file, &fdata, NULL, NULL)) { gchar *start, *ptr; gchar **array; start = fdata; while (1) { gboolean done = FALSE; for (ptr = start; *ptr && (*ptr != '\n'); ptr++); if (*ptr == '\n') *ptr = 0; else done = TRUE; if (*start && (*start != '#')) { array = g_strsplit (start, ",", 3); if (array[0] && array[1] && array[2]) { LdapAttribute *lat; lat = g_new (LdapAttribute, 1); lat->name = g_strdup (array[2]); lat->type = gda_ldap_get_type_info (array[0]); lat->single_value = (*array[1] == '0' ? FALSE : TRUE); g_hash_table_insert (data->cdata->attributes_hash, lat->name, lat); /*g_print ("CACHE ADDED [%s][%p][%d] for OID %s\n", lat->name, lat->type, lat->single_value, array[0]);*/ } g_strfreev (array); } if (done) break; else start = ptr+1; } g_free (fdata); return g_hash_table_lookup (data->cdata->attributes_hash, data->attribute); } } GString *string = NULL; LDAPMessage *msg, *entry; int res; gchar *subschema = NULL; char *subschemasubentry[] = {"subschemaSubentry", NULL}; char *schema_attrs[] = {"attributeTypes", NULL}; /* look for subschema */ if (! gda_ldap_ensure_bound (data->cnc, NULL)) return NULL; gda_ldap_execution_slowdown (data->cnc); res = ldap_search_ext_s (data->cdata->handle, "", LDAP_SCOPE_BASE, "(objectclass=*)", subschemasubentry, 0, NULL, NULL, NULL, 0, &msg); if (res != LDAP_SUCCESS) { gda_ldap_may_unbind (data->cnc); return NULL; } if ((entry = ldap_first_entry (data->cdata->handle, msg))) { char *attr; BerElement *ber; if ((attr = ldap_first_attribute (data->cdata->handle, entry, &ber))) { BerValue **bvals; if ((bvals = ldap_get_values_len (data->cdata->handle, entry, attr))) { subschema = g_strdup (bvals[0]->bv_val); ldap_value_free_len (bvals); } ldap_memfree (attr); } if (ber) ber_free (ber, 0); } ldap_msgfree (msg); if (! subschema) { gda_ldap_may_unbind (data->cnc); return NULL; } /* look for attributeTypes */ gda_ldap_execution_slowdown (data->cnc); res = ldap_search_ext_s (data->cdata->handle, subschema, LDAP_SCOPE_BASE, "(objectclass=*)", schema_attrs, 0, NULL, NULL, NULL, 0, &msg); g_free (subschema); if (res != LDAP_SUCCESS) { gda_ldap_may_unbind (data->cnc); return NULL; } if (data->cdata->attributes_cache_file) string = g_string_new ("# Cache file. This file can safely be removed, in this case\n" "# it will be automatically recreated.\n" "# DO NOT MODIFY\n"); for (entry = ldap_first_entry (data->cdata->handle, msg); entry; entry = ldap_next_entry (data->cdata->handle, msg)) { char *attr; BerElement *ber; for (attr = ldap_first_attribute (data->cdata->handle, msg, &ber); attr; attr = ldap_next_attribute (data->cdata->handle, msg, ber)) { if (strcasecmp(attr, "attributeTypes")) { ldap_memfree (attr); continue; } BerValue **bvals; bvals = ldap_get_values_len (data->cdata->handle, entry, attr); if (bvals) { gint i; for (i = 0; bvals[i]; i++) { LDAPAttributeType *at; const char *errp; int retcode; at = ldap_str2attributetype (bvals[i]->bv_val, &retcode, &errp, LDAP_SCHEMA_ALLOW_ALL); if (at && at->at_names && at->at_syntax_oid && at->at_names[0] && *(at->at_names[0])) { LdapAttribute *lat; lat = g_new (LdapAttribute, 1); lat->name = g_strdup (at->at_names [0]); lat->type = gda_ldap_get_type_info (at->at_syntax_oid); lat->single_value = (at->at_single_value == 0 ? FALSE : TRUE); g_hash_table_insert (data->cdata->attributes_hash, lat->name, lat); /*g_print ("ADDED [%s][%p][%d] for OID %s\n", lat->name, lat->type, lat->single_value, at->at_syntax_oid);*/ if (string) g_string_append_printf (string, "%s,%d,%s\n", at->at_syntax_oid, lat->single_value, lat->name); } if (at) ldap_memfree (at); } ldap_value_free_len (bvals); } ldap_memfree (attr); } if (ber) ber_free (ber, 0); } ldap_msgfree (msg); if (string) { if (! g_file_set_contents (data->cdata->attributes_cache_file, string->str, -1, NULL)) { gchar *dirname; dirname = g_path_get_dirname (data->cdata->attributes_cache_file); g_mkdir_with_parents (dirname, 0700); g_free (dirname); g_file_set_contents (data->cdata->attributes_cache_file, string->str, -1, NULL); } g_string_free (string, TRUE); } gda_ldap_may_unbind (data->cnc); retval = g_hash_table_lookup (data->cdata->attributes_hash, data->attribute); return retval; }
/** Convert group membership information into attributes * * @param[in] inst rlm_ldap configuration. * @param[in] request Current request. * @param[in,out] pconn to use. May change as this function calls functions which auto re-connect. * @return One of the RLM_MODULE_* values. */ rlm_rcode_t rlm_ldap_cacheable_groupobj(ldap_instance_t const *inst, REQUEST *request, ldap_handle_t **pconn) { rlm_rcode_t rcode = RLM_MODULE_OK; ldap_rcode_t status; int ldap_errno; char **vals; LDAPMessage *result = NULL; LDAPMessage *entry; char base_dn[LDAP_MAX_DN_STR_LEN]; char const *filters[] = { inst->groupobj_filter, inst->groupobj_membership_filter }; char filter[LDAP_MAX_FILTER_STR_LEN + 1]; char const *attrs[] = { inst->groupobj_name_attr, NULL }; char *dn; rad_assert(inst->groupobj_base_dn); if (!inst->groupobj_membership_filter) { RDEBUG2("Skipping caching group objects as directive 'group.membership_filter' is not set"); return RLM_MODULE_OK; } if (rlm_ldap_xlat_filter(request, filters, sizeof(filters) / sizeof(*filters), filter, sizeof(filter)) < 0) { return RLM_MODULE_INVALID; } if (radius_xlat(base_dn, sizeof(base_dn), request, inst->groupobj_base_dn, rlm_ldap_escape_func, NULL) < 0) { REDEBUG("Failed creating base_dn"); return RLM_MODULE_INVALID; } status = rlm_ldap_search(inst, request, pconn, base_dn, inst->groupobj_scope, filter, attrs, &result); switch (status) { case LDAP_PROC_SUCCESS: break; case LDAP_PROC_NO_RESULT: RDEBUG2("No cacheable group memberships found in group objects"); default: goto finish; } entry = ldap_first_entry((*pconn)->handle, result); if (!entry) { ldap_get_option((*pconn)->handle, LDAP_OPT_RESULT_CODE, &ldap_errno); REDEBUG("Failed retrieving entry: %s", ldap_err2string(ldap_errno)); goto finish; } do { if (inst->cacheable_group_dn) { dn = ldap_get_dn((*pconn)->handle, entry); pairmake(request, &request->config_items, inst->cache_da->name, dn, T_OP_ADD); RDEBUG("Added %s with value \"%s\" to control list", inst->cache_da->name, dn); ldap_memfree(dn); } if (inst->cacheable_group_name) { vals = ldap_get_values((*pconn)->handle, entry, inst->groupobj_name_attr); if (!vals) { continue; } pairmake(request, &request->config_items, inst->cache_da->name, *vals, T_OP_ADD); RDEBUG("Added %s with value \"%s\" to control list", inst->cache_da->name, *vals); ldap_value_free(vals); } } while((entry = ldap_next_entry((*pconn)->handle, entry))); finish: if (result) { ldap_msgfree(result); } return rcode; }
/** Convert multiple group names into a DNs * * Given an array of group names, builds a filter matching all names, then retrieves all group objects * and stores the DN associated with each group object. * * @param[in] inst rlm_ldap configuration. * @param[in] request Current request. * @param[in,out] pconn to use. May change as this function calls functions which auto re-connect. * @param[in] names to covert to DNs (NULL terminated). * @param[out] out Where to write the DNs. DNs must be freed with ldap_memfree(). Will be NULL terminated. * @param[in] outlen Size of out. * @return One of the RLM_MODULE_* values. */ static rlm_rcode_t rlm_ldap_group_name2dn(ldap_instance_t const *inst, REQUEST *request, ldap_handle_t **pconn, char **names, char **out, size_t outlen) { rlm_rcode_t rcode = RLM_MODULE_OK; ldap_rcode_t status; int ldap_errno; unsigned int name_cnt = 0; unsigned int entry_cnt; char const *attrs[] = { NULL }; LDAPMessage *result = NULL, *entry; char **name = names; char **dn = out; char buffer[LDAP_MAX_GROUP_NAME_LEN + 1]; char *filter; *dn = NULL; if (!*names) { return RLM_MODULE_OK; } if (!inst->groupobj_name_attr) { REDEBUG("Told to convert group names to DNs but missing 'group.name_attribute' directive"); return RLM_MODULE_INVALID; } RDEBUG("Converting group name(s) to group DN(s)"); /* * It'll probably only save a few ms in network latency, but it means we can send a query * for the entire group list at once. */ filter = talloc_asprintf(request, "%s%s%s", inst->groupobj_filter ? "(&" : "", inst->groupobj_filter ? inst->groupobj_filter : "", names[0] && names[1] ? "(|" : ""); while (*name) { rlm_ldap_escape_func(request, buffer, sizeof(buffer), *name++, NULL); filter = talloc_asprintf_append_buffer(filter, "(%s=%s)", inst->groupobj_name_attr, buffer); name_cnt++; } filter = talloc_asprintf_append_buffer(filter, "%s%s", inst->groupobj_filter ? ")" : "", names[0] && names[1] ? ")" : ""); status = rlm_ldap_search(inst, request, pconn, inst->groupobj_base_dn, inst->groupobj_scope, filter, attrs, &result); switch (status) { case LDAP_PROC_SUCCESS: break; case LDAP_PROC_NO_RESULT: RDEBUG("Tried to resolve group name(s) to DNs but got no results"); goto finish; default: rcode = RLM_MODULE_FAIL; goto finish; } entry_cnt = ldap_count_entries((*pconn)->handle, result); if (entry_cnt > name_cnt) { REDEBUG("Number of DNs exceeds number of names, group and/or dn should be more restrictive"); rcode = RLM_MODULE_INVALID; goto finish; } if (entry_cnt > (outlen - 1)) { REDEBUG("Number of DNs exceeds limit (%zu)", outlen - 1); rcode = RLM_MODULE_INVALID; goto finish; } if (entry_cnt < name_cnt) { RWDEBUG("Got partial mapping of group names (%i) to DNs (%i), membership information may be incomplete", name_cnt, entry_cnt); } entry = ldap_first_entry((*pconn)->handle, result); if (!entry) { ldap_get_option((*pconn)->handle, LDAP_OPT_RESULT_CODE, &ldap_errno); REDEBUG("Failed retrieving entry: %s", ldap_err2string(ldap_errno)); rcode = RLM_MODULE_FAIL; goto finish; } do { *dn = ldap_get_dn((*pconn)->handle, entry); RDEBUG("Got group DN \"%s\"", *dn); dn++; } while((entry = ldap_next_entry((*pconn)->handle, entry))); *dn = NULL; finish: talloc_free(filter); if (result) { ldap_msgfree(result); } /* * Be nice and cleanup the output array if we error out. */ if (rcode != RLM_MODULE_OK) { dn = out; while(*dn) ldap_memfree(*dn++); *dn = NULL; } return rcode; }
/** Convert group membership information into attributes * * @param[in] inst rlm_ldap configuration. * @param[in] request Current request. * @param[in,out] pconn to use. May change as this function calls functions which auto re-connect. * @param[in] entry retrieved by rlm_ldap_find_user or rlm_ldap_search. * @param[in] attr membership attribute to look for in the entry. * @return One of the RLM_MODULE_* values. */ rlm_rcode_t rlm_ldap_cacheable_userobj(ldap_instance_t const *inst, REQUEST *request, ldap_handle_t **pconn, LDAPMessage *entry, char const *attr) { rlm_rcode_t rcode = RLM_MODULE_OK; char **vals; char *group_name[LDAP_MAX_CACHEABLE + 1]; char **name_p = group_name; char *group_dn[LDAP_MAX_CACHEABLE + 1]; char **dn_p; char *name; int is_dn, i; rad_assert(entry); rad_assert(attr); /* * Parse the membership information we got in the initial user query. */ vals = ldap_get_values((*pconn)->handle, entry, attr); if (!vals) { RDEBUG2("No cacheable group memberships found in user object"); return RLM_MODULE_OK; } for (i = 0; (vals[i] != NULL) && (i < LDAP_MAX_CACHEABLE); i++) { is_dn = rlm_ldap_is_dn(vals[i]); if (inst->cacheable_group_dn) { /* * The easy case, were caching DNs and we got a DN. */ if (is_dn) { pairmake(request, &request->config_items, inst->cache_da->name, vals[i], T_OP_ADD); RDEBUG("Added %s with value \"%s\" to control list", inst->cache_da->name, vals[i]); /* * We were told to cache DNs but we got a name, we now need to resolve * this to a DN. Store all the group names in an array so we can do one query. */ } else { *name_p++ = vals[i]; } } if (inst->cacheable_group_name) { /* * The easy case, were caching names and we got a name. */ if (!is_dn) { pairmake(request, &request->config_items, inst->cache_da->name, vals[i], T_OP_ADD); RDEBUG("Added %s with value \"%s\" to control list", inst->cache_da->name, vals[i]); /* * We were told to cache names but we got a DN, we now need to resolve * this to a name. * Only Active Directory supports filtering on DN, so we have to search * for each individual group. */ } else { rcode = rlm_ldap_group_dn2name(inst, request, pconn, vals[i], &name); if (rcode != RLM_MODULE_OK) { ldap_value_free(vals); return rcode; } pairmake(request, &request->config_items, inst->cache_da->name, name, T_OP_ADD); RDEBUG("Added %s with value \"%s\" to control list", inst->cache_da->name, name); talloc_free(name); } } } *name_p = NULL; rcode = rlm_ldap_group_name2dn(inst, request, pconn, group_name, group_dn, sizeof(group_dn)); ldap_value_free(vals); if (rcode != RLM_MODULE_OK) { return rcode; } dn_p = group_dn; while(*dn_p) { pairmake(request, &request->config_items, inst->cache_da->name, *dn_p, T_OP_ADD); RDEBUG("Added %s with value \"%s\" to control list", inst->cache_da->name, *dn_p); ldap_memfree(*dn_p); dn_p++; } return rcode; }
OPENLDAP::Book::Book (Ekiga::ServiceCore &_core, boost::shared_ptr<xmlDoc> _doc, xmlNodePtr _node): saslform(NULL), core(_core), doc(_doc), node(_node), name_node(NULL), uri_node(NULL), authcID_node(NULL), password_node(NULL), ldap_context(NULL), patience(0) { xmlChar *xml_str; bool upgrade_config = false; /* for previous config */ std::string hostname="", port="", base="", scope="", call_attribute=""; xmlNodePtr hostname_node = NULL, port_node = NULL, base_node = NULL, scope_node = NULL, call_attribute_node = NULL; bookinfo.name = ""; bookinfo.uri = ""; bookinfo.authcID = ""; bookinfo.password = ""; bookinfo.saslMech = ""; bookinfo.sasl = false; bookinfo.starttls = false; for (xmlNodePtr child = node->children ; child != NULL; child = child->next) { if (child->type == XML_ELEMENT_NODE && child->name != NULL) { if (xmlStrEqual (BAD_CAST ("name"), child->name)) { xml_str = xmlNodeGetContent (child); bookinfo.name = (const char *)xml_str; xmlFree (xml_str); name_node = child; continue; } if (xmlStrEqual (BAD_CAST ("uri"), child->name)) { xml_str = xmlNodeGetContent (child); bookinfo.uri = (const char *)xml_str; xmlFree (xml_str); uri_node = child; continue; } if (xmlStrEqual (BAD_CAST ("hostname"), child->name)) { xml_str = xmlNodeGetContent (child); hostname = (const char *)xml_str; hostname_node = child; xmlFree (xml_str); upgrade_config = true; continue; } if (xmlStrEqual (BAD_CAST ("port"), child->name)) { xml_str = xmlNodeGetContent (child); port = (const char *)xml_str; port_node = child; xmlFree (xml_str); upgrade_config = true; continue; } if (xmlStrEqual (BAD_CAST ("base"), child->name)) { xml_str = xmlNodeGetContent (child); base = (const char *)xml_str; base_node = child; xmlFree (xml_str); upgrade_config = true; continue; } if (xmlStrEqual (BAD_CAST ("scope"), child->name)) { xml_str = xmlNodeGetContent (child); scope = (const char *)xml_str; scope_node = child; xmlFree (xml_str); upgrade_config = true; continue; } if (xmlStrEqual (BAD_CAST ("call_attribute"), child->name)) { xml_str = xmlNodeGetContent (child); call_attribute = (const char *)xml_str; call_attribute_node = child; xmlFree (xml_str); upgrade_config = true; continue; } if (xmlStrEqual (BAD_CAST ("authcID"), child->name)) { xml_str = xmlNodeGetContent (child); bookinfo.authcID = (const char *)xml_str; authcID_node = child; xmlFree (xml_str); continue; } if (xmlStrEqual (BAD_CAST ("password"), child->name)) { xml_str = xmlNodeGetContent (child); bookinfo.password = (const char *)xml_str; password_node = child; xmlFree (xml_str); continue; } } } if (upgrade_config) { if (!uri_node) { LDAPURLDesc *url_tmp = NULL; char *url_str; std::string new_uri; if (hostname.empty()) hostname="localhost"; new_uri = std::string("ldap://") + hostname; if (!port.empty()) new_uri += std::string(":") + port; new_uri += "/?cn," + call_attribute + "?" + scope; ldap_url_parse (new_uri.c_str(), &url_tmp); url_tmp->lud_dn = (char *)base.c_str(); url_str = ldap_url_desc2str (url_tmp); bookinfo.uri = std::string(url_str); ldap_memfree (url_str); robust_xmlNodeSetContent (node, &uri_node, "uri", bookinfo.uri); url_tmp->lud_dn = NULL; ldap_free_urldesc (url_tmp); } if (hostname_node) { xmlUnlinkNode (hostname_node); xmlFreeNode (hostname_node); } if (port_node) { xmlUnlinkNode (port_node); xmlFreeNode (port_node); } if (base_node) { xmlUnlinkNode (base_node); xmlFreeNode (base_node); } if (scope_node) { xmlUnlinkNode (scope_node); xmlFreeNode (scope_node); } if (call_attribute_node) { xmlUnlinkNode (call_attribute_node); xmlFreeNode (call_attribute_node); } trigger_saving (); } OPENLDAP::BookInfoParse (bookinfo); if (bookinfo.uri_host == EKIGA_NET_URI) I_am_an_ekiga_net_book = true; else I_am_an_ekiga_net_book = false; /* Actor stuff */ add_action (Ekiga::ActionPtr (new Ekiga::Action ("edit-book", _("_Edit"), boost::bind (&OPENLDAP::Book::edit, this)))); add_action (Ekiga::ActionPtr (new Ekiga::Action ("remove-book", _("_Remove"), boost::bind (&OPENLDAP::Book::remove, this)))); add_action (Ekiga::ActionPtr (new Ekiga::Action ("refresh-book", _("_Refresh"), boost::bind (&OPENLDAP::Book::refresh, this)))); }
int OPENLDAP::BookFormInfo (Ekiga::Form &result, struct BookInfo &bookinfo, std::string &errmsg) { LDAPURLDesc *url_base = NULL, *url_host = NULL; char *url_str; std::string name = result.text ("name"); std::string uri = result.text ("uri"); std::string nameAttr = result.text ("nameAttr"); std::string callAttr = result.text ("callAttr"); std::string filter = result.text ("filter"); errmsg = ""; if (name.empty()) errmsg += _("Please provide a Book Name for this directory\n"); if (uri.empty()) errmsg += _("Please provide a Server URI\n"); if (nameAttr.empty()) errmsg += _("Please provide a DisplayName attribute\n"); if (callAttr.empty()) errmsg += _("Please provide a Call attribute\n"); if (ldap_url_parse (uri.c_str(), &url_host)) errmsg += _("Invalid Server URI\n"); if (!errmsg.empty()) { return -1; } if (filter.empty()) filter = "(cn=$)"; bookinfo.name = name; std::string base = result.text ("base"); std::string new_bits = "ldap:///?" + result.text ("nameAttr") + "," + result.text ("callAttr") + "?" + result.single_choice ("scope") + "?" + result.text ("filter"); bookinfo.authcID = result.text ("authcID"); bookinfo.password = result.text ("password"); bookinfo.starttls = result.boolean ("startTLS"); bookinfo.sasl = result.boolean ("sasl"); bookinfo.saslMech = result.single_choice ("saslMech"); if (bookinfo.sasl || bookinfo.starttls) { new_bits += "?"; if (bookinfo.starttls) new_bits += "StartTLS"; if (bookinfo.sasl) { if (bookinfo.starttls) new_bits += ","; new_bits += "SASL"; if (!bookinfo.saslMech.empty()) new_bits += "=" + bookinfo.saslMech; } } if (ldap_url_parse (new_bits.c_str(), &url_base)) errmsg += _("Invalid Server URI\n"); if (!errmsg.empty()) { return -1; } url_host->lud_dn = ldap_strdup (base.c_str()); url_host->lud_attrs = url_base->lud_attrs; url_host->lud_scope = url_base->lud_scope; url_host->lud_filter = url_base->lud_filter; if (!url_host->lud_exts) { url_host->lud_exts = url_base->lud_exts; url_base->lud_exts = NULL; } url_base->lud_attrs = NULL; url_base->lud_filter = NULL; ldap_free_urldesc (url_base); bookinfo.urld = boost::shared_ptr<LDAPURLDesc> (url_host, ldap_url_desc_deleter ()); url_str = ldap_url_desc2str (url_host); bookinfo.uri = std::string(url_str); ldap_memfree (url_str); { size_t pos; pos = bookinfo.uri.find ('/', strlen(url_host->lud_scheme) + 3); if (pos != std::string::npos) bookinfo.uri_host = bookinfo.uri.substr (0,pos); else bookinfo.uri_host = bookinfo.uri; } return 0; }
void kuhl_m_sid_displayMessage(PLDAP ld, PLDAPMessage pMessage) { PLDAPMessage pEntry; PWCHAR pAttribute, name, domain; BerElement* pBer = NULL; PBERVAL *pBerVal; DWORD i; SID_NAME_USE nameUse; for(pEntry = ldap_first_entry(ld, pMessage); pEntry; pEntry = ldap_next_entry(ld, pEntry)) { kprintf(L"\n%s\n", ldap_get_dn(ld, pEntry)); for(pAttribute = ldap_first_attribute(ld, pEntry, &pBer); pAttribute; pAttribute = ldap_next_attribute(ld, pEntry, pBer)) { kprintf(L" %s: ", pAttribute); if(pBerVal = ldap_get_values_len(ld, pEntry, pAttribute)) { if( (_wcsicmp(pAttribute, L"name") == 0) || (_wcsicmp(pAttribute, L"sAMAccountName") == 0) ) { kprintf(L"%*S\n", pBerVal[0]->bv_len, pBerVal[0]->bv_val); } else if((_wcsicmp(pAttribute, L"objectSid") == 0)) { kull_m_string_displaySID(pBerVal[0]->bv_val); kprintf(L"\n"); } else if((_wcsicmp(pAttribute, L"objectGUID") == 0)) { kull_m_string_displayGUID((LPGUID) pBerVal[0]->bv_val); kprintf(L"\n"); } else { for(i = 0; pBerVal[i]; i++) { kprintf(L"\n [%u] ", i); if((_wcsicmp(pAttribute, L"sIDHistory") == 0)) { kull_m_string_displaySID(pBerVal[i]->bv_val); if(kull_m_token_getNameDomainFromSID(pBerVal[i]->bv_val, &name, &domain, &nameUse, NULL)) { kprintf(L" ( %s -- %s\\%s )", kull_m_token_getSidNameUse(nameUse), domain, name); LocalFree(name); LocalFree(domain); } } else kull_m_string_wprintf_hex(pBerVal[i]->bv_val, pBerVal[i]->bv_len, 1); } kprintf(L"\n"); } ldap_value_free_len(pBerVal); } ldap_memfree(pAttribute); } if(pBer) ber_free(pBer, 0); } }
static GdaLdapClass * worker_gdaprov_ldap_get_class_info (WorkerLdapClassInfoData *data, GError **error) { GdaLdapClass *retval = NULL; /* initialize known classes */ data->cdata->classes_hash = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, (GDestroyNotify) ldap_class_free); LDAPMessage *msg, *entry; int res; gchar *subschema = NULL; char *subschemasubentry[] = {"subschemaSubentry", NULL}; char *schema_attrs[] = {"objectClasses", NULL}; /* look for subschema */ if (! gda_ldap_ensure_bound (data->cnc, NULL)) return NULL; gda_ldap_execution_slowdown (data->cnc); res = ldap_search_ext_s (data->cdata->handle, "", LDAP_SCOPE_BASE, "(objectclass=*)", subschemasubentry, 0, NULL, NULL, NULL, 0, &msg); if (res != LDAP_SUCCESS) { gda_ldap_may_unbind (data->cnc); return NULL; } if ((entry = ldap_first_entry (data->cdata->handle, msg))) { char *attr; BerElement *ber; if ((attr = ldap_first_attribute (data->cdata->handle, entry, &ber))) { BerValue **bvals; if ((bvals = ldap_get_values_len (data->cdata->handle, entry, attr))) { subschema = g_strdup (bvals[0]->bv_val); ldap_value_free_len (bvals); } ldap_memfree (attr); } if (ber) ber_free (ber, 0); } ldap_msgfree (msg); if (! subschema) { gda_ldap_may_unbind (data->cnc); return NULL; } /* look for attributeTypes */ gda_ldap_execution_slowdown (data->cnc); res = ldap_search_ext_s (data->cdata->handle, subschema, LDAP_SCOPE_BASE, "(objectclass=*)", schema_attrs, 0, NULL, NULL, NULL, 0, &msg); g_free (subschema); if (res != LDAP_SUCCESS) { gda_ldap_may_unbind (data->cnc); return NULL; } GHashTable *h_refs; h_refs = g_hash_table_new_full (NULL, NULL, NULL, (GDestroyNotify) g_strfreev); for (entry = ldap_first_entry (data->cdata->handle, msg); entry; entry = ldap_next_entry (data->cdata->handle, msg)) { char *attr; BerElement *ber; for (attr = ldap_first_attribute (data->cdata->handle, msg, &ber); attr; attr = ldap_next_attribute (data->cdata->handle, msg, ber)) { if (strcasecmp(attr, "objectClasses")) { ldap_memfree (attr); continue; } BerValue **bvals; bvals = ldap_get_values_len (data->cdata->handle, entry, attr); if (bvals) { gint i; for (i = 0; bvals[i]; i++) { LDAPObjectClass *oc; const char *errp; int retcode; oc = ldap_str2objectclass (bvals[i]->bv_val, &retcode, &errp, LDAP_SCHEMA_ALLOW_ALL); if (oc && oc->oc_oid && oc->oc_names && oc->oc_names[0]) { GdaLdapClass *lcl; guint k; lcl = g_new0 (GdaLdapClass, 1); lcl->oid = g_strdup (oc->oc_oid); //#define CLASS_DEBUG #ifdef CLASS_DEBUG g_print ("FOUND CLASS\n"); #endif lcl->names = make_array_from_strv (oc->oc_names, &(lcl->nb_names)); for (k = 0; lcl->names[k]; k++) { #ifdef CLASS_DEBUG g_print (" oc_names[%d] = %s\n", k, lcl->names[k]); #endif g_hash_table_insert (data->cdata->classes_hash, lcl->names[k], lcl); } if (oc->oc_desc) { #ifdef CLASS_DEBUG g_print (" oc_desc = %s\n", oc->oc_desc); #endif lcl->description = g_strdup (oc->oc_desc); } #ifdef CLASS_DEBUG g_print (" oc_kind = %d\n", oc->oc_kind); #endif switch (oc->oc_kind) { case 0: lcl->kind = GDA_LDAP_CLASS_KIND_ABSTRACT; break; case 1: lcl->kind = GDA_LDAP_CLASS_KIND_STRUTURAL; break; case 2: lcl->kind = GDA_LDAP_CLASS_KIND_AUXILIARY; break; default: lcl->kind = GDA_LDAP_CLASS_KIND_UNKNOWN; break; } lcl->obsolete = oc->oc_obsolete; #ifdef CLASS_DEBUG g_print (" oc_obsolete = %d\n", oc->oc_obsolete); #endif gchar **refs; refs = make_array_from_strv (oc->oc_sup_oids, NULL); if (refs) g_hash_table_insert (h_refs, lcl, refs); else data->cdata->top_classes = g_slist_insert_sorted (data->cdata->top_classes, lcl, (GCompareFunc) classes_sort); #ifdef CLASS_DEBUG for (k = 0; oc->oc_sup_oids && oc->oc_sup_oids[k]; k++) g_print (" oc_sup_oids[0] = %s\n", oc->oc_sup_oids[k]); #endif lcl->req_attributes = make_array_from_strv (oc->oc_at_oids_must, &(lcl->nb_req_attributes)); #ifdef CLASS_DEBUG for (k = 0; oc->oc_at_oids_must && oc->oc_at_oids_must[k]; k++) g_print (" oc_at_oids_must[0] = %s\n", oc->oc_at_oids_must[k]); #endif lcl->opt_attributes = make_array_from_strv (oc->oc_at_oids_may, &(lcl->nb_opt_attributes)); #ifdef CLASS_DEBUG for (k = 0; oc->oc_at_oids_may && oc->oc_at_oids_may[k]; k++) g_print (" oc_at_oids_may[0] = %s\n", oc->oc_at_oids_may[k]); #endif } if (oc) ldap_memfree (oc); } ldap_value_free_len (bvals); } ldap_memfree (attr); } if (ber) ber_free (ber, 0); } ldap_msgfree (msg); /* create hierarchy */ g_hash_table_foreach (h_refs, (GHFunc) classes_h_func, data->cdata); g_hash_table_destroy (h_refs); retval = g_hash_table_lookup (data->cdata->classes_hash, data->classname); gda_ldap_may_unbind (data->cnc); return retval; }
static CURLcode ldap_connecting(struct connectdata *conn, bool *done) { ldapconninfo *li = conn->proto.generic; struct SessionHandle *data = conn->data; LDAPMessage *msg = NULL; struct timeval tv = {0, 1}, *tvp; int rc, err; char *info = NULL; #ifdef USE_SSL if(conn->handler->flags & PROTOPT_SSL) { /* Is the SSL handshake complete yet? */ if(!li->ssldone) { CURLcode result = Curl_ssl_connect_nonblocking(conn, FIRSTSOCKET, &li->ssldone); if(result || !li->ssldone) return result; } /* Have we installed the libcurl SSL handlers into the sockbuf yet? */ if(!li->sslinst) { Sockbuf *sb; ldap_get_option(li->ld, LDAP_OPT_SOCKBUF, &sb); ber_sockbuf_add_io(sb, &ldapsb_tls, LBER_SBIOD_LEVEL_TRANSPORT, conn); li->sslinst = TRUE; li->recv = conn->recv[FIRSTSOCKET]; li->send = conn->send[FIRSTSOCKET]; } } #endif tvp = &tv; retry: if(!li->didbind) { char *binddn; struct berval passwd; if(conn->bits.user_passwd) { binddn = conn->user; passwd.bv_val = conn->passwd; passwd.bv_len = strlen(passwd.bv_val); } else { binddn = NULL; passwd.bv_val = NULL; passwd.bv_len = 0; } rc = ldap_sasl_bind(li->ld, binddn, LDAP_SASL_SIMPLE, &passwd, NULL, NULL, &li->msgid); if(rc) return CURLE_LDAP_CANNOT_BIND; li->didbind = TRUE; if(tvp) return CURLE_OK; } rc = ldap_result(li->ld, li->msgid, LDAP_MSG_ONE, tvp, &msg); if(rc < 0) { failf(data, "LDAP local: bind ldap_result %s", ldap_err2string(rc)); return CURLE_LDAP_CANNOT_BIND; } if(rc == 0) { /* timed out */ return CURLE_OK; } rc = ldap_parse_result(li->ld, msg, &err, NULL, &info, NULL, NULL, 1); if(rc) { failf(data, "LDAP local: bind ldap_parse_result %s", ldap_err2string(rc)); return CURLE_LDAP_CANNOT_BIND; } /* Try to fallback to LDAPv2? */ if(err == LDAP_PROTOCOL_ERROR) { int proto; ldap_get_option(li->ld, LDAP_OPT_PROTOCOL_VERSION, &proto); if(proto == LDAP_VERSION3) { if(info) { ldap_memfree(info); info = NULL; } proto = LDAP_VERSION2; ldap_set_option(li->ld, LDAP_OPT_PROTOCOL_VERSION, &proto); li->didbind = FALSE; goto retry; } } if(err) { failf(data, "LDAP remote: bind failed %s %s", ldap_err2string(rc), info ? info : ""); if(info) ldap_memfree(info); return CURLE_LOGIN_DENIED; } if(info) ldap_memfree(info); conn->recv[FIRSTSOCKET] = ldap_recv; *done = TRUE; return CURLE_OK; }
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; }
/* Convert an LDAP error into an informative python exception */ PyObject* LDAPerror( LDAP*l, char*msg ) { if (l == NULL) { PyErr_SetFromErrno( LDAPexception_class ); return NULL; } else { int errnum; PyObject *errobj; PyObject *info; PyObject *str; char *matched, *error; if (ldap_get_option(l, LDAP_OPT_ERROR_NUMBER, &errnum) < 0) errobj = LDAPexception_class; /* unknown error XXX */ else errobj = errobjects[errnum+LDAP_ERROR_OFFSET]; if (errnum == LDAP_NO_MEMORY) return PyErr_NoMemory(); info = PyDict_New(); if (info == NULL) return NULL; str = PyBytes_FromString(ldap_err2string(errnum)); if (str) PyDict_SetItemString( info, "desc", str ); Py_XDECREF(str); if (ldap_get_option(l, LDAP_OPT_MATCHED_DN, &matched) >= 0 && matched != NULL) { if (*matched != '\0') { str = PyBytes_FromString(matched); if (str) PyDict_SetItemString( info, "matched", str ); Py_XDECREF(str); } ldap_memfree(matched); } if (errnum == LDAP_REFERRAL) { str = PyBytes_FromString(msg); if (str) PyDict_SetItemString( info, "info", str ); Py_XDECREF(str); } else if (ldap_get_option(l, LDAP_OPT_ERROR_STRING, &error) >= 0 && error != NULL) { if (error != '\0') { str = PyBytes_FromString(error); if (str) PyDict_SetItemString( info, "info", str ); Py_XDECREF(str); } ldap_memfree(error); } PyErr_SetObject( errobj, info ); Py_DECREF(info); return NULL; } }
/** Perform basic parsing of multiple types of messages, checking for error conditions * * @note Error messages should be retrieved with fr_strerror() and fr_strerror_pop() * * @param[out] ctrls Server ctrls returned to the client. May be NULL if not required. * Must be freed with ldap_free_ctrls. * @param[in] conn the message was received on. * @param[in] msg we're parsing. * @param[in] dn if processing the result from a search request. * @return One of the LDAP_PROC_* (#fr_ldap_rcode_t) values. */ fr_ldap_rcode_t fr_ldap_error_check(LDAPControl ***ctrls, fr_ldap_connection_t const *conn, LDAPMessage *msg, char const *dn) { fr_ldap_rcode_t status = LDAP_PROC_SUCCESS; int msg_type; int lib_errno = LDAP_SUCCESS; /* errno returned by the library */ int srv_errno = LDAP_SUCCESS; /* errno in the result message */ char *part_dn = NULL; /* Partial DN match */ char *srv_err = NULL; /* Server's extended error message */ ssize_t len; if (ctrls) *ctrls = NULL; if (!msg) { ldap_get_option(conn->handle, LDAP_OPT_ERROR_NUMBER, &lib_errno); if (lib_errno != LDAP_SUCCESS) goto process_error; fr_strerror_printf("No result available"); return LDAP_PROC_NO_RESULT; } msg_type = ldap_msgtype(msg); switch (msg_type) { /* * Parse the result and check for errors sent by the server */ case LDAP_RES_SEARCH_RESULT: /* The result of a search */ case LDAP_RES_BIND: /* The result of a bind operation */ case LDAP_RES_EXTENDED: lib_errno = ldap_parse_result(conn->handle, msg, &srv_errno, &part_dn, &srv_err, NULL, ctrls, 0); break; /* * These are messages containing objects so unless they're * malformed they can't contain errors. */ case LDAP_RES_SEARCH_ENTRY: if (ctrls) lib_errno = ldap_get_entry_controls(conn->handle, msg, ctrls); break; /* * An intermediate message updating us on the result of an operation */ case LDAP_RES_INTERMEDIATE: lib_errno = ldap_parse_intermediate(conn->handle, msg, NULL, NULL, ctrls, 0); break; /* * Can't extract any more useful information. */ default: return LDAP_PROC_SUCCESS; } /* * Stupid messy API */ if (lib_errno != LDAP_SUCCESS) { rad_assert(!ctrls || !*ctrls); ldap_get_option(conn->handle, LDAP_OPT_ERROR_NUMBER, &lib_errno); } process_error: if ((lib_errno == LDAP_SUCCESS) && (srv_errno != LDAP_SUCCESS)) { lib_errno = srv_errno; } else if ((lib_errno != LDAP_SUCCESS) && (srv_errno == LDAP_SUCCESS)) { srv_errno = lib_errno; } switch (lib_errno) { case LDAP_SUCCESS: fr_strerror_printf("Success"); break; case LDAP_SASL_BIND_IN_PROGRESS: fr_strerror_printf("Continuing"); status = LDAP_PROC_CONTINUE; break; case LDAP_NO_SUCH_OBJECT: fr_strerror_printf("The specified DN wasn't found"); status = LDAP_PROC_BAD_DN; /* * Build our own internal diagnostic string */ if (dn && part_dn) { char *spaces; char *text; len = fr_ldap_common_dn(dn, part_dn); if (len < 0) break; fr_canonicalize_error(NULL, &spaces, &text, -len, dn); fr_strerror_printf_push("%s", text); fr_strerror_printf_push("%s^ %s", spaces, "match stopped here"); talloc_free(spaces); talloc_free(text); } goto error_string; case LDAP_INSUFFICIENT_ACCESS: fr_strerror_printf("Insufficient access. Check the identity and password configuration directives"); status = LDAP_PROC_NOT_PERMITTED; break; case LDAP_UNWILLING_TO_PERFORM: fr_strerror_printf("Server was unwilling to perform"); status = LDAP_PROC_NOT_PERMITTED; break; case LDAP_FILTER_ERROR: fr_strerror_printf("Bad search filter"); status = LDAP_PROC_ERROR; break; case LDAP_TIMEOUT: fr_strerror_printf("Timed out while waiting for server to respond"); status = LDAP_PROC_TIMEOUT; break; case LDAP_TIMELIMIT_EXCEEDED: fr_strerror_printf("Time limit exceeded"); status = LDAP_PROC_TIMEOUT; break; case LDAP_BUSY: case LDAP_UNAVAILABLE: case LDAP_SERVER_DOWN: status = LDAP_PROC_BAD_CONN; goto error_string; case LDAP_INVALID_CREDENTIALS: case LDAP_CONSTRAINT_VIOLATION: status = LDAP_PROC_REJECT; goto error_string; case LDAP_OPERATIONS_ERROR: fr_strerror_printf("Please set 'chase_referrals=yes' and 'rebind=yes'. " "See the ldap module configuration for details"); /* FALL-THROUGH */ default: status = LDAP_PROC_ERROR; error_string: if (lib_errno == srv_errno) { fr_strerror_printf("lib error: %s (%u)", ldap_err2string(lib_errno), lib_errno); } else { fr_strerror_printf("lib error: %s (%u), srv error: %s (%u)", ldap_err2string(lib_errno), lib_errno, ldap_err2string(srv_errno), srv_errno); } if (srv_err) fr_strerror_printf_push("Server said: %s", srv_err); break; } /* * Cleanup memory */ if (srv_err) ldap_memfree(srv_err); if (part_dn) ldap_memfree(part_dn); return status; }
int parse_at( struct config_args_s *c, AttributeType **sat, AttributeType *prev ) { LDAPAttributeType *at; int code; const char *err; char *line = strchr( c->line, '(' ); at = ldap_str2attributetype( line, &code, &err, LDAP_SCHEMA_ALLOW_ALL ); if ( !at ) { snprintf( c->cr_msg, sizeof( c->cr_msg ), "%s: %s before %s", c->argv[0], ldap_scherr2str(code), err ); Debug( LDAP_DEBUG_CONFIG|LDAP_DEBUG_NONE, "%s %s\n", c->log, c->cr_msg ); at_usage(); return 1; } if ( at->at_oid == NULL ) { snprintf( c->cr_msg, sizeof( c->cr_msg ), "%s: OID is missing", c->argv[0] ); Debug( LDAP_DEBUG_CONFIG|LDAP_DEBUG_NONE, "%s %s\n", c->log, c->cr_msg ); at_usage(); code = 1; goto done; } /* operational attributes should be defined internally */ if ( at->at_usage ) { snprintf( c->cr_msg, sizeof( c->cr_msg ), "%s: \"%s\" is operational", c->argv[0], at->at_oid ); Debug( LDAP_DEBUG_CONFIG|LDAP_DEBUG_NONE, "%s %s\n", c->log, c->cr_msg ); code = 1; goto done; } code = at_add( at, 1, sat, prev, &err); if ( code ) { snprintf( c->cr_msg, sizeof( c->cr_msg ), "%s: %s: \"%s\"", c->argv[0], scherr2str(code), err); Debug( LDAP_DEBUG_CONFIG|LDAP_DEBUG_NONE, "%s %s\n", c->log, c->cr_msg ); code = 1; goto done; } done:; if ( code ) { ldap_attributetype_free( at ); } else { ldap_memfree( at ); } return code; }
/** 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; }
/* * handle the LDAP_RES_INTERMEDIATE response */ static int ldap_sync_search_intermediate( ldap_sync_t *ls, LDAPMessage *res, int *refreshDone ) { int rc; char *retoid = NULL; struct berval *retdata = NULL; BerElement *ber = NULL; ber_len_t len; ber_tag_t syncinfo_tag; struct berval cookie; int refreshDeletes = 0; BerVarray syncUUIDs = NULL; ldap_sync_refresh_t phase; #ifdef LDAP_SYNC_TRACE fprintf( stderr, "\tgot LDAP_RES_INTERMEDIATE\n" ); #endif /* LDAP_SYNC_TRACE */ assert( ls != NULL ); assert( res != NULL ); assert( refreshDone != NULL ); *refreshDone = 0; rc = ldap_parse_intermediate( ls->ls_ld, res, &retoid, &retdata, NULL, 0 ); #ifdef LDAP_SYNC_TRACE fprintf( stderr, "\t%sldap_parse_intermediate(%s) == %d\n", rc != LDAP_SUCCESS ? "!!! " : "", retoid == NULL ? "\"\"" : retoid, rc ); #endif /* LDAP_SYNC_TRACE */ /* parsing must be successful, and yield the OID * of the sync info intermediate response */ if ( rc != LDAP_SUCCESS ) { goto done; } rc = LDAP_OTHER; if ( retoid == NULL || strcmp( retoid, LDAP_SYNC_INFO ) != 0 ) { goto done; } /* init ber using the value in the response */ ber = ber_init( retdata ); if ( ber == NULL ) { goto done; } syncinfo_tag = ber_peek_tag( ber, &len ); switch ( syncinfo_tag ) { case LDAP_TAG_SYNC_NEW_COOKIE: if ( ber_scanf( ber, "m", &cookie ) == LBER_ERROR ) { goto done; } if ( cookie.bv_val != NULL ) { ber_bvreplace( &ls->ls_cookie, &cookie ); } #ifdef LDAP_SYNC_TRACE fprintf( stderr, "\t\tgot cookie=%s\n", cookie.bv_val ? cookie.bv_val : "(null)" ); #endif /* LDAP_SYNC_TRACE */ break; case LDAP_TAG_SYNC_REFRESH_DELETE: case LDAP_TAG_SYNC_REFRESH_PRESENT: if ( syncinfo_tag == LDAP_TAG_SYNC_REFRESH_DELETE ) { #ifdef LDAP_SYNC_TRACE fprintf( stderr, "\t\tgot refreshDelete\n" ); #endif /* LDAP_SYNC_TRACE */ switch ( ls->ls_refreshPhase ) { case LDAP_SYNC_CAPI_NONE: case LDAP_SYNC_CAPI_PRESENTS: ls->ls_refreshPhase = LDAP_SYNC_CAPI_DELETES; break; default: /* TODO: impossible; handle */ goto done; } } else { #ifdef LDAP_SYNC_TRACE fprintf( stderr, "\t\tgot refreshPresent\n" ); #endif /* LDAP_SYNC_TRACE */ switch ( ls->ls_refreshPhase ) { case LDAP_SYNC_CAPI_NONE: ls->ls_refreshPhase = LDAP_SYNC_CAPI_PRESENTS; break; default: /* TODO: impossible; handle */ goto done; } } if ( ber_scanf( ber, "{" /*"}"*/ ) == LBER_ERROR ) { goto done; } if ( ber_peek_tag( ber, &len ) == LDAP_TAG_SYNC_COOKIE ) { if ( ber_scanf( ber, "m", &cookie ) == LBER_ERROR ) { goto done; } if ( cookie.bv_val != NULL ) { ber_bvreplace( &ls->ls_cookie, &cookie ); } #ifdef LDAP_SYNC_TRACE fprintf( stderr, "\t\tgot cookie=%s\n", cookie.bv_val ? cookie.bv_val : "(null)" ); #endif /* LDAP_SYNC_TRACE */ } *refreshDone = 1; if ( ber_peek_tag( ber, &len ) == LDAP_TAG_REFRESHDONE ) { if ( ber_scanf( ber, "b", refreshDone ) == LBER_ERROR ) { goto done; } } #ifdef LDAP_SYNC_TRACE fprintf( stderr, "\t\tgot refreshDone=%s\n", *refreshDone ? "TRUE" : "FALSE" ); #endif /* LDAP_SYNC_TRACE */ if ( ber_scanf( ber, /*"{"*/ "}" ) == LBER_ERROR ) { goto done; } if ( *refreshDone ) { ls->ls_refreshPhase = LDAP_SYNC_CAPI_DONE; } if ( ls->ls_intermediate ) { ls->ls_intermediate( ls, res, NULL, ls->ls_refreshPhase ); } break; case LDAP_TAG_SYNC_ID_SET: #ifdef LDAP_SYNC_TRACE fprintf( stderr, "\t\tgot syncIdSet\n" ); #endif /* LDAP_SYNC_TRACE */ if ( ber_scanf( ber, "{" /*"}"*/ ) == LBER_ERROR ) { goto done; } if ( ber_peek_tag( ber, &len ) == LDAP_TAG_SYNC_COOKIE ) { if ( ber_scanf( ber, "m", &cookie ) == LBER_ERROR ) { goto done; } if ( cookie.bv_val != NULL ) { ber_bvreplace( &ls->ls_cookie, &cookie ); } #ifdef LDAP_SYNC_TRACE fprintf( stderr, "\t\tgot cookie=%s\n", cookie.bv_val ? cookie.bv_val : "(null)" ); #endif /* LDAP_SYNC_TRACE */ } if ( ber_peek_tag( ber, &len ) == LDAP_TAG_REFRESHDELETES ) { if ( ber_scanf( ber, "b", &refreshDeletes ) == LBER_ERROR ) { goto done; } } if ( ber_scanf( ber, /*"{"*/ "[W]}", &syncUUIDs ) == LBER_ERROR || syncUUIDs == NULL ) { goto done; } #ifdef LDAP_SYNC_TRACE { int i; fprintf( stderr, "\t\tgot refreshDeletes=%s\n", refreshDeletes ? "TRUE" : "FALSE" ); for ( i = 0; syncUUIDs[ i ].bv_val != NULL; i++ ) { char buf[ BUFSIZ ]; fprintf( stderr, "\t\t%s\n", lutil_uuidstr_from_normalized( syncUUIDs[ i ].bv_val, syncUUIDs[ i ].bv_len, buf, sizeof( buf ) ) ); } } #endif /* LDAP_SYNC_TRACE */ if ( refreshDeletes ) { phase = LDAP_SYNC_CAPI_DELETES_IDSET; } else { phase = LDAP_SYNC_CAPI_PRESENTS_IDSET; } /* FIXME: should touch ls->ls_refreshPhase? */ if ( ls->ls_intermediate ) { ls->ls_intermediate( ls, res, syncUUIDs, phase ); } ber_bvarray_free( syncUUIDs ); break; default: #ifdef LDAP_SYNC_TRACE fprintf( stderr, "\t\tunknown tag!\n" ); #endif /* LDAP_SYNC_TRACE */ goto done; } rc = LDAP_SUCCESS; done:; if ( ber != NULL ) { ber_free( ber, 1 ); } if ( retoid != NULL ) { ldap_memfree( retoid ); } if ( retdata != NULL ) { ber_bvfree( retdata ); } return rc; }
static NTSTATUS idmap_ldap_set_mapping(struct idmap_domain *dom, const struct id_map *map) { NTSTATUS ret; TALLOC_CTX *memctx; struct idmap_ldap_context *ctx; LDAPMessage *entry = NULL; LDAPMod **mods = NULL; const char *type; char *id_str; char *sid; char *dn; int rc = -1; /* Only do query if we are online */ if (idmap_is_offline()) { return NT_STATUS_FILE_IS_OFFLINE; } ctx = talloc_get_type(dom->private_data, struct idmap_ldap_context); switch(map->xid.type) { case ID_TYPE_UID: type = get_attr_key2string(sidmap_attr_list, LDAP_ATTR_UIDNUMBER); break; case ID_TYPE_GID: type = get_attr_key2string(sidmap_attr_list, LDAP_ATTR_GIDNUMBER); break; default: return NT_STATUS_INVALID_PARAMETER; } memctx = talloc_new(ctx); if ( ! memctx) { DEBUG(0, ("Out of memory!\n")); return NT_STATUS_NO_MEMORY; } id_str = talloc_asprintf(memctx, "%lu", (unsigned long)map->xid.id); CHECK_ALLOC_DONE(id_str); sid = talloc_strdup(memctx, sid_string_talloc(memctx, map->sid)); CHECK_ALLOC_DONE(sid); dn = talloc_asprintf(memctx, "%s=%s,%s", get_attr_key2string(sidmap_attr_list, LDAP_ATTR_SID), sid, ctx->suffix); CHECK_ALLOC_DONE(dn); smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectClass", LDAP_OBJ_IDMAP_ENTRY); smbldap_make_mod(ctx->smbldap_state->ldap_struct, entry, &mods, type, id_str); smbldap_make_mod(ctx->smbldap_state->ldap_struct, entry, &mods, get_attr_key2string(sidmap_attr_list, LDAP_ATTR_SID), sid); if ( ! mods) { DEBUG(2, ("ERROR: No mods?\n")); ret = NT_STATUS_UNSUCCESSFUL; goto done; } /* TODO: remove conflicting mappings! */ smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectClass", LDAP_OBJ_SID_ENTRY); DEBUG(10, ("Set DN %s (%s -> %s)\n", dn, sid, id_str)); rc = smbldap_add(ctx->smbldap_state, dn, mods); ldap_mods_free(mods, True); if (rc != LDAP_SUCCESS) { char *ld_error = NULL; ldap_get_option(ctx->smbldap_state->ldap_struct, LDAP_OPT_ERROR_STRING, &ld_error); DEBUG(0,("ldap_set_mapping_internals: Failed to add %s to %lu " "mapping [%s]\n", sid, (unsigned long)map->xid.id, type)); DEBUG(0, ("ldap_set_mapping_internals: Error was: %s (%s)\n", ld_error ? ld_error : "(NULL)", ldap_err2string (rc))); if (ld_error) { ldap_memfree(ld_error); } ret = NT_STATUS_UNSUCCESSFUL; goto done; } DEBUG(10,("ldap_set_mapping: Successfully created mapping from %s to " "%lu [%s]\n", sid, (unsigned long)map->xid.id, type)); ret = NT_STATUS_OK; done: talloc_free(memctx); return ret; }
int asyncmeta_handle_search_msg(LDAPMessage *res, a_metaconn_t *mc, bm_context_t *bc, int candidate) { a_metainfo_t *mi; a_metatarget_t *mt; a_metasingleconn_t *msc; Operation *op = bc->op; SlapReply *rs; int i, rc = LDAP_SUCCESS, sres; SlapReply *candidates; char **references = NULL; LDAPControl **ctrls = NULL; a_dncookie dc; LDAPMessage *msg; ber_int_t id; rs = &bc->rs; mi = mc->mc_info; mt = mi->mi_targets[ candidate ]; msc = &mc->mc_conns[ candidate ]; dc.op = op; dc.target = mt; dc.to_from = MASSAGE_REP; id = ldap_msgid(res); candidates = bc->candidates; i = candidate; while (res && !META_BACK_CONN_INVALID(msc)) { for (msg = ldap_first_message(msc->msc_ldr, res); msg; msg = ldap_next_message(msc->msc_ldr, msg)) { switch(ldap_msgtype(msg)) { case LDAP_RES_SEARCH_ENTRY: Debug( LDAP_DEBUG_TRACE, "%s asyncmeta_handle_search_msg: msc %p entry\n", op->o_log_prefix, msc ); if ( candidates[ i ].sr_type == REP_INTERMEDIATE ) { /* don't retry any more... */ candidates[ i ].sr_type = REP_RESULT; } /* count entries returned by target */ candidates[ i ].sr_nentries++; if (bc->c_peer_name.bv_val == op->o_conn->c_peer_name.bv_val && !op->o_abandon) { rs->sr_err = asyncmeta_send_entry( &bc->copy_op, rs, mc, i, msg ); } else { goto err_cleanup; } switch ( rs->sr_err ) { case LDAP_SIZELIMIT_EXCEEDED: asyncmeta_send_ldap_result(bc, op, rs); rs->sr_err = LDAP_SUCCESS; goto err_cleanup; case LDAP_UNAVAILABLE: rs->sr_err = LDAP_OTHER; break; default: break; } bc->is_ok++; break; case LDAP_RES_SEARCH_REFERENCE: if ( META_BACK_TGT_NOREFS( mt ) ) { rs->sr_err = LDAP_OTHER; asyncmeta_send_ldap_result(bc, op, rs); goto err_cleanup; } if ( candidates[ i ].sr_type == REP_INTERMEDIATE ) { /* don't retry any more... */ candidates[ i ].sr_type = REP_RESULT; } bc->is_ok++; rc = ldap_parse_reference( msc->msc_ldr, msg, &references, &rs->sr_ctrls, 0 ); if ( rc != LDAP_SUCCESS || references == NULL ) { rs->sr_err = LDAP_OTHER; asyncmeta_send_ldap_result(bc, op, rs); goto err_cleanup; } /* FIXME: merge all and return at the end */ { int cnt; for ( cnt = 0; references[ cnt ]; cnt++ ) ; rs->sr_ref = ber_memalloc_x( sizeof( struct berval ) * ( cnt + 1 ), op->o_tmpmemctx ); for ( cnt = 0; references[ cnt ]; cnt++ ) { ber_str2bv_x( references[ cnt ], 0, 1, &rs->sr_ref[ cnt ], op->o_tmpmemctx ); } BER_BVZERO( &rs->sr_ref[ cnt ] ); } { dc.memctx = op->o_tmpmemctx; ( void )asyncmeta_referral_result_rewrite( &dc, rs->sr_ref ); } if ( rs->sr_ref != NULL ) { if (!BER_BVISNULL( &rs->sr_ref[ 0 ] ) ) { /* ignore return value by now */ ( void )send_search_reference( op, rs ); } ber_bvarray_free_x( rs->sr_ref, op->o_tmpmemctx ); rs->sr_ref = NULL; } /* cleanup */ if ( references ) { ber_memvfree( (void **)references ); } if ( rs->sr_ctrls ) { ldap_controls_free( rs->sr_ctrls ); rs->sr_ctrls = NULL; } break; case LDAP_RES_INTERMEDIATE: if ( candidates[ i ].sr_type == REP_INTERMEDIATE ) { /* don't retry any more... */ candidates[ i ].sr_type = REP_RESULT; } bc->is_ok++; /* FIXME: response controls * are passed without checks */ rs->sr_err = ldap_parse_intermediate( msc->msc_ldr, msg, (char **)&rs->sr_rspoid, &rs->sr_rspdata, &rs->sr_ctrls, 0 ); if ( rs->sr_err != LDAP_SUCCESS ) { candidates[ i ].sr_type = REP_RESULT; rs->sr_err = LDAP_OTHER; asyncmeta_send_ldap_result(bc, op, rs); goto err_cleanup; } slap_send_ldap_intermediate( op, rs ); if ( rs->sr_rspoid != NULL ) { ber_memfree( (char *)rs->sr_rspoid ); rs->sr_rspoid = NULL; } if ( rs->sr_rspdata != NULL ) { ber_bvfree( rs->sr_rspdata ); rs->sr_rspdata = NULL; } if ( rs->sr_ctrls != NULL ) { ldap_controls_free( rs->sr_ctrls ); rs->sr_ctrls = NULL; } break; case LDAP_RES_SEARCH_RESULT: if ( mi->mi_idle_timeout != 0 ) { asyncmeta_set_msc_time(msc); } Debug( LDAP_DEBUG_TRACE, "%s asyncmeta_handle_search_msg: msc %p result\n", op->o_log_prefix, msc ); candidates[ i ].sr_type = REP_RESULT; candidates[ i ].sr_msgid = META_MSGID_IGNORE; /* NOTE: ignores response controls * (and intermediate response controls * as well, except for those with search * references); this may not be correct, * but if they're not ignored then * back-meta would need to merge them * consistently (think of pagedResults...) */ /* FIXME: response controls? */ rs->sr_err = ldap_parse_result( msc->msc_ldr, msg, &candidates[ i ].sr_err, (char **)&candidates[ i ].sr_matched, (char **)&candidates[ i ].sr_text, &references, &ctrls /* &candidates[ i ].sr_ctrls (unused) */ , 0 ); if ( rs->sr_err != LDAP_SUCCESS ) { candidates[ i ].sr_err = rs->sr_err; sres = slap_map_api2result( &candidates[ i ] ); candidates[ i ].sr_type = REP_RESULT; goto finish; } rs->sr_err = candidates[ i ].sr_err; /* massage matchedDN if need be */ if ( candidates[ i ].sr_matched != NULL ) { struct berval match, mmatch; ber_str2bv( candidates[ i ].sr_matched, 0, 0, &match ); candidates[ i ].sr_matched = NULL; dc.memctx = NULL; asyncmeta_dn_massage( &dc, &match, &mmatch ); if ( mmatch.bv_val == match.bv_val ) { candidates[ i ].sr_matched = ch_strdup( mmatch.bv_val ); } else { candidates[ i ].sr_matched = mmatch.bv_val; } bc->candidate_match++; ldap_memfree( match.bv_val ); } /* add references to array */ /* RFC 4511: referrals can only appear * if result code is LDAP_REFERRAL */ if ( references != NULL && references[ 0 ] != NULL && references[ 0 ][ 0 ] != '\0' ) { if ( rs->sr_err != LDAP_REFERRAL ) { Debug( LDAP_DEBUG_ANY, "%s asncmeta_search_result[%d]: " "got referrals with err=%d\n", op->o_log_prefix, i, rs->sr_err ); } else { BerVarray sr_ref; int cnt; for ( cnt = 0; references[ cnt ]; cnt++ ) ; sr_ref = ber_memalloc_x( sizeof( struct berval ) * ( cnt + 1 ), op->o_tmpmemctx ); for ( cnt = 0; references[ cnt ]; cnt++ ) { ber_str2bv_x( references[ cnt ], 0, 1, &sr_ref[ cnt ], op->o_tmpmemctx ); } BER_BVZERO( &sr_ref[ cnt ] ); dc.memctx = op->o_tmpmemctx; ( void )asyncmeta_referral_result_rewrite( &dc, sr_ref ); if ( rs->sr_v2ref == NULL ) { rs->sr_v2ref = sr_ref; } else { for ( cnt = 0; !BER_BVISNULL( &sr_ref[ cnt ] ); cnt++ ) { ber_bvarray_add_x( &rs->sr_v2ref, &sr_ref[ cnt ], op->o_tmpmemctx ); } ber_memfree_x( sr_ref, op->o_tmpmemctx ); } } } else if ( rs->sr_err == LDAP_REFERRAL ) { Debug( LDAP_DEBUG_TRACE, "%s asyncmeta_search_result[%d]: " "got err=%d with null " "or empty referrals\n", op->o_log_prefix, i, rs->sr_err ); rs->sr_err = LDAP_NO_SUCH_OBJECT; } /* cleanup */ ber_memvfree( (void **)references ); sres = slap_map_api2result( rs ); if ( candidates[ i ].sr_err == LDAP_SUCCESS ) { Debug( LDAP_DEBUG_TRACE, "%s asyncmeta_search_result[%d] " "match=\"%s\" err=%ld", op->o_log_prefix, i, candidates[ i ].sr_matched ? candidates[ i ].sr_matched : "", (long) candidates[ i ].sr_err ); } else { Debug( LDAP_DEBUG_ANY, "%s asyncmeta_search_result[%d] " "match=\"%s\" err=%ld (%s)", op->o_log_prefix, i, candidates[ i ].sr_matched ? candidates[ i ].sr_matched : "", (long) candidates[ i ].sr_err, ldap_err2string( candidates[ i ].sr_err ) ); } switch ( sres ) { case LDAP_NO_SUCH_OBJECT: /* is_ok is touched any time a valid * (even intermediate) result is * returned; as a consequence, if * a candidate returns noSuchObject * it is ignored and the candidate * is simply demoted. */ if ( bc->is_ok ) { sres = LDAP_SUCCESS; } break; case LDAP_SUCCESS: if ( ctrls != NULL && ctrls[0] != NULL ) { #ifdef SLAPD_META_CLIENT_PR LDAPControl *pr_c; pr_c = ldap_control_find( LDAP_CONTROL_PAGEDRESULTS, ctrls, NULL ); if ( pr_c != NULL ) { BerElementBuffer berbuf; BerElement *ber = (BerElement *)&berbuf; ber_tag_t tag; ber_int_t prsize; struct berval prcookie; /* unsolicited, do not accept */ if ( mt->mt_ps == 0 ) { rs->sr_err = LDAP_OTHER; goto err_pr; } ber_init2( ber, &pr_c->ldctl_value, LBER_USE_DER ); tag = ber_scanf( ber, "{im}", &prsize, &prcookie ); if ( tag == LBER_ERROR ) { rs->sr_err = LDAP_OTHER; goto err_pr; } /* more pages? new search request */ if ( !BER_BVISNULL( &prcookie ) && !BER_BVISEMPTY( &prcookie ) ) { if ( mt->mt_ps > 0 ) { /* ignore size if specified */ prsize = 0; } else if ( prsize == 0 ) { /* guess the page size from the entries returned so far */ prsize = candidates[ i ].sr_nentries; } candidates[ i ].sr_nentries = 0; candidates[ i ].sr_msgid = META_MSGID_IGNORE; candidates[ i ].sr_type = REP_INTERMEDIATE; assert( candidates[ i ].sr_matched == NULL ); assert( candidates[ i ].sr_text == NULL ); assert( candidates[ i ].sr_ref == NULL ); switch ( asyncmeta_back_search_start( &bc->copy_op, rs, mc, bc, i, &prcookie, prsize, 1 ) ) { case META_SEARCH_CANDIDATE: assert( candidates[ i ].sr_msgid >= 0 ); ldap_controls_free( ctrls ); // goto free_message; case META_SEARCH_ERR: case META_SEARCH_NEED_BIND: err_pr:; candidates[ i ].sr_err = rs->sr_err; candidates[ i ].sr_type = REP_RESULT; if ( META_BACK_ONERR_STOP( mi ) ) { asyncmeta_send_ldap_result(bc, op, rs); ldap_controls_free( ctrls ); goto err_cleanup; } /* fallthru */ case META_SEARCH_NOT_CANDIDATE: /* means that asyncmeta_back_search_start() * failed but onerr == continue */ candidates[ i ].sr_msgid = META_MSGID_IGNORE; candidates[ i ].sr_type = REP_RESULT; break; default: /* impossible */ assert( 0 ); break; } break; } } #endif /* SLAPD_META_CLIENT_PR */ ldap_controls_free( ctrls ); } /* fallthru */ case LDAP_REFERRAL: bc->is_ok++; break; case LDAP_SIZELIMIT_EXCEEDED: /* if a target returned sizelimitExceeded * and the entry count is equal to the * proxy's limit, the target would have * returned more, and the error must be * propagated to the client; otherwise, * the target enforced a limit lower * than what requested by the proxy; * ignore it */ candidates[ i ].sr_err = rs->sr_err; if ( rs->sr_nentries == op->ors_slimit || META_BACK_ONERR_STOP( mi ) ) { const char *save_text; got_err: save_text = rs->sr_text; rs->sr_text = candidates[ i ].sr_text; asyncmeta_send_ldap_result(bc, op, rs); if (candidates[ i ].sr_text != NULL) { ch_free( (char *)candidates[ i ].sr_text ); candidates[ i ].sr_text = NULL; } rs->sr_text = save_text; ldap_controls_free( ctrls ); goto err_cleanup; } break; default: candidates[ i ].sr_err = rs->sr_err; if ( META_BACK_ONERR_STOP( mi ) ) { goto got_err; } break; } /* if this is the last result we will ever receive, send it back */ rc = rs->sr_err; if (asyncmeta_is_last_result(mc, bc, i) == 0) { Debug( LDAP_DEBUG_TRACE, "%s asyncmeta_handle_search_msg: msc %p last result\n", op->o_log_prefix, msc ); asyncmeta_search_last_result(mc, bc, i, sres); err_cleanup: rc = rs->sr_err; ldap_pvt_thread_mutex_lock( &mc->mc_om_mutex ); asyncmeta_drop_bc( mc, bc); asyncmeta_clear_bm_context(bc); ldap_pvt_thread_mutex_unlock( &mc->mc_om_mutex ); ldap_msgfree(res); return rc; } finish: break; default: continue; } } ldap_msgfree(res); res = NULL; if (candidates[ i ].sr_type != REP_RESULT) { struct timeval tv = {0}; rc = ldap_result( msc->msc_ldr, id, LDAP_MSG_RECEIVED, &tv, &res ); if (res != NULL) { msc->msc_result_time = slap_get_time(); } } } ldap_pvt_thread_mutex_lock( &mc->mc_om_mutex ); bc->bc_active--; ldap_pvt_thread_mutex_unlock( &mc->mc_om_mutex ); return rc; }
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; }
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; }
int main( int argc, char *argv[] ) { int rc, i, debug = 0, f2 = 0; unsigned flags[ 2 ] = { 0U, 0 }; char *strin, *str = NULL, buf[ 1024 ]; LDAPDN dn, dn2 = NULL; while ( 1 ) { int opt = getopt( argc, argv, "d:" ); if ( opt == EOF ) { break; } switch ( opt ) { case 'd': debug = atoi( optarg ); break; } } optind--; argc -= optind; argv += optind; if ( argc < 2 ) { fprintf( stderr, "usage: dntest <dn> [flags-in[,...]] [flags-out[,...]]\n\n" ); fprintf( stderr, "\tflags-in: V3,V2,DCE,<flags>\n" ); fprintf( stderr, "\tflags-out: V3,V2,UFN,DCE,AD,<flags>\n\n" ); fprintf( stderr, "\t<flags>: PRETTY,PEDANTIC,NOSPACES,NOONESPACE\n\n" ); return( 0 ); } if ( ber_set_option( NULL, LBER_OPT_DEBUG_LEVEL, &debug ) != LBER_OPT_SUCCESS ) { fprintf( stderr, "Could not set LBER_OPT_DEBUG_LEVEL %d\n", debug ); } if ( ldap_set_option( NULL, LDAP_OPT_DEBUG_LEVEL, &debug ) != LDAP_OPT_SUCCESS ) { fprintf( stderr, "Could not set LDAP_OPT_DEBUG_LEVEL %d\n", debug ); } if ( strcmp( argv[ 1 ], "-" ) == 0 ) { size_t len = fgets( buf, sizeof( buf ), stdin ) ? strlen( buf ) : 0; if ( len == 0 || buf[ --len ] == '\n' ) { buf[ len ] = '\0'; } strin = buf; } else { strin = argv[ 1 ]; } if ( argc >= 3 ) { for ( i = 0; i < argc - 2; i++ ) { char *s, *e; for ( s = argv[ 2 + i ]; s; s = e ) { e = strchr( s, ',' ); if ( e != NULL ) { e[ 0 ] = '\0'; e++; } if ( !strcasecmp( s, "V3" ) ) { flags[ i ] |= LDAP_DN_FORMAT_LDAPV3; } else if ( !strcasecmp( s, "V2" ) ) { flags[ i ] |= LDAP_DN_FORMAT_LDAPV2; } else if ( !strcasecmp( s, "DCE" ) ) { flags[ i ] |= LDAP_DN_FORMAT_DCE; } else if ( !strcasecmp( s, "UFN" ) ) { flags[ i ] |= LDAP_DN_FORMAT_UFN; } else if ( !strcasecmp( s, "AD" ) ) { flags[ i ] |= LDAP_DN_FORMAT_AD_CANONICAL; } else if ( !strcasecmp( s, "PRETTY" ) ) { flags[ i ] |= LDAP_DN_PRETTY; } else if ( !strcasecmp( s, "PEDANTIC" ) ) { flags[ i ] |= LDAP_DN_PEDANTIC; } else if ( !strcasecmp( s, "NOSPACES" ) ) { flags[ i ] |= LDAP_DN_P_NOLEADTRAILSPACES; } else if ( !strcasecmp( s, "NOONESPACE" ) ) { flags[ i ] |= LDAP_DN_P_NOSPACEAFTERRDN; } } } } if ( flags[ 1 ] == 0 ) flags[ 1 ] = LDAP_DN_FORMAT_LDAPV3; f2 = 1; rc = ldap_str2dn( strin, &dn, flags[ 0 ] ); if ( rc == LDAP_SUCCESS ) { int i; if ( dn ) { for ( i = 0; dn[ i ]; i++ ) { LDAPRDN rdn = dn[ i ]; char *rstr = NULL; if ( ldap_rdn2str( rdn, &rstr, flags[ f2 ] ) ) { fprintf( stdout, "\tldap_rdn2str() failed\n" ); continue; } fprintf( stdout, "\tldap_rdn2str() = \"%s\"\n", rstr ); ldap_memfree( rstr ); } } else { fprintf( stdout, "\tempty DN\n" ); } } str = NULL; if ( rc == LDAP_SUCCESS && ldap_dn2str( dn, &str, flags[ f2 ] ) == LDAP_SUCCESS ) { char **values, *tmp, *tmp2, *str2 = NULL; int n; fprintf( stdout, "\nldap_dn2str(ldap_str2dn(\"%s\"))\n" "\t= \"%s\"\n", strin, str ); switch ( flags[ f2 ] & LDAP_DN_FORMAT_MASK ) { case LDAP_DN_FORMAT_UFN: case LDAP_DN_FORMAT_AD_CANONICAL: return( 0 ); case LDAP_DN_FORMAT_LDAPV3: case LDAP_DN_FORMAT_LDAPV2: n = ldap_dn2domain( strin, &tmp ); if ( n ) { fprintf( stdout, "\nldap_dn2domain(\"%s\") FAILED\n", strin ); } else { fprintf( stdout, "\nldap_dn2domain(\"%s\")\n" "\t= \"%s\"\n", strin, tmp ? tmp : "" ); } ldap_memfree( tmp ); tmp = ldap_dn2ufn( strin ); fprintf( stdout, "\nldap_dn2ufn(\"%s\")\n" "\t= \"%s\"\n", strin, tmp ? tmp : "" ); ldap_memfree( tmp ); tmp = ldap_dn2dcedn( strin ); fprintf( stdout, "\nldap_dn2dcedn(\"%s\")\n" "\t= \"%s\"\n", strin, tmp ? tmp : "" ); tmp2 = ldap_dcedn2dn( tmp ); fprintf( stdout, "\nldap_dcedn2dn(\"%s\")\n" "\t= \"%s\"\n", tmp ? tmp : "", tmp2 ? tmp2 : "" ); ldap_memfree( tmp ); ldap_memfree( tmp2 ); tmp = ldap_dn2ad_canonical( strin ); fprintf( stdout, "\nldap_dn2ad_canonical(\"%s\")\n" "\t= \"%s\"\n", strin, tmp ? tmp : "" ); ldap_memfree( tmp ); fprintf( stdout, "\nldap_explode_dn(\"%s\"):\n", str ); values = ldap_explode_dn( str, 0 ); for ( n = 0; values && values[ n ]; n++ ) { char **vv; int nn; fprintf( stdout, "\t\"%s\"\n", values[ n ] ); fprintf( stdout, "\tldap_explode_rdn(\"%s\")\n", values[ n ] ); vv = ldap_explode_rdn( values[ n ], 0 ); for ( nn = 0; vv && vv[ nn ]; nn++ ) { fprintf( stdout, "\t\t'%s'\n", vv[ nn ] ); } LDAP_VFREE( vv ); fprintf( stdout, "\tldap_explode_rdn(\"%s\")" " (no types)\n", values[ n ] ); vv = ldap_explode_rdn( values[ n ], 1 ); for ( nn = 0; vv && vv[ nn ]; nn++ ) { fprintf( stdout, "\t\t\t\"%s\"\n", vv[ nn ] ); } LDAP_VFREE( vv ); } LDAP_VFREE( values ); fprintf( stdout, "\nldap_explode_dn(\"%s\")" " (no types):\n", str ); values = ldap_explode_dn( str, 1 ); for ( n = 0; values && values[ n ]; n++ ) { fprintf( stdout, "\t\"%s\"\n", values[ n ] ); } LDAP_VFREE( values ); break; } dn2 = NULL; rc = ldap_str2dn( str, &dn2, flags[ f2 ] ); str2 = NULL; if ( rc == LDAP_SUCCESS && ldap_dn2str( dn2, &str2, flags[ f2 ] ) == LDAP_SUCCESS ) { int iRDN; fprintf( stdout, "\n\"%s\"\n\t == \"%s\" ? %s\n", str, str2, strcmp( str, str2 ) == 0 ? "yes" : "no" ); if( dn != NULL && dn2 == NULL ) { fprintf( stdout, "dn mismatch\n" ); } else if (( dn != NULL ) && (dn2 != NULL)) for ( iRDN = 0; dn[ iRDN ] && dn2[ iRDN ]; iRDN++ ) { LDAPRDN r = dn[ iRDN ]; LDAPRDN r2 = dn2[ iRDN ]; int iAVA; for ( iAVA = 0; r[ iAVA ] && r2[ iAVA ]; iAVA++ ) { LDAPAVA *a = r[ iAVA ]; LDAPAVA *a2 = r2[ iAVA ]; if ( a->la_attr.bv_len != a2->la_attr.bv_len ) { fprintf( stdout, "ava(%d), rdn(%d) attr len mismatch (%ld->%ld)\n", iAVA + 1, iRDN + 1, a->la_attr.bv_len, a2->la_attr.bv_len ); } else if ( memcmp( a->la_attr.bv_val, a2->la_attr.bv_val, a->la_attr.bv_len ) ) { fprintf( stdout, "ava(%d), rdn(%d) attr mismatch\n", iAVA + 1, iRDN + 1 ); } else if ( a->la_flags != a2->la_flags ) { fprintf( stdout, "ava(%d), rdn(%d) flag mismatch (%x->%x)\n", iAVA + 1, iRDN + 1, a->la_flags, a2->la_flags ); } else if ( a->la_value.bv_len != a2->la_value.bv_len ) { fprintf( stdout, "ava(%d), rdn(%d) value len mismatch (%ld->%ld)\n", iAVA + 1, iRDN + 1, a->la_value.bv_len, a2->la_value.bv_len ); } else if ( memcmp( a->la_value.bv_val, a2->la_value.bv_val, a->la_value.bv_len ) ) { fprintf( stdout, "ava(%d), rdn(%d) value mismatch\n", iAVA + 1, iRDN + 1 ); } } } ldap_dnfree( dn2 ); ldap_memfree( str2 ); } ldap_memfree( str ); } ldap_dnfree( dn ); /* note: dn is not freed */ return( 0 ); }
// if getP is true, we get the attributes by recursing once // (without getP set) in order to fill in *attrCount, then allocate // and fill in the *aAttributes. // // if getP is false, just fill in *attrCount and return // nsresult nsLDAPMessage::IterateAttributes(PRUint32 *aAttrCount, char** *aAttributes, bool getP) { BerElement *position; nsresult rv; if (!aAttrCount || !aAttributes ) { return NS_ERROR_INVALID_POINTER; } // if we've been called from GetAttributes, recurse once in order to // count the elements in this message. // if (getP) { *aAttributes = 0; *aAttrCount = 0; rv = IterateAttributes(aAttrCount, aAttributes, false); if (NS_FAILED(rv)) return rv; // create an array of the appropriate size // *aAttributes = static_cast<char **>(nsMemory::Alloc(*aAttrCount * sizeof(char *))); if (!*aAttributes) { return NS_ERROR_OUT_OF_MEMORY; } } // get the first attribute // char *attr = ldap_first_attribute(mConnectionHandle, mMsgHandle, &position); if (!attr) { return IterateAttrErrHandler(ldap_get_lderrno(mConnectionHandle, 0, 0), aAttrCount, aAttributes, position); } // if we're getting attributes, try and fill in the first field // if (getP) { (*aAttributes)[0] = nsCRT::strdup(attr); if (!(*aAttributes)[0]) { ldap_memfree(attr); nsMemory::Free(*aAttributes); return NS_ERROR_OUT_OF_MEMORY; } // note that we start counting again, in order to keep our place in // the array so that we can unwind gracefully and avoid leakage if // we hit an error as we're filling in the array // *aAttrCount = 1; } else { // otherwise just update the count // *aAttrCount = 1; } ldap_memfree(attr); while (1) { // get the next attribute // attr = ldap_next_attribute(mConnectionHandle, mMsgHandle, position); // check to see if there is an error, or if we're just done iterating // if (!attr) { // bail out if there's an error // PRInt32 lderrno = ldap_get_lderrno(mConnectionHandle, 0, 0); if (lderrno != LDAP_SUCCESS) { return IterateAttrErrHandler(lderrno, aAttrCount, aAttributes, position); } // otherwise, there are no more attributes; we're done with // the while loop // break; } else if (getP) { // if ldap_next_attribute did return successfully, and // we're supposed to fill in a value, do so. // (*aAttributes)[*aAttrCount] = nsCRT::strdup(attr); if (!(*aAttributes)[*aAttrCount]) { ldap_memfree(attr); return IterateAttrErrHandler(LDAP_NO_MEMORY, aAttrCount, aAttributes, position); } } ldap_memfree(attr); // we're done using *aAttrCount as a c-style array index (ie starting // at 0). update it to reflect the number of elements now in the array // *aAttrCount += 1; } // free the position pointer, if necessary // if (position) { ldap_ber_free(position, 0); } return NS_OK; }
int main( int argc, char **argv ) { char *rbuf = NULL, *rejbuf = NULL; FILE *rejfp; struct LDIFFP *ldiffp = NULL, ldifdummy = {0}; char *matched_msg, *error_msg; int rc, retval, ldifrc; int len; int i = 0, lmax = 0; unsigned long lineno, nextline = 0; LDAPControl c[1]; prog = lutil_progname( "ldapmodify", argc, argv ); /* strncmp instead of strcmp since NT binaries carry .exe extension */ ldapadd = ( strncasecmp( prog, "ldapadd", sizeof("ldapadd")-1 ) == 0 ); tool_init( ldapadd ? TOOL_ADD : TOOL_MODIFY ); tool_args( argc, argv ); if ( argc != optind ) usage(); if ( rejfile != NULL ) { if (( rejfp = fopen( rejfile, "w" )) == NULL ) { perror( rejfile ); retval = EXIT_FAILURE; goto fail; } } else { rejfp = NULL; } if ( infile != NULL ) { if (( ldiffp = ldif_open( infile, "r" )) == NULL ) { perror( infile ); retval = EXIT_FAILURE; goto fail; } } else { ldifdummy.fp = stdin; ldiffp = &ldifdummy; } if ( debug ) ldif_debug = debug; ld = tool_conn_setup( dont, 0 ); if ( !dont ) { tool_bind( ld ); } #ifdef LDAP_X_TXN if( txn ) { /* start transaction */ rc = ldap_txn_start_s( ld, NULL, NULL, &txn_id ); if( rc != LDAP_SUCCESS ) { tool_perror( "ldap_txn_start_s", rc, NULL, NULL, NULL, NULL ); if( txn > 1 ) { retval = EXIT_FAILURE; goto fail; } txn = 0; } } #endif if ( 0 #ifdef LDAP_X_TXN || txn #endif ) { #ifdef LDAP_X_TXN if( txn ) { c[i].ldctl_oid = LDAP_CONTROL_X_TXN_SPEC; c[i].ldctl_value = *txn_id; c[i].ldctl_iscritical = 1; i++; } #endif } tool_server_controls( ld, c, i ); rc = 0; retval = 0; lineno = 1; while (( rc == 0 || contoper ) && ( ldifrc = ldif_read_record( ldiffp, &nextline, &rbuf, &lmax )) > 0 ) { if ( rejfp ) { len = strlen( rbuf ); if (( rejbuf = (char *)ber_memalloc( len+1 )) == NULL ) { perror( "malloc" ); retval = EXIT_FAILURE; goto fail; } memcpy( rejbuf, rbuf, len+1 ); } rc = process_ldif_rec( rbuf, lineno ); lineno = nextline+1; if ( rc ) retval = rc; if ( rc && rejfp ) { fprintf(rejfp, _("# Error: %s (%d)"), ldap_err2string(rc), rc); matched_msg = NULL; ldap_get_option(ld, LDAP_OPT_MATCHED_DN, &matched_msg); if ( matched_msg != NULL ) { if ( *matched_msg != '\0' ) { fprintf( rejfp, _(", matched DN: %s"), matched_msg ); } ldap_memfree( matched_msg ); } error_msg = NULL; ldap_get_option(ld, LDAP_OPT_DIAGNOSTIC_MESSAGE, &error_msg); if ( error_msg != NULL ) { if ( *error_msg != '\0' ) { fprintf( rejfp, _(", additional info: %s"), error_msg ); } ldap_memfree( error_msg ); } fprintf( rejfp, "\n%s\n", rejbuf ); } if (rejfp) ber_memfree( rejbuf ); } ber_memfree( rbuf ); if ( ldifrc < 0 ) retval = LDAP_OTHER; #ifdef LDAP_X_TXN if( retval == 0 && txn ) { rc = ldap_set_option( ld, LDAP_OPT_SERVER_CONTROLS, NULL ); if ( rc != LDAP_OPT_SUCCESS ) { fprintf( stderr, "Could not unset controls for ldap_txn_end\n"); } /* create transaction */ rc = ldap_txn_end_s( ld, !txnabort, txn_id, NULL, NULL, NULL ); if( rc != LDAP_SUCCESS ) { tool_perror( "ldap_txn_end_s", rc, NULL, NULL, NULL, NULL ); retval = rc; } } #endif fail:; if ( rejfp != NULL ) { fclose( rejfp ); } if ( ldiffp != NULL && ldiffp != &ldifdummy ) { ldif_close( ldiffp ); } tool_exit( ld, retval ); }