/** * Make a compare for every new value we want to store in the * directory with the current values. Great tool for debugging * against invalid syntax in attributes * * \param ld AddressBook resource * \param dn dn for the entry * \param cnt Number of attributes to compare * \param mods LDAPMod structure */ void ldapsvr_compare_attr(LDAP *ld, gchar *dn, gint cnt, LDAPMod *mods[]) { int i, rc; #ifdef OPEN_LDAP_API_AT_LEAST_3000 struct berval val; #endif cm_return_if_fail(ld != NULL || dn != NULL || cnt >= 0 || mods != NULL); for (i = 0; i < cnt; i++) { gchar *value = g_strdup(mods[i]->mod_vals.modv_strvals[0]); if (!value || strcmp(value, "") == 0) value = g_strdup("thisisonlyadummy"); #ifdef OPEN_LDAP_API_AT_LEAST_3000 val.bv_val = value; val.bv_len = strlen(value); rc = ldap_compare_ext_s(ld, dn, mods[i]->mod_type, &val, NULL, NULL); #else /* This is deprecated as of OpenLDAP-2.3.0 */ rc = ldap_compare_s(ld, dn, mods[i]->mod_type, value); #endif g_printerr("ldap_compare for (%s:%s)\" failed[0x%x]: %s\n", mods[i]->mod_type, value, rc, ldaputil_get_error(ld)); g_free(value); } }
/* ARGSUSED */ int _ns_ldap_compare_ext_s(char *service, int flags, char *dn, char *attr, struct berval *bvalue, LDAPControl ** serverctrls, LDAPControl **clientctrls) { LDAP *ld = __s_api_getLDAPconn(flags); return (ldap_compare_ext_s(ld, dn, attr, bvalue, serverctrls, clientctrls)); }
/*********************************************************************** * ldap_compare_ext_sW (WLDAP32.@) * * Check if an attribute has a certain value (synchronous operation). * * PARAMS * ld [I] Pointer to an LDAP context. * dn [I] DN of entry to compare value for. * attr [I] Attribute to compare value for. * value [I] string encoded value to compare. * data [I] berval encoded value to compare. * serverctrls [I] Array of LDAP server controls. * clientctrls [I] Array of LDAP client controls. * * RETURNS * Success: LDAP_SUCCESS * Failure: An LDAP error code. * * NOTES * Set value to compare strings or data to compare binary values. If * both are non-NULL, data will be used. The serverctrls and clientctrls * parameters are optional and should be set to NULL if not used. */ ULONG CDECL ldap_compare_ext_sW( WLDAP32_LDAP *ld, PWCHAR dn, PWCHAR attr, PWCHAR value, struct WLDAP32_berval *data, PLDAPControlW *serverctrls, PLDAPControlW *clientctrls ) { ULONG ret = WLDAP32_LDAP_NOT_SUPPORTED; #ifdef HAVE_LDAP char *dnU = NULL, *attrU = NULL, *valueU = NULL; LDAPControl **serverctrlsU = NULL, **clientctrlsU = NULL; struct berval val = { 0, NULL }; ret = WLDAP32_LDAP_NO_MEMORY; TRACE( "(%p, %s, %s, %s, %p, %p, %p)\n", ld, debugstr_w(dn), debugstr_w(attr), debugstr_w(value), data, serverctrls, clientctrls ); if (!ld) return WLDAP32_LDAP_PARAM_ERROR; if (dn) { dnU = strWtoU( dn ); if (!dnU) goto exit; } if (attr) { attrU = strWtoU( attr ); if (!attrU) goto exit; } if (!data) { if (value) { valueU = strWtoU( value ); if (!valueU) goto exit; val.bv_len = strlen( valueU ); val.bv_val = valueU; } } if (serverctrls) { serverctrlsU = controlarrayWtoU( serverctrls ); if (!serverctrlsU) goto exit; } if (clientctrls) { clientctrlsU = controlarrayWtoU( clientctrls ); if (!clientctrlsU) goto exit; } ret = ldap_compare_ext_s( ld, dn ? dnU : "", attr ? attrU : "", data ? (struct berval *)data : &val, serverctrlsU, clientctrlsU ); exit: strfreeU( dnU ); strfreeU( attrU ); strfreeU( valueU ); controlarrayfreeU( serverctrlsU ); controlarrayfreeU( clientctrlsU ); #endif return ret; }
/** * Deside which kind of operation is required to handle * updating the specified attribute * * \param ld AddressBook resource * \param server Reference to server * \param dn dn for the entry * \param attr Attribute * \param value New value * \return int, return will be LDAP_MOD_ADD, LDAP_MOD_REPLACE, or LDAP_MOD_DELETE */ int ldapsvr_deside_operation(LDAP *ld, LdapServer *server, char *dn, char *attr, char *value) { int rc; gboolean dummy = FALSE; #ifdef OPEN_LDAP_API_AT_LEAST_3000 struct berval val; #endif cm_return_val_if_fail(ld != NULL || server != NULL || dn != NULL || attr != NULL, -1); if (value == NULL) return -1; /* value containing empty string cause invalid syntax. A bug in * the LDAP library? Therefore we add a dummy value */ if (strcmp(value,"") == 0) { value = g_strdup("thisisonlyadummy"); dummy = TRUE; } #ifdef OPEN_LDAP_API_AT_LEAST_3000 val.bv_val = value; val.bv_len = strlen(value); rc = ldap_compare_ext_s(ld, dn, attr, &val, NULL, NULL); #else /* This is deprecated as of OpenLDAP-2.3.0 */ rc = ldap_compare_s(ld, dn, attr, value); #endif debug_print("ldap_compare for (%s:%s)\" error_code[0x%x]: %s\n", attr, value, rc, ldaputil_get_error(ld)); switch (rc) { case LDAP_COMPARE_FALSE: if (dummy) return LDAP_MOD_DELETE; else return LDAP_MOD_REPLACE; case LDAP_COMPARE_TRUE: return -1; case LDAP_NO_SUCH_ATTRIBUTE: return LDAP_MOD_ADD; /* LDAP_INAPPROPRIATE_MATCHING needs extensive testing because I * am not aware off the condition causing this return value! */ case LDAP_INAPPROPRIATE_MATCHING: if (dummy) value = NULL; return ldapsvr_compare_manual_attr(ld, server, dn, attr, value); case LDAP_UNDEFINED_TYPE: return -2; case LDAP_INVALID_SYNTAX: return -2; default: return -2; } }
static void *compare_thread(char *id) { char dn[BUFSIZ], name[40], cmpval[40]; int rc, randval, opcount; struct berval bv; void *voidrc = (void *)0; printf("Starting compare_thread %s.\n", id); opcount = 0; tsd_setup(); for (;;) { randval = get_random_id(); sprintf(name, "%d", randval); sprintf(dn, "cn=%s, " BASE, name); sprintf(cmpval, "%d", randval + random() % 3); bv.bv_val = cmpval; bv.bv_len = strlen(cmpval); printf("Thread %s: Comparing cn in entry (%s) with %s\n", id, dn, cmpval); rc = ldap_compare_ext_s(ld, dn, "cn", &bv, NULL, NULL); switch (rc) { case LDAP_COMPARE_TRUE: printf("Thread %s: entry (%s) contains cn %s\n", id, dn, cmpval); break; case LDAP_COMPARE_FALSE: printf("Thread %s: entry (%s) doesn't contain cn %s\n", id, dn, cmpval); break; default: ldap_perror(ld, "ldap_compare_ext_s"); if (rc == LDAP_SERVER_DOWN) { perror("ldap_compare_ext_s"); voidrc = (void *)1; goto compare_cleanup_and_return; } } ++opcount; if (maxops != 0 && opcount >= maxops) { break; } } compare_cleanup_and_return: printf("Thread %s: attempted %d compare operations\n", id, opcount); set_ld_error(0, NULL, NULL, NULL); /* disposes of memory */ tsd_cleanup(); free(id); return voidrc; }
static int st_compare(SearchThread *st) { int rval; int compare_true; int correct_answer; int e; char *dn = NULL; char *uid = NULL; char *uidFalse = NULL; struct berval bvvalue = {0, NULL}; /* Decide what entry to modify, for this we need a table */ if (NULL == sdattable || sdt_getlen(sdattable) == 0) { fprintf(stderr, "-c option requires a DN file. Use -B file.\n"); return 0; } /* Get the target dn */ do { e = sdt_getrand(sdattable); } while (e < 0); dn = sdt_dn_get(sdattable, e); uid = sdt_uid_get(sdattable, e); compare_true = ( (rand() % 5) < 2 ); if (!compare_true) { /* modify the uid to make it fail the comparison */ uidFalse = PR_smprintf("@%s",uid); uid = uidFalse; } bvvalue.bv_val = uid; bvvalue.bv_len = uid ? strlen(uid) : 0; rval = ldap_compare_ext_s(st->ld, dn, "uid", &bvvalue, NULL, NULL); correct_answer = compare_true ? LDAP_COMPARE_TRUE : LDAP_COMPARE_FALSE; if (rval == correct_answer) { rval = LDAP_SUCCESS; } else { fprintf(stderr, "T%d: Failed to compare error=0x%x (%d)\n", st->id, rval, correct_answer); fprintf(stderr, "dn: %s, uid: %s\n", dn, uid); } if(uidFalse){ PR_smprintf_free(uidFalse); } return rval; }
int ldap_compare_s( LDAP *ld, LDAP_CONST char *dn, LDAP_CONST char *attr, LDAP_CONST char *value ) { struct berval bvalue; assert( value != NULL ); bvalue.bv_val = (char *) value; bvalue.bv_len = (value == NULL) ? 0 : strlen( value ); return ldap_compare_ext_s( ld, dn, attr, &bvalue, NULL, NULL ); }
static boolean ClientListExists(LDAP *ld) { struct berval bvalue; if( ld == NULL ) return FALSE; bvalue.bv_val = "clients"; bvalue.bv_len = strlen("clients"); if(ldap_compare_ext_s( ld, CLIENT_PATH, "ou", &bvalue, NULL, NULL ) == LDAP_COMPARE_TRUE ) return TRUE; else return FALSE; }
static boolean RootExists(LDAP *ld) { struct berval bvalue; if( ld == NULL ) return FALSE; bvalue.bv_val = MOVIE_STORE_NAME; bvalue.bv_len = strlen(MOVIE_STORE_NAME); if(ldap_compare_ext_s( ld, MOVIE_STORE_DN, "o", &bvalue, NULL, NULL ) == LDAP_COMPARE_TRUE ) return TRUE; else return FALSE; }
/*********************************************************************** * ldap_compare_sW (WLDAP32.@) * * Check if an attribute has a certain value (synchronous operation). * * PARAMS * ld [I] Pointer to an LDAP context. * dn [I] DN of entry to compare value for. * attr [I] Attribute to compare value for. * value [I] Value to compare. * * RETURNS * Success: LDAP_SUCCESS * Failure: An LDAP error code. */ ULONG CDECL ldap_compare_sW( WLDAP32_LDAP *ld, PWCHAR dn, PWCHAR attr, PWCHAR value ) { ULONG ret = WLDAP32_LDAP_NOT_SUPPORTED; #ifdef HAVE_LDAP char *dnU = NULL, *attrU = NULL, *valueU = NULL; struct berval val = { 0, NULL }; ret = WLDAP32_LDAP_NO_MEMORY; TRACE( "(%p, %s, %s, %s)\n", ld, debugstr_w(dn), debugstr_w(attr), debugstr_w(value) ); if (!ld) return WLDAP32_LDAP_PARAM_ERROR; if (dn) { dnU = strWtoU( dn ); if (!dnU) goto exit; } if (attr) { attrU = strWtoU( attr ); if (!attrU) goto exit; } if (value) { valueU = strWtoU( value ); if (!valueU) goto exit; val.bv_len = strlen( valueU ); val.bv_val = valueU; } ret = ldap_compare_ext_s( ld, dn ? dnU : "", attr ? attrU : "", &val, NULL, NULL ); exit: strfreeU( dnU ); strfreeU( attrU ); strfreeU( valueU ); #endif return ret; }
boolean PasswdIsValid(LDAP *ld, char *user, char *passwd) { struct berval bvalue; int rc; char *aux; const char *compAttribute = "userPassword"; if( ld == NULL || user == NULL || passwd == NULL ) return FALSE; bvalue.bv_val = passwd; bvalue.bv_len = strlen(passwd); aux = GetClientDN(user); rc = ldap_compare_ext_s( ld, aux, compAttribute, &bvalue, NULL, NULL ); free(aux); if( rc == LDAP_COMPARE_TRUE ) return TRUE; else return FALSE; }
boolean UserExist(LDAP *ld,char *user) { struct berval bvalue; int rc; char *aux; const char *compAttribute = CLIENT_KEY; if( ld == NULL || user == NULL ) return FALSE; bvalue.bv_val = user; bvalue.bv_len = strlen(user); aux = GetClientDN(user); rc = ldap_compare_ext_s( ld, aux, compAttribute, &bvalue, NULL, NULL ); free(aux); if( rc == LDAP_COMPARE_TRUE ) return TRUE; else return FALSE; }
static ngx_int_t ngx_http_auth_ldap_authenticate(ngx_http_request_t *r, ngx_http_auth_ldap_ctx_t *ctx, ngx_str_t *passwd, ngx_http_auth_ldap_loc_conf_t *conf) { LDAP *ld; LDAPMessage *searchResult; LDAPURLDesc *ludpp = conf->ludpp; int version = LDAP_VERSION3; struct berval bvalue; struct timeval timeOut = { 10, 0 }; int reqcert = LDAP_OPT_X_TLS_ALLOW; int rc; ngx_uint_t i; ngx_ldap_require_t *value; ngx_ldap_userinfo *uinfo; ngx_flag_t pass = NGX_CONF_UNSET; char *dn; u_char *p, *filter; if (conf->ludpp == NULL) { return NGX_HTTP_INTERNAL_SERVER_ERROR; } uinfo = ngx_http_auth_ldap_get_user_info(r); if (uinfo == NULL) { return NGX_HTTP_INTERNAL_SERVER_ERROR; } if (uinfo->password.len == 0) { return ngx_http_auth_ldap_set_realm(r, &conf->realm); } /// Set LDAP version to 3 and set connection timeout. ldap_set_option(NULL, LDAP_OPT_PROTOCOL_VERSION, &version); ldap_set_option(NULL, LDAP_OPT_NETWORK_TIMEOUT, &timeOut); rc = ldap_set_option(NULL, LDAP_OPT_X_TLS_REQUIRE_CERT, &reqcert); if (rc != LDAP_OPT_SUCCESS) { ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "LDAP: unable to set require cert option: %s", ldap_err2string(rc)); return NGX_HTTP_INTERNAL_SERVER_ERROR; } ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "LDAP: URL: %s", conf->url.data); rc = ldap_initialize(&ld, (const char*) conf->url.data); if (rc != LDAP_SUCCESS) { ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "LDAP: Session initializing failed: %d, %s, (%s)", rc, ldap_err2string(rc), (const char*) conf->url.data); return NGX_HTTP_INTERNAL_SERVER_ERROR; } ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "LDAP: Session initialized", NULL); /// Bind to the server rc = ldap_simple_bind_s(ld, (const char *) conf->bind_dn.data, (const char *) conf->bind_dn_passwd.data); if (rc != LDAP_SUCCESS) { ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "LDAP: ldap_simple_bind_s error: %d, %s", rc, ldap_err2string(rc)); ldap_unbind_s(ld); return NGX_HTTP_INTERNAL_SERVER_ERROR; } ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "LDAP: Bind successful", NULL); /// Create filter for search users by uid filter = ngx_pcalloc( r->pool, (ludpp->lud_filter != NULL ? ngx_strlen(ludpp->lud_filter) : ngx_strlen("(objectClass=*)")) + ngx_strlen("(&(=))") + ngx_strlen(ludpp->lud_attrs[0]) + uinfo->username.len + 1); p = ngx_sprintf(filter, "(&%s(%s=%s))", ludpp->lud_filter != NULL ? ludpp->lud_filter : "(objectClass=*)", ludpp->lud_attrs[0], uinfo->username.data); *p = 0; ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "LDAP: filter %s", (const char*) filter); /// Search the directory rc = ldap_search_ext_s(ld, ludpp->lud_dn, ludpp->lud_scope, (const char*) filter, NULL, 0, NULL, NULL, &timeOut, 0, &searchResult); if (rc != LDAP_SUCCESS) { ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "LDAP: ldap_search_ext_s: %d, %s", rc, ldap_err2string(rc)); ldap_msgfree(searchResult); ldap_unbind_s(ld); return NGX_HTTP_INTERNAL_SERVER_ERROR; } if (ldap_count_entries(ld, searchResult) > 0) { dn = ldap_get_dn(ld, searchResult); if (dn != NULL) { ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "LDAP: result DN %s", dn); /// Check require user if (conf->require_user != NULL) { value = conf->require_user->elts; for (i = 0; i < conf->require_user->nelts; i++) { ngx_str_t val; if (value[i].lengths == NULL) { val = value[i].value; } else { if (ngx_http_script_run(r, &val, value[i].lengths->elts, 0, value[i].values->elts) == NULL) { ldap_memfree(dn); ldap_msgfree(searchResult); ldap_unbind_s(ld); return NGX_HTTP_INTERNAL_SERVER_ERROR; } val.data[val.len] = '\0'; } ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "LDAP: compare with: %s", val.data); if (ngx_strncmp(val.data, dn, val.len) == 0) { pass = 1; if (conf->satisfy_all == 0) { break; } } else { if (conf->satisfy_all == 1) { ldap_memfree(dn); ldap_msgfree(searchResult); ldap_unbind_s(ld); return ngx_http_auth_ldap_set_realm(r, &conf->realm); } } } } /// Check require group if (conf->require_group != NULL) { if (conf->group_attribute_dn == 1) { bvalue.bv_val = dn; bvalue.bv_len = ngx_strlen(dn); } else { bvalue.bv_val = (char*) uinfo->username.data; bvalue.bv_len = uinfo->username.len; } value = conf->require_group->elts; for (i = 0; i < conf->require_group->nelts; i++) { ngx_str_t val; if (value[i].lengths == NULL) { val = value[i].value; } else { if (ngx_http_script_run(r, &val, value[i].lengths->elts, 0, value[i].values->elts) == NULL) { ldap_memfree(dn); ldap_msgfree(searchResult); ldap_unbind_s(ld); return NGX_HTTP_INTERNAL_SERVER_ERROR; } val.data[val.len] = '\0'; } ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "LDAP: group compare with: %s", val.data); rc = ldap_compare_ext_s(ld, (const char*) val.data, (const char*) conf->group_attribute.data, &bvalue, NULL, NULL); /*if (rc != LDAP_COMPARE_TRUE && rc != LDAP_COMPARE_FALSE && rc != LDAP_NO_SUCH_ATTRIBUTE ) { ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "LDAP: ldap_search_ext_s: %d, %s", rc, ldap_err2string(rc)); ldap_memfree(dn); ldap_msgfree(searchResult); ldap_unbind_s(ld); return NGX_HTTP_INTERNAL_SERVER_ERROR; }*/ if (rc == LDAP_COMPARE_TRUE) { pass = 1; if (conf->satisfy_all == 0) { break; } } else { if (conf->satisfy_all == 1) { pass = 0; break; } } } } /// Check valid user if ( pass != 0 || (conf->require_valid_user == 1 && conf->satisfy_all == 0 && pass == 0)) { /// Bind user to the server rc = ldap_simple_bind_s(ld, dn, (const char *) uinfo->password.data); if (rc != LDAP_SUCCESS) { ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "LDAP: ldap_simple_bind_s error: %d, %s", rc, ldap_err2string(rc)); pass = 0; } else { ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "LDAP: User bind successful", NULL); if (conf->require_valid_user == 1) pass = 1; } } } ldap_memfree(dn); } ldap_msgfree(searchResult); ldap_unbind_s(ld); if (pass == 1) { return NGX_OK; } return ngx_http_auth_ldap_set_realm(r, &conf->realm); }