📄 util_ldap.c
字号:
l->bound = 0; util_ldap_strdup((char**)&(l->binddn), binddn); util_ldap_strdup((char**)&(l->bindpw), bindpw); break; }#if APR_HAS_THREADS /* If this connection didn't match the criteria, then we * need to unlock the mutex so it is available to be reused. */ apr_thread_mutex_unlock(l->lock); }#endif p = l; } }/* artificially disable cache *//* l = NULL; */ /* If no connection what found after the second search, we * must create one. */ if (!l) { /* * Add the new connection entry to the linked list. Note that we * don't actually establish an LDAP connection yet; that happens * the first time authentication is requested. */ /* create the details to the pool in st */ l = apr_pcalloc(st->pool, sizeof(util_ldap_connection_t));#if APR_HAS_THREADS apr_thread_mutex_create(&l->lock, APR_THREAD_MUTEX_DEFAULT, st->pool); apr_thread_mutex_lock(l->lock);#endif l->pool = st->pool; l->bound = 0; l->host = apr_pstrdup(st->pool, host); l->port = port; l->deref = deref; util_ldap_strdup((char**)&(l->binddn), binddn); util_ldap_strdup((char**)&(l->bindpw), bindpw); l->secure = secure; /* add the cleanup to the pool */ apr_pool_cleanup_register(l->pool, l, util_ldap_connection_cleanup, apr_pool_cleanup_null); if (p) { p->next = l; } else { st->connections = l; } }#if APR_HAS_THREADS apr_thread_mutex_unlock(st->mutex);#endif return l;}/* ------------------------------------------------------------------ *//* * Compares two DNs to see if they're equal. The only way to do this correctly is to * search for the dn and then do ldap_get_dn() on the result. This should match the * initial dn, since it would have been also retrieved with ldap_get_dn(). This is * expensive, so if the configuration value compare_dn_on_server is * false, just does an ordinary strcmp. * * The lock for the ldap cache should already be acquired. */LDAP_DECLARE(int) util_ldap_cache_comparedn(request_rec *r, util_ldap_connection_t *ldc, const char *url, const char *dn, const char *reqdn, int compare_dn_on_server){ int result = 0; util_url_node_t *curl; util_url_node_t curnode; util_dn_compare_node_t *node; util_dn_compare_node_t newnode; int failures = 0; LDAPMessage *res, *entry; char *searchdn; util_ldap_state_t *st = (util_ldap_state_t *)ap_get_module_config(r->server->module_config, &ldap_module); /* get cache entry (or create one) */ LDAP_CACHE_LOCK(); curnode.url = url; curl = util_ald_cache_fetch(st->util_ldap_cache, &curnode); if (curl == NULL) { curl = util_ald_create_caches(st, url); } LDAP_CACHE_UNLOCK(); /* a simple compare? */ if (!compare_dn_on_server) { /* unlock this read lock */ if (strcmp(dn, reqdn)) { ldc->reason = "DN Comparison FALSE (direct strcmp())"; return LDAP_COMPARE_FALSE; } else { ldc->reason = "DN Comparison TRUE (direct strcmp())"; return LDAP_COMPARE_TRUE; } } if (curl) { /* no - it's a server side compare */ LDAP_CACHE_LOCK(); /* is it in the compare cache? */ newnode.reqdn = (char *)reqdn; node = util_ald_cache_fetch(curl->dn_compare_cache, &newnode); if (node != NULL) { /* If it's in the cache, it's good */ /* unlock this read lock */ LDAP_CACHE_UNLOCK(); ldc->reason = "DN Comparison TRUE (cached)"; return LDAP_COMPARE_TRUE; } /* unlock this read lock */ LDAP_CACHE_UNLOCK(); }start_over: if (failures++ > 10) { /* too many failures */ return result; } /* make a server connection */ if (LDAP_SUCCESS != (result = util_ldap_connection_open(r, ldc))) { /* connect to server failed */ return result; } /* search for reqdn */ if ((result = ldap_search_ext_s(ldc->ldap, const_cast(reqdn), LDAP_SCOPE_BASE, "(objectclass=*)", NULL, 1, NULL, NULL, NULL, -1, &res)) == LDAP_SERVER_DOWN) { ldc->reason = "DN Comparison ldap_search_ext_s() failed with server down"; util_ldap_connection_unbind(ldc); goto start_over; } if (result != LDAP_SUCCESS) { /* search for reqdn failed - no match */ ldc->reason = "DN Comparison ldap_search_ext_s() failed"; return result; } entry = ldap_first_entry(ldc->ldap, res); searchdn = ldap_get_dn(ldc->ldap, entry); ldap_msgfree(res); if (strcmp(dn, searchdn) != 0) { /* compare unsuccessful */ ldc->reason = "DN Comparison FALSE (checked on server)"; result = LDAP_COMPARE_FALSE; } else { if (curl) { /* compare successful - add to the compare cache */ LDAP_CACHE_LOCK(); newnode.reqdn = (char *)reqdn; newnode.dn = (char *)dn; node = util_ald_cache_fetch(curl->dn_compare_cache, &newnode); if ((node == NULL) || (strcmp(reqdn, node->reqdn) != 0) || (strcmp(dn, node->dn) != 0)) { util_ald_cache_insert(curl->dn_compare_cache, &newnode); } LDAP_CACHE_UNLOCK(); } ldc->reason = "DN Comparison TRUE (checked on server)"; result = LDAP_COMPARE_TRUE; } ldap_memfree(searchdn); return result;}/* * Does an generic ldap_compare operation. It accepts a cache that it will use * to lookup the compare in the cache. We cache two kinds of compares * (require group compares) and (require user compares). Each compare has a different * cache node: require group includes the DN; require user does not because the * require user cache is owned by the * */LDAP_DECLARE(int) util_ldap_cache_compare(request_rec *r, util_ldap_connection_t *ldc, const char *url, const char *dn, const char *attrib, const char *value){ int result = 0; util_url_node_t *curl; util_url_node_t curnode; util_compare_node_t *compare_nodep; util_compare_node_t the_compare_node; apr_time_t curtime = 0; /* silence gcc -Wall */ int failures = 0; util_ldap_state_t *st = (util_ldap_state_t *)ap_get_module_config(r->server->module_config, &ldap_module); /* get cache entry (or create one) */ LDAP_CACHE_LOCK(); curnode.url = url; curl = util_ald_cache_fetch(st->util_ldap_cache, &curnode); if (curl == NULL) { curl = util_ald_create_caches(st, url); } LDAP_CACHE_UNLOCK(); if (curl) { /* make a comparison to the cache */ LDAP_CACHE_LOCK(); curtime = apr_time_now(); the_compare_node.dn = (char *)dn; the_compare_node.attrib = (char *)attrib; the_compare_node.value = (char *)value; the_compare_node.result = 0; compare_nodep = util_ald_cache_fetch(curl->compare_cache, &the_compare_node); if (compare_nodep != NULL) { /* found it... */ if (curtime - compare_nodep->lastcompare > st->compare_cache_ttl) { /* ...but it is too old */ util_ald_cache_remove(curl->compare_cache, compare_nodep); } else { /* ...and it is good */ /* unlock this read lock */ LDAP_CACHE_UNLOCK(); if (LDAP_COMPARE_TRUE == compare_nodep->result) { ldc->reason = "Comparison true (cached)"; return compare_nodep->result; } else if (LDAP_COMPARE_FALSE == compare_nodep->result) { ldc->reason = "Comparison false (cached)"; return compare_nodep->result; } else if (LDAP_NO_SUCH_ATTRIBUTE == compare_nodep->result) { ldc->reason = "Comparison no such attribute (cached)"; return compare_nodep->result; } else { ldc->reason = "Comparison undefined (cached)"; return compare_nodep->result; } } } /* unlock this read lock */ LDAP_CACHE_UNLOCK(); }start_over: if (failures++ > 10) { /* too many failures */ return result; } if (LDAP_SUCCESS != (result = util_ldap_connection_open(r, ldc))) { /* connect failed */ return result; } if ((result = ldap_compare_s(ldc->ldap, const_cast(dn), const_cast(attrib), const_cast(value))) == LDAP_SERVER_DOWN) { /* connection failed - try again */ ldc->reason = "ldap_compare_s() failed with server down"; util_ldap_connection_unbind(ldc); goto start_over; } ldc->reason = "Comparison complete"; if ((LDAP_COMPARE_TRUE == result) || (LDAP_COMPARE_FALSE == result) || (LDAP_NO_SUCH_ATTRIBUTE == result)) { if (curl) { /* compare completed; caching result */ LDAP_CACHE_LOCK(); the_compare_node.lastcompare = curtime; the_compare_node.result = result; /* If the node doesn't exist then insert it, otherwise just update it with the last results */ compare_nodep = util_ald_cache_fetch(curl->compare_cache, &the_compare_node); if ((compare_nodep == NULL) || (strcmp(the_compare_node.dn, compare_nodep->dn) != 0) || (strcmp(the_compare_node.attrib, compare_nodep->attrib) != 0) || (strcmp(the_compare_node.value, compare_nodep->value) != 0)) { util_ald_cache_insert(curl->compare_cache, &the_compare_node); } else { compare_nodep->lastcompare = curtime; compare_nodep->result = result; } LDAP_CACHE_UNLOCK(); } if (LDAP_COMPARE_TRUE == result) { ldc->reason = "Comparison true (adding to cache)"; return LDAP_COMPARE_TRUE; } else if (LDAP_COMPARE_FALSE == result) { ldc->reason = "Comparison false (adding to cache)"; return LDAP_COMPARE_FALSE; } else { ldc->reason = "Comparison no such attribute (adding to cache)"; return LDAP_NO_SUCH_ATTRIBUTE; } } return result;}LDAP_DECLARE(int) util_ldap_cache_checkuserid(request_rec *r, util_ldap_connection_t *ldc, const char *url, const char *basedn, int scope, char **attrs, const char *filter, const char *bindpw, const char **binddn, const char ***retvals){ const char **vals = NULL; int numvals = 0; int result = 0; LDAPMessage *res, *entry; char *dn; int count; int failures = 0; util_url_node_t *curl; /* Cached URL node */ util_url_node_t curnode; util_search_node_t *search_nodep; /* Cached search node */ util_search_node_t the_search_node; apr_time_t curtime; util_ldap_state_t *st = (util_ldap_state_t *)ap_get_module_config(r->server->module_config, &ldap_module); /* Get the cache node for this url */ LDAP_CACHE_LOCK(); curnode.url = url; curl = (util_url_node_t *)util_ald_cache_fetch(st->util_ldap_cache, &curnode); if (curl == NULL) { curl = util_ald_create_caches(st, url); } LDAP_CACHE_UNLOCK(); if (curl) { LDAP_CACHE_LOCK(); the_search_node.username = filter; search_nodep = util_ald_cache_fetch(curl->search_cache, &the_search_node); if (search_nodep != NULL) { /* found entry in search cache... */ curtime = apr_time_now(); /* * Remove this item from the cache if its expired. * If the sent password doesn't match the stored password, * the entry will be removed and readded later if the * credentials pass authentication. */ if ((curtime - search_nodep->lastbind) > st->search_cache_ttl) { /* ...but entry is too old */ util_ald_cache_remove(curl->search_cache, search_nodep); } else if ((search_nodep->bindpw) && (search_nodep->bindpw[0] != '\0') && (strcmp(search_nodep->bindpw, bindpw) == 0)) { /* ...and entry is valid */ *binddn = search_nodep->dn; *retvals = search_nodep->vals; LDAP_CACHE_UNLOCK(); ldc->reason = "Authentication successful (cached)"; return LDAP_SUCCESS; } } /* unlock this read lock */ LDAP_CACHE_UNLOCK(); } /* * At this point, there is no valid cached search, so lets do the search. */ /* * If any LDAP operation fails due to LDAP_SERVER_DOWN, control returns here. */start_over: if (failures++ > 10) { return result; } if (LDAP_SUCCESS != (result = util_ldap_connection_open(r, ldc))) { return result; } /* try do the search */ if ((result = ldap_search_ext_s(ldc->ldap, const_cast(basedn), scope, const_cast(filter), attrs, 0, NULL, NULL, NULL, -1, &res)) == LDAP_SERVER_DOWN) { ldc->reason = "ldap_search_ext_s() for user failed with server down"; util_ldap_connection_unbind(ldc); goto start_over; } /* if there is an error (including LDAP_NO_SUCH_OBJECT) return now */ if (result != LDAP_SUCCESS) { ldc->reason = "ldap_search_ext_s() for user failed"; return result; } /* * We should have found exactly one entry; to find a different * number is an error. */ count = ldap_count_entries(ldc->ldap, res); if (count != 1) { if (count == 0 ) ldc->reason = "User not found"; else ldc->reason = "User is not unique (search found two or more matches)"; ldap_msgfree(res); return LDAP_NO_SUCH_OBJECT; } entry = ldap_first_entry(ldc->ldap, res);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -