util_ldap.c revision d5cff0d8e871bf2528aadd8736fb50dc044b1e6d
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding/* Copyright 2001-2004 The Apache Software Foundation
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fielding * Licensed under the Apache License, Version 2.0 (the "License");
bc8fd1b0b1afdf89b8d28eefa8cd74e26ba97986fielding * you may not use this file except in compliance with the License.
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fielding * You may obtain a copy of the License at
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding * Unless required by applicable law or agreed to in writing, software
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding * distributed under the License is distributed on an "AS IS" BASIS,
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fielding * See the License for the specific language governing permissions and
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding * limitations under the License.
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding * util_ldap.c: LDAP things
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fielding * Original code from auth_ldap module for Apache v1.3:
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fielding * Copyright 1998, 1999 Enbridge Pipelines Inc.
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fielding * Copyright 1999-2001 Dave Carrigan
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fielding#error mod_ldap requires APR-util to have LDAP support built in
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding /* defines for certificate file types
0f081398cf0eef8cc7c66a535d450110a92dc8aefieldingvoid *util_ldap_create_config(apr_pool_t *p, server_rec *s);
3568de757bac0b47256647504c186d17ca272f85rbb * Some definitions to help between various versions of apache.
3568de757bac0b47256647504c186d17ca272f85rbb#define DOCTYPE_HTML_2_0 "<!DOCTYPE HTML PUBLIC \"-//IETF//" \
3568de757bac0b47256647504c186d17ca272f85rbb "DTD HTML 2.0//EN\">\n"
3568de757bac0b47256647504c186d17ca272f85rbb#define DOCTYPE_HTML_3_2 "<!DOCTYPE HTML PUBLIC \"-//W3C//" \
3568de757bac0b47256647504c186d17ca272f85rbb "DTD HTML 3.2 Final//EN\">\n"
3568de757bac0b47256647504c186d17ca272f85rbb#define DOCTYPE_HTML_4_0S "<!DOCTYPE HTML PUBLIC \"-//W3C//" \
3568de757bac0b47256647504c186d17ca272f85rbb "DTD HTML 4.0//EN\"\n" \
3568de757bac0b47256647504c186d17ca272f85rbb#define DOCTYPE_HTML_4_0T "<!DOCTYPE HTML PUBLIC \"-//W3C//" \
3568de757bac0b47256647504c186d17ca272f85rbb "DTD HTML 4.0 Transitional//EN\"\n" \
3568de757bac0b47256647504c186d17ca272f85rbb#define DOCTYPE_HTML_4_0F "<!DOCTYPE HTML PUBLIC \"-//W3C//" \
3568de757bac0b47256647504c186d17ca272f85rbb "DTD HTML 4.0 Frameset//EN\"\n" \
0f081398cf0eef8cc7c66a535d450110a92dc8aefieldingstatic void util_ldap_strdup (char **str, const char *newstr)
3568de757bac0b47256647504c186d17ca272f85rbb * Status Handler
3568de757bac0b47256647504c186d17ca272f85rbb * --------------
3568de757bac0b47256647504c186d17ca272f85rbb * This handler generates a status page about the current performance of
3568de757bac0b47256647504c186d17ca272f85rbb * the LDAP cache. It is enabled as follows:
3568de757bac0b47256647504c186d17ca272f85rbb * <Location /ldap-status>
3568de757bac0b47256647504c186d17ca272f85rbb * SetHandler ldap-status
3568de757bac0b47256647504c186d17ca272f85rbb * </Location>
28c170ac8e99644de58cad454c6e0f9b4b359be6jerenkrantz util_ldap_state_t *st = (util_ldap_state_t *)ap_get_module_config(r->server->module_config, &ldap_module);
cd8f8c995d415473f3bfb0b329b2450f2a722c3atrawick "<html><head><title>LDAP Cache Information</title></head>\n", r);
3568de757bac0b47256647504c186d17ca272f85rbb ap_rputs("<body bgcolor='#ffffff'><h1 align=center>LDAP Cache Information</h1>\n", r);
3568de757bac0b47256647504c186d17ca272f85rbb/* ------------------------------------------------------------------ */
3568de757bac0b47256647504c186d17ca272f85rbb * Closes an LDAP connection by unlocking it. The next time
3568de757bac0b47256647504c186d17ca272f85rbb * util_ldap_connection_find() is called this connection will be
3568de757bac0b47256647504c186d17ca272f85rbb * available for reuse.
0f081398cf0eef8cc7c66a535d450110a92dc8aefieldingLDAP_DECLARE(void) util_ldap_connection_close(util_ldap_connection_t *ldc)
3568de757bac0b47256647504c186d17ca272f85rbb * QUESTION:
3568de757bac0b47256647504c186d17ca272f85rbb * Is it safe leaving bound connections floating around between the
41634f717c623556a16b27b25d7d909a66fe20f8wrowe * different modules? Keeping the user bound is a performance boost,
3568de757bac0b47256647504c186d17ca272f85rbb * but it is also a potential security problem - maybe.
28c170ac8e99644de58cad454c6e0f9b4b359be6jerenkrantz * For now we unbind the user when we finish with a connection, but
3568de757bac0b47256647504c186d17ca272f85rbb * we don't have to...
28c170ac8e99644de58cad454c6e0f9b4b359be6jerenkrantz /* mark our connection as available for reuse */
3568de757bac0b47256647504c186d17ca272f85rbb * Destroys an LDAP connection by unbinding and closing the connection to
28c170ac8e99644de58cad454c6e0f9b4b359be6jerenkrantz * the LDAP server. It is used to bring the connection back to a known
3568de757bac0b47256647504c186d17ca272f85rbb * state after an error, and during pool cleanup.
0f081398cf0eef8cc7c66a535d450110a92dc8aefieldingLDAP_DECLARE_NONSTD(apr_status_t) util_ldap_connection_unbind(void *param)
28c170ac8e99644de58cad454c6e0f9b4b359be6jerenkrantz * Clean up an LDAP connection by unbinding and unlocking the connection.
28c170ac8e99644de58cad454c6e0f9b4b359be6jerenkrantz * This function is registered with the pool cleanup function - causing
3568de757bac0b47256647504c186d17ca272f85rbb * the LDAP connections to be shut down cleanly on graceful restart.
28c170ac8e99644de58cad454c6e0f9b4b359be6jerenkrantzLDAP_DECLARE_NONSTD(apr_status_t) util_ldap_connection_cleanup(void *param)
3568de757bac0b47256647504c186d17ca272f85rbb /* unbind and disconnect from the LDAP server */
28c170ac8e99644de58cad454c6e0f9b4b359be6jerenkrantz /* free the username and password */
3568de757bac0b47256647504c186d17ca272f85rbb /* unlock this entry */
3568de757bac0b47256647504c186d17ca272f85rbb * Connect to the LDAP server and binds. Does not connect if already
3568de757bac0b47256647504c186d17ca272f85rbb * connected (i.e. ldc->ldap is non-NULL.) Does not bind if already bound.
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding * Returns LDAP_SUCCESS on success; and an error code on failure
3568de757bac0b47256647504c186d17ca272f85rbbLDAP_DECLARE(int) util_ldap_connection_open(request_rec *r,
41634f717c623556a16b27b25d7d909a66fe20f8wrowe /* sanity check for NULL */
3568de757bac0b47256647504c186d17ca272f85rbb return -1;
3568de757bac0b47256647504c186d17ca272f85rbb /* If the connection is already bound, return
64c351fd973428b5bb4c28e983fa86875ea4e60fdougm ldc->reason = "LDAP: connection open successful (already bound)";
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding /* create the ldap session handle
ca53a74f4012a45cbad48e940eddf27d866981f9dougm /* To work around a bug in the Netware SDK, if no client certs are
ca53a74f4012a45cbad48e940eddf27d866981f9dougm * present (Netware client certs are global), we apply the SSL
6653a33e820463abd4f81915b7a1eba0f602e200brianp * settings immediately. If client certs are present, we defer the
6653a33e820463abd4f81915b7a1eba0f602e200brianp * setting of SSL on the connection until later.
6653a33e820463abd4f81915b7a1eba0f602e200brianp /* Since the host will include a port if the default port is not used,
6653a33e820463abd4f81915b7a1eba0f602e200brianp * always specify the default ports for the port parameter. This will allow
6653a33e820463abd4f81915b7a1eba0f602e200brianp * a host string that contains multiple hosts the ability to mix some
6653a33e820463abd4f81915b7a1eba0f602e200brianp * hosts with ports and some without. All hosts which do not specify
6653a33e820463abd4f81915b7a1eba0f602e200brianp * a port will use the default port.
6653a33e820463abd4f81915b7a1eba0f602e200brianp APR_LDAP_SSL == ldc->secure ? LDAPS_PORT : LDAP_PORT,
6653a33e820463abd4f81915b7a1eba0f602e200brianp apr_is_empty_array(ldc->client_certs) ? ldc->secure : APR_LDAP_NONE,
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding /* set client certificates */
3568de757bac0b47256647504c186d17ca272f85rbb apr_ldap_set_option(ldc->pool, ldc->ldap, APR_LDAP_OPT_TLS_CERT,
28c170ac8e99644de58cad454c6e0f9b4b359be6jerenkrantz /* switch on SSL/TLS */
c0659e61002e9d6ff77b2dca72540e0af1b2ca64stoddard /* Set the alias dereferencing option */
c0659e61002e9d6ff77b2dca72540e0af1b2ca64stoddard ldap_set_option(ldc->ldap, LDAP_OPT_DEREF, &(ldc->deref));
c0659e61002e9d6ff77b2dca72540e0af1b2ca64stoddard /* always default to LDAP V3 */
e0d102c882a7ed34d3eec24b36da49f097066a36stoddard ldap_set_option(ldc->ldap, LDAP_OPT_PROTOCOL_VERSION, &version);
28c170ac8e99644de58cad454c6e0f9b4b359be6jerenkrantz /* loop trying to bind up to 10 times if LDAP_SERVER_DOWN error is
c0659e61002e9d6ff77b2dca72540e0af1b2ca64stoddard * returned. Break out of the loop on Success or any other error.
3568de757bac0b47256647504c186d17ca272f85rbb * NOTE: Looping is probably not a great idea. If the server isn't
3568de757bac0b47256647504c186d17ca272f85rbb * responding the chances it will respond after a few tries are poor.
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding * However, the original code looped and it only happens on
c0659e61002e9d6ff77b2dca72540e0af1b2ca64stoddard * the error condition.
64c351fd973428b5bb4c28e983fa86875ea4e60fdougm /* free the handle if there was an error
64c351fd973428b5bb4c28e983fa86875ea4e60fdougm * Compare client certificate arrays.
64c351fd973428b5bb4c28e983fa86875ea4e60fdougm * Returns 1 on compare failure, 0 otherwise.
ad83978f20c7d1a4323059d9af122e56fcd353bdstoddardint compare_client_certs(apr_array_header_t *srcs, apr_array_header_t *dests) {
c0659e61002e9d6ff77b2dca72540e0af1b2ca64stoddard /* arrays both NULL? if so, then equal */
c0659e61002e9d6ff77b2dca72540e0af1b2ca64stoddard /* arrays different length or either NULL? If so, then not equal */
3568de757bac0b47256647504c186d17ca272f85rbb if (srcs == NULL || dests == NULL || srcs->nelts != dests->nelts) {
3568de757bac0b47256647504c186d17ca272f85rbb /* run an actual comparison */
74fd6d9aeadb9022086259c5c1ae00bc0dda9c9astoddard src = (struct apr_ldap_opt_tls_cert_t *)srcs->elts;
28c170ac8e99644de58cad454c6e0f9b4b359be6jerenkrantz dest = (struct apr_ldap_opt_tls_cert_t *)dests->elts;
c0659e61002e9d6ff77b2dca72540e0af1b2ca64stoddard /* if we got here, the cert arrays were identical */
28c170ac8e99644de58cad454c6e0f9b4b359be6jerenkrantz * Find an existing ldap connection struct that matches the
c0659e61002e9d6ff77b2dca72540e0af1b2ca64stoddard * provided ldap connection parameters.
28c170ac8e99644de58cad454c6e0f9b4b359be6jerenkrantz * If not found in the cache, a new ldc structure will be allocated from st->pool
28c170ac8e99644de58cad454c6e0f9b4b359be6jerenkrantz * and returned to the caller. If found in the cache, a pointer to the existing
c0659e61002e9d6ff77b2dca72540e0af1b2ca64stoddard * ldc structure will be returned.
3568de757bac0b47256647504c186d17ca272f85rbb struct util_ldap_connection_t *l, *p; /* To traverse the linked list */
28c170ac8e99644de58cad454c6e0f9b4b359be6jerenkrantz (util_ldap_state_t *)ap_get_module_config(r->server->module_config,
28c170ac8e99644de58cad454c6e0f9b4b359be6jerenkrantz /* mutex lock this function */
28c170ac8e99644de58cad454c6e0f9b4b359be6jerenkrantz apr_thread_mutex_create(&st->mutex, APR_THREAD_MUTEX_DEFAULT, st->pool);
c0659e61002e9d6ff77b2dca72540e0af1b2ca64stoddard /* Search for an exact connection match in the list that is not
c0659e61002e9d6ff77b2dca72540e0af1b2ca64stoddard * being used.
c0659e61002e9d6ff77b2dca72540e0af1b2ca64stoddard if (APR_SUCCESS == apr_thread_mutex_trylock(l->lock)) {
3568de757bac0b47256647504c186d17ca272f85rbb if ((l->port == port) && (strcmp(l->host, host) == 0) &&
c0659e61002e9d6ff77b2dca72540e0af1b2ca64stoddard ((!l->binddn && !binddn) || (l->binddn && binddn && !strcmp(l->binddn, binddn))) &&
c0659e61002e9d6ff77b2dca72540e0af1b2ca64stoddard ((!l->bindpw && !bindpw) || (l->bindpw && bindpw && !strcmp(l->bindpw, bindpw))) &&
c0659e61002e9d6ff77b2dca72540e0af1b2ca64stoddard !compare_client_certs(st->client_certs, l->client_certs)) {
3568de757bac0b47256647504c186d17ca272f85rbb /* If this connection didn't match the criteria, then we
ad83978f20c7d1a4323059d9af122e56fcd353bdstoddard * need to unlock the mutex so it is available to be reused.
3568de757bac0b47256647504c186d17ca272f85rbb /* If nothing found, search again, but we don't care about the
3568de757bac0b47256647504c186d17ca272f85rbb * binddn and bindpw this time.
c0659e61002e9d6ff77b2dca72540e0af1b2ca64stoddard if (APR_SUCCESS == apr_thread_mutex_trylock(l->lock)) {
c0659e61002e9d6ff77b2dca72540e0af1b2ca64stoddard if ((l->port == port) && (strcmp(l->host, host) == 0) &&
3568de757bac0b47256647504c186d17ca272f85rbb !compare_client_certs(st->client_certs, l->client_certs)) {
28c170ac8e99644de58cad454c6e0f9b4b359be6jerenkrantz /* the bind credentials have changed */
28c170ac8e99644de58cad454c6e0f9b4b359be6jerenkrantz /* If this connection didn't match the criteria, then we
3568de757bac0b47256647504c186d17ca272f85rbb * need to unlock the mutex so it is available to be reused.
c0659e61002e9d6ff77b2dca72540e0af1b2ca64stoddard/* artificially disable cache */
3568de757bac0b47256647504c186d17ca272f85rbb/* l = NULL; */
3568de757bac0b47256647504c186d17ca272f85rbb /* If no connection what found after the second search, we
cd8f8c995d415473f3bfb0b329b2450f2a722c3atrawick * must create one.
28c170ac8e99644de58cad454c6e0f9b4b359be6jerenkrantz * Add the new connection entry to the linked list. Note that we
c0659e61002e9d6ff77b2dca72540e0af1b2ca64stoddard * don't actually establish an LDAP connection yet; that happens
beb70d51e435dc36c56a72b6cd83556c04db9283wrowe * the first time authentication is requested.
3568de757bac0b47256647504c186d17ca272f85rbb /* create the details to the pool in st */
3568de757bac0b47256647504c186d17ca272f85rbb l = apr_pcalloc(st->pool, sizeof(util_ldap_connection_t));
3568de757bac0b47256647504c186d17ca272f85rbb apr_thread_mutex_create(&l->lock, APR_THREAD_MUTEX_DEFAULT, st->pool);
c0659e61002e9d6ff77b2dca72540e0af1b2ca64stoddard /* The security mode after parsing the URL will always be either
1ec8bd0373f11c07688ec9afbbf778cf78a0bc52wrowe * APR_LDAP_NONE (ldap://) or APR_LDAP_SSL (ldaps://).
c0659e61002e9d6ff77b2dca72540e0af1b2ca64stoddard * If the security setting is NONE, override it to the security
c0659e61002e9d6ff77b2dca72540e0af1b2ca64stoddard * setting optionally supplied by the admin using LDAPTrustedMode
c0659e61002e9d6ff77b2dca72540e0af1b2ca64stoddard /* save away a copy of the client cert list that is presently valid */
cd8f8c995d415473f3bfb0b329b2450f2a722c3atrawick l->client_certs = apr_array_copy_hdr(l->pool, st->client_certs);
3568de757bac0b47256647504c186d17ca272f85rbb /* add the cleanup to the pool */
3568de757bac0b47256647504c186d17ca272f85rbb/* ------------------------------------------------------------------ */
8bfe865d8d61be4ba4a89e45427a3c4211ebabdctrawick * Compares two DNs to see if they're equal. The only way to do this correctly is to
8bfe865d8d61be4ba4a89e45427a3c4211ebabdctrawick * search for the dn and then do ldap_get_dn() on the result. This should match the
8bfe865d8d61be4ba4a89e45427a3c4211ebabdctrawick * initial dn, since it would have been also retrieved with ldap_get_dn(). This is
8bfe865d8d61be4ba4a89e45427a3c4211ebabdctrawick * expensive, so if the configuration value compare_dn_on_server is
8bfe865d8d61be4ba4a89e45427a3c4211ebabdctrawick * false, just does an ordinary strcmp.
8bfe865d8d61be4ba4a89e45427a3c4211ebabdctrawick * The lock for the ldap cache should already be acquired.
8bfe865d8d61be4ba4a89e45427a3c4211ebabdctrawickLDAP_DECLARE(int) util_ldap_cache_comparedn(request_rec *r, util_ldap_connection_t *ldc,
2e7f1d7da527c09e717251e186deffe55e6fbd0ftrawick util_ldap_state_t *st = (util_ldap_state_t *)ap_get_module_config(r->server->module_config, &ldap_module);
64c351fd973428b5bb4c28e983fa86875ea4e60fdougm /* get cache entry (or create one) */
28c170ac8e99644de58cad454c6e0f9b4b359be6jerenkrantz curl = util_ald_cache_fetch(st->util_ldap_cache, &curnode);
28c170ac8e99644de58cad454c6e0f9b4b359be6jerenkrantz /* a simple compare? */
64c351fd973428b5bb4c28e983fa86875ea4e60fdougm /* unlock this read lock */
64c351fd973428b5bb4c28e983fa86875ea4e60fdougm ldc->reason = "DN Comparison FALSE (direct strcmp())";
8bfe865d8d61be4ba4a89e45427a3c4211ebabdctrawick ldc->reason = "DN Comparison TRUE (direct strcmp())";
8bfe865d8d61be4ba4a89e45427a3c4211ebabdctrawick /* no - it's a server side compare */
cb97ae2ff6969c2789b8e03f1bc4187fa73b6bafwrowe /* is it in the compare cache? */
64c351fd973428b5bb4c28e983fa86875ea4e60fdougm node = util_ald_cache_fetch(curl->dn_compare_cache, &newnode);
8bfe865d8d61be4ba4a89e45427a3c4211ebabdctrawick /* If it's in the cache, it's good */
64c351fd973428b5bb4c28e983fa86875ea4e60fdougm /* unlock this read lock */
8bfe865d8d61be4ba4a89e45427a3c4211ebabdctrawick /* unlock this read lock */
8bfe865d8d61be4ba4a89e45427a3c4211ebabdctrawick /* too many failures */
8bfe865d8d61be4ba4a89e45427a3c4211ebabdctrawick /* make a server connection */
8bfe865d8d61be4ba4a89e45427a3c4211ebabdctrawick if (LDAP_SUCCESS != (result = util_ldap_connection_open(r, ldc))) {
8bfe865d8d61be4ba4a89e45427a3c4211ebabdctrawick /* connect to server failed */
8bfe865d8d61be4ba4a89e45427a3c4211ebabdctrawick /* search for reqdn */
8bfe865d8d61be4ba4a89e45427a3c4211ebabdctrawick if ((result = ldap_search_ext_s(ldc->ldap, (char *)reqdn, LDAP_SCOPE_BASE,
8bfe865d8d61be4ba4a89e45427a3c4211ebabdctrawick ldc->reason = "DN Comparison ldap_search_ext_s() failed with server down";
8bfe865d8d61be4ba4a89e45427a3c4211ebabdctrawick /* search for reqdn failed - no match */
8bfe865d8d61be4ba4a89e45427a3c4211ebabdctrawick ldc->reason = "DN Comparison ldap_search_ext_s() failed";
8bfe865d8d61be4ba4a89e45427a3c4211ebabdctrawick /* compare unsuccessful */
f886987cd0bd4220c14043c4d9be77ec22902e73trawick ldc->reason = "DN Comparison FALSE (checked on server)";
64c351fd973428b5bb4c28e983fa86875ea4e60fdougm /* compare successful - add to the compare cache */
8bfe865d8d61be4ba4a89e45427a3c4211ebabdctrawick node = util_ald_cache_fetch(curl->dn_compare_cache, &newnode);
8bfe865d8d61be4ba4a89e45427a3c4211ebabdctrawick (strcmp(reqdn, node->reqdn) != 0) || (strcmp(dn, node->dn) != 0)) {
8bfe865d8d61be4ba4a89e45427a3c4211ebabdctrawick util_ald_cache_insert(curl->dn_compare_cache, &newnode);
8bfe865d8d61be4ba4a89e45427a3c4211ebabdctrawick ldc->reason = "DN Comparison TRUE (checked on server)";
8bfe865d8d61be4ba4a89e45427a3c4211ebabdctrawick * Does an generic ldap_compare operation. It accepts a cache that it will use
64c351fd973428b5bb4c28e983fa86875ea4e60fdougm * to lookup the compare in the cache. We cache two kinds of compares
2e7f1d7da527c09e717251e186deffe55e6fbd0ftrawick * (require group compares) and (require user compares). Each compare has a different
8bfe865d8d61be4ba4a89e45427a3c4211ebabdctrawick * cache node: require group includes the DN; require user does not because the
64c351fd973428b5bb4c28e983fa86875ea4e60fdougm * require user cache is owned by the
f886987cd0bd4220c14043c4d9be77ec22902e73trawickLDAP_DECLARE(int) util_ldap_cache_compare(request_rec *r, util_ldap_connection_t *ldc,
8bfe865d8d61be4ba4a89e45427a3c4211ebabdctrawick (util_ldap_state_t *)ap_get_module_config(r->server->module_config,
8bfe865d8d61be4ba4a89e45427a3c4211ebabdctrawick /* get cache entry (or create one) */
8bfe865d8d61be4ba4a89e45427a3c4211ebabdctrawick curl = util_ald_cache_fetch(st->util_ldap_cache, &curnode);
8bfe865d8d61be4ba4a89e45427a3c4211ebabdctrawick /* make a comparison to the cache */
8bfe865d8d61be4ba4a89e45427a3c4211ebabdctrawick compare_nodep = util_ald_cache_fetch(curl->compare_cache, &the_compare_node);
8bfe865d8d61be4ba4a89e45427a3c4211ebabdctrawick /* found it... */
8bfe865d8d61be4ba4a89e45427a3c4211ebabdctrawick if (curtime - compare_nodep->lastcompare > st->compare_cache_ttl) {
8bfe865d8d61be4ba4a89e45427a3c4211ebabdctrawick /* ...but it is too old */
8bfe865d8d61be4ba4a89e45427a3c4211ebabdctrawick util_ald_cache_remove(curl->compare_cache, compare_nodep);
8bfe865d8d61be4ba4a89e45427a3c4211ebabdctrawick /* ...and it is good */
8bfe865d8d61be4ba4a89e45427a3c4211ebabdctrawick /* unlock this read lock */
f886987cd0bd4220c14043c4d9be77ec22902e73trawick else if (LDAP_COMPARE_FALSE == compare_nodep->result) {
64c351fd973428b5bb4c28e983fa86875ea4e60fdougm else if (LDAP_NO_SUCH_ATTRIBUTE == compare_nodep->result) {
64c351fd973428b5bb4c28e983fa86875ea4e60fdougm ldc->reason = "Comparison no such attribute (cached)";
8bfe865d8d61be4ba4a89e45427a3c4211ebabdctrawick /* unlock this read lock */
8bfe865d8d61be4ba4a89e45427a3c4211ebabdctrawick /* too many failures */
64c351fd973428b5bb4c28e983fa86875ea4e60fdougm if (LDAP_SUCCESS != (result = util_ldap_connection_open(r, ldc))) {
8bfe865d8d61be4ba4a89e45427a3c4211ebabdctrawick /* connect failed */
28c170ac8e99644de58cad454c6e0f9b4b359be6jerenkrantz /* connection failed - try again */
1ec8bd0373f11c07688ec9afbbf778cf78a0bc52wrowe ldc->reason = "ldap_compare_s() failed with server down";
f886987cd0bd4220c14043c4d9be77ec22902e73trawick /* compare completed; caching result */
1ec8bd0373f11c07688ec9afbbf778cf78a0bc52wrowe /* If the node doesn't exist then insert it, otherwise just update it with
3568de757bac0b47256647504c186d17ca272f85rbb the last results */
28c170ac8e99644de58cad454c6e0f9b4b359be6jerenkrantz compare_nodep = util_ald_cache_fetch(curl->compare_cache, &the_compare_node);
28c170ac8e99644de58cad454c6e0f9b4b359be6jerenkrantz (strcmp(the_compare_node.dn, compare_nodep->dn) != 0) ||
3568de757bac0b47256647504c186d17ca272f85rbb (strcmp(the_compare_node.attrib, compare_nodep->attrib) != 0) ||
28c170ac8e99644de58cad454c6e0f9b4b359be6jerenkrantz (strcmp(the_compare_node.value, compare_nodep->value) != 0)) {
28c170ac8e99644de58cad454c6e0f9b4b359be6jerenkrantz util_ald_cache_insert(curl->compare_cache, &the_compare_node);
28c170ac8e99644de58cad454c6e0f9b4b359be6jerenkrantz ldc->reason = "Comparison no such attribute (adding to cache)";
3568de757bac0b47256647504c186d17ca272f85rbbLDAP_DECLARE(int) util_ldap_cache_checkuserid(request_rec *r, util_ldap_connection_t *ldc,
ec020ca384efb30d501a5af796ddc3bb237d7b8fgregames const char *url, const char *basedn, int scope, char **attrs,
3568de757bac0b47256647504c186d17ca272f85rbb const char *filter, const char *bindpw, const char **binddn,
ce03576b2434cec77f2921db9d5b6a0510581c23rederpj const char ***retvals)
ca53a74f4012a45cbad48e940eddf27d866981f9dougm util_search_node_t *search_nodep; /* Cached search node */
28c170ac8e99644de58cad454c6e0f9b4b359be6jerenkrantz (util_ldap_state_t *)ap_get_module_config(r->server->module_config,
28c170ac8e99644de58cad454c6e0f9b4b359be6jerenkrantz /* Get the cache node for this url */
0f081398cf0eef8cc7c66a535d450110a92dc8aefielding curl = (util_url_node_t *)util_ald_cache_fetch(st->util_ldap_cache, &curnode);
if (curl) {
return LDAP_SUCCESS;
return result;
return result;
goto start_over;
return result;
if (count == 0 )
return LDAP_NO_SUCH_OBJECT;
return LDAP_INVALID_CREDENTIALS;
(char *)*binddn,
goto start_over;
return result;
if (attrs) {
while (attrs[k++]);
while (attrs[i]) {
char **values;
if (curl) {
return LDAP_SUCCESS;
const char ***retvals)
int result = 0;
char *dn;
int count;
int failures = 0;
&ldap_module);
if (curl) {
return LDAP_SUCCESS;
return result;
return result;
goto start_over;
return result;
if (count == 0 )
return LDAP_NO_SUCH_OBJECT;
if (attrs) {
while (attrs[k++]);
while (attrs[i]) {
char **values;
if (curl) {
return LDAP_SUCCESS;
&ldap_module);
return NULL;
&ldap_module);
if (file) {
return NULL;
&ldap_module);
return NULL;
&ldap_module);
return NULL;
&ldap_module);
return NULL;
&ldap_module);
return NULL;
return APR_LDAP_CA_TYPE_DER;
return APR_LDAP_CA_TYPE_BASE64;
return APR_LDAP_CA_TYPE_CERT7_DB;
return APR_LDAP_CA_TYPE_SECMOD;
return APR_LDAP_CERT_TYPE_DER;
return APR_LDAP_CERT_TYPE_BASE64;
return APR_LDAP_CERT_TYPE_KEY3_DB;
return APR_LDAP_CERT_TYPE_NICKNAME;
return APR_LDAP_KEY_TYPE_DER;
return APR_LDAP_KEY_TYPE_BASE64;
return APR_LDAP_CA_TYPE_UNKNOWN;
static const char *util_ldap_set_trusted_global_cert(cmd_parms *cmd, void *dummy, const char *type, const char *file, const char *password)
&ldap_module);
int cert_type = 0;
return err;
if (type) {
return(NULL);
static const char *util_ldap_set_trusted_client_cert(cmd_parms *cmd, void *config, const char *type, const char *file, const char *password)
&ldap_module);
int cert_type = 0;
if (type) {
return(NULL);
&ldap_module);
mode);
return(NULL);
return st;
return st;
return APR_SUCCESS;
void *data;
int rc;
if (!data) {
return OK;
result = apr_global_mutex_create(&st->util_ldap_cache_lock, st->lock_file, APR_LOCK_DEFAULT, st->pool);
return result;
#ifdef AP_NEED_SET_MUTEX_PERMS
return result;
while (s_vhost) {
ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, "LDAP cache: LDAPSharedCacheSize is zero, disabling shared memory cache");
NULL,
&(result_err));
return(OK);
{NULL}