util_ldap.c revision f2be127030aa4190033084f0a6add531c9bc41de
842ae4bd224140319ae7feec1872b93dfd491143fielding/* Licensed to the Apache Software Foundation (ASF) under one or more
842ae4bd224140319ae7feec1872b93dfd491143fielding * contributor license agreements. See the NOTICE file distributed with
842ae4bd224140319ae7feec1872b93dfd491143fielding * this work for additional information regarding copyright ownership.
842ae4bd224140319ae7feec1872b93dfd491143fielding * The ASF licenses this file to You under the Apache License, Version 2.0
842ae4bd224140319ae7feec1872b93dfd491143fielding * (the "License"); you may not use this file except in compliance with
842ae4bd224140319ae7feec1872b93dfd491143fielding * the License. You may obtain a copy of the License at
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * Unless required by applicable law or agreed to in writing, software
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * distributed under the License is distributed on an "AS IS" BASIS,
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * See the License for the specific language governing permissions and
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * limitations under the License.
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * util_ldap.c: LDAP things
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * Original code from auth_ldap module for Apache v1.3:
e8f95a682820a599fe41b22977010636be5c2717jim * Copyright 1998, 1999 Enbridge Pipelines Inc.
1747d30b98aa1bdbc43994c02cd46ab4cb9319e4fielding * Copyright 1999-2001 Dave Carrigan
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes#error mod_ldap requires APR-util to have LDAP support built in
22f8da8087791fcb95b836c8a81937c5a9bba202bnicholes/* Default define for ldap functions that need a SIZELIMIT but
22f8da8087791fcb95b836c8a81937c5a9bba202bnicholes * do not have the define
22f8da8087791fcb95b836c8a81937c5a9bba202bnicholes * XXX This should be removed once a supporting #define is
22f8da8087791fcb95b836c8a81937c5a9bba202bnicholes * released through APR-Util.
43997561b2302d13dee973998e77743a3ddd2374trawickstatic const char *ldap_cache_mutex_type = "ldap-cache";
0568280364eb026393be492ebc732795c4934643jorton#define LDAP_CACHE_LOCK() do { \
0568280364eb026393be492ebc732795c4934643jorton#define LDAP_CACHE_UNLOCK() do { \
4e9c24785b525d2956e6e381015c0f2bd0a72f4bcovenerstatic apr_status_t util_ldap_connection_remove (void *param);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholesstatic void util_ldap_strdup (char **str, const char *newstr)
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * Status Handler
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * --------------
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * This handler generates a status page about the current performance of
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * the LDAP cache. It is enabled as follows:
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * <Location /ldap-status>
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * SetHandler ldap-status
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * </Location>
a1790fb35c4b352dab721370985c623a9f8f5062rpluem ap_set_content_type(r, "text/html; charset=ISO-8859-1");
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes "<html><head><title>LDAP Cache Information</title></head>\n", r);
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe ap_rputs("<body bgcolor='#ffffff'><h1 align=center>LDAP Cache Information"
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe "</h1>\n", r);
4e9c24785b525d2956e6e381015c0f2bd0a72f4bcovener/* ------------------------------------------------------------------ */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * Closes an LDAP connection by unlocking it. The next time
f43b67c5a9d29b572eac916f8335cedc80c908bebnicholes * uldap_connection_find() is called this connection will be
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * available for reuse.
8113dac419143273351446c3ad653f3fe5ba5cfdwrowestatic void uldap_connection_close(util_ldap_connection_t *ldc)
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * Is it safe leaving bound connections floating around between the
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * different modules? Keeping the user bound is a performance boost,
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * but it is also a potential security problem - maybe.
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * For now we unbind the user when we finish with a connection, but
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * we don't have to...
4e9c24785b525d2956e6e381015c0f2bd0a72f4bcovener /* mark our connection as available for reuse */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * Destroys an LDAP connection by unbinding and closing the connection to
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * the LDAP server. It is used to bring the connection back to a known
4e9c24785b525d2956e6e381015c0f2bd0a72f4bcovener * state after an error.
8113dac419143273351446c3ad653f3fe5ba5cfdwrowestatic apr_status_t uldap_connection_unbind(void *param)
1f299703465bd9975d94e9f229f76af807442de2covener * Clean up an LDAP connection by unbinding and unlocking the connection.
4e9c24785b525d2956e6e381015c0f2bd0a72f4bcovener * This cleanup does not remove the util_ldap_connection_t from the
4e9c24785b525d2956e6e381015c0f2bd0a72f4bcovener * per-virtualhost list of connections, does not remove the storage
4e9c24785b525d2956e6e381015c0f2bd0a72f4bcovener * for the util_ldap_connection_t or it's data, and is NOT run automatically.
8113dac419143273351446c3ad653f3fe5ba5cfdwrowestatic apr_status_t uldap_connection_cleanup(void *param)
9ad7b260be233be7d7b5576979825cac72e15498rederpj /* Release the rebind info for this connection. No more referral rebinds required. */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes /* unbind and disconnect from the LDAP server */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes /* free the username and password */
3e6d7277b90d3011db832139afc20efb5f17e203rederpj /* ldc->reason is allocated from r->pool */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes /* unlock this entry */
4e9c24785b525d2956e6e381015c0f2bd0a72f4bcovener * util_ldap_connection_remove frees all storage associated with the LDAP
4e9c24785b525d2956e6e381015c0f2bd0a72f4bcovener * connection and removes it completely from the per-virtualhost list of
4e9c24785b525d2956e6e381015c0f2bd0a72f4bcovener * connections
4e9c24785b525d2956e6e381015c0f2bd0a72f4bcovener * The caller should hold the lock for this connection
4e9c24785b525d2956e6e381015c0f2bd0a72f4bcovenerstatic apr_status_t util_ldap_connection_remove (void *param) {
4e9c24785b525d2956e6e381015c0f2bd0a72f4bcovener util_ldap_connection_t *ldc = param, *l = NULL, *prev = NULL;
4e9c24785b525d2956e6e381015c0f2bd0a72f4bcovener /* Remove ldc from the list */
4e9c24785b525d2956e6e381015c0f2bd0a72f4bcovener if (l == ldc) {
4e9c24785b525d2956e6e381015c0f2bd0a72f4bcovener /* Some unfortunate duplication between this method
4e9c24785b525d2956e6e381015c0f2bd0a72f4bcovener * and uldap_connection_cleanup()
4e9c24785b525d2956e6e381015c0f2bd0a72f4bcovener /* Destory the pool associated with this connection */
4be9c459920a7c1cfe62d654327dae5c4bb6b284sf struct timeval connectionTimeout = {10,0}; /* 10 second connection timeout */
3dfeb02cfb853d8717ca0cc259b59fea610173f5bnicholes (util_ldap_state_t *)ap_get_module_config(r->server->module_config,
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes /* Since the host will include a port if the default port is not used,
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes * always specify the default ports for the port parameter. This will
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes * allow a host string that contains multiple hosts the ability to mix
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes * some hosts with ports and some without. All hosts which do not
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes * specify a port will use the default port.
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes APR_LDAP_SSL == ldc->secure ? LDAPS_PORT : LDAP_PORT,
513b324e774c559b579896df131fd7c8471ed529rederpj /* something really bad happened */
9ad7b260be233be7d7b5576979825cac72e15498rederpj /* Now that we have an ldap struct, add it to the referral list for rebinds. */
9ad7b260be233be7d7b5576979825cac72e15498rederpj rc = apr_ldap_rebind_add(ldc->pool, ldc->ldap, ldc->binddn, ldc->bindpw);
9ad7b260be233be7d7b5576979825cac72e15498rederpj "LDAP: Unable to add rebind cross reference entry. Out of memory?");
9ad7b260be233be7d7b5576979825cac72e15498rederpj ldc->reason = "LDAP: Unable to add rebind cross reference entry.";
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes /* always default to LDAP V3 */
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes ldap_set_option(ldc->ldap, LDAP_OPT_PROTOCOL_VERSION, &version);
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes /* set client certificates */
ebe5305f8b22507374358f32b74d12fb50c05a25covener apr_ldap_set_option(r->pool, ldc->ldap, APR_LDAP_OPT_TLS_CERT,
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes /* switch on SSL/TLS */
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes /* Set the alias dereferencing option */
b08925593f214f621161742925dcf074a8047e0acovener ldap_set_option(ldc->ldap, LDAP_OPT_DEREF, &ldap_option);
9ad7b260be233be7d7b5576979825cac72e15498rederpj /* Set options for rebind and referrals. */
9ad7b260be233be7d7b5576979825cac72e15498rederpj "LDAP: Setting referrals to %s.",
128a5d93141a86e3afa151e921035a07297c9833rederpj ((ldc->ChaseReferrals == AP_LDAP_CHASEREFERRALS_ON) ? "On" : "Off"));
128a5d93141a86e3afa151e921035a07297c9833rederpj (void *)((ldc->ChaseReferrals == AP_LDAP_CHASEREFERRALS_ON) ?
9ad7b260be233be7d7b5576979825cac72e15498rederpj "Unable to set LDAP_OPT_REFERRALS option to %s: %d.",
128a5d93141a86e3afa151e921035a07297c9833rederpj ((ldc->ChaseReferrals == AP_LDAP_CHASEREFERRALS_ON) ? "On" : "Off"),
9ad7b260be233be7d7b5576979825cac72e15498rederpj result->reason = "Unable to set LDAP_OPT_REFERRALS.";
87587593f1a53030e840acc0dec6cc881022ea40covener if ((ldc->ReferralHopLimit != AP_LDAP_HOPLIMIT_UNSET) && ldc->ChaseReferrals == AP_LDAP_CHASEREFERRALS_ON) {
87587593f1a53030e840acc0dec6cc881022ea40covener /* Referral hop limit - only if referrals are enabled and a hop limit is explicitly requested */
9ad7b260be233be7d7b5576979825cac72e15498rederpj "Setting referral hop limit to %d.",
9ad7b260be233be7d7b5576979825cac72e15498rederpj "Unable to set LDAP_OPT_REFHOPLIMIT option to %d: %d.",
9ad7b260be233be7d7b5576979825cac72e15498rederpj result->reason = "Unable to set LDAP_OPT_REFHOPLIMIT.";
7add8f7fb048534390571801b7794f71cd9e127abnicholes/*XXX All of the #ifdef's need to be removed once apr-util 1.2 is released */
8445dae5cc606ba8ba04efc341cc1e081d95920drpluem apr_ldap_set_option(r->pool, ldc->ldap, APR_LDAP_OPT_VERIFY_CERT,
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes result->rc = ldapssl_set_verify_mode(LDAPSSL_VERIFY_SERVER);
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes result->rc = ldapssl_set_verify_mode(LDAPSSL_VERIFY_NONE);
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes /* This is not a per-connection setting so just pass NULL for the
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes Ldap connection handle */
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes result->rc = ldap_set_option(NULL, LDAP_OPT_X_TLS_REQUIRE_CERT, &i);
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes result->rc = ldap_set_option(NULL, LDAP_OPT_X_TLS_REQUIRE_CERT, &i);
ebe5305f8b22507374358f32b74d12fb50c05a25covener rc = apr_ldap_set_option(r->pool, ldc->ldap, LDAP_OPT_NETWORK_TIMEOUT,
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes "LDAP: Could not set the connection timeout");
4be9c459920a7c1cfe62d654327dae5c4bb6b284sf * LDAP_OPT_TIMEOUT is not portable, but it influences all synchronous ldap
4be9c459920a7c1cfe62d654327dae5c4bb6b284sf * function calls and not just ldap_search_ext_s(), which accepts a timeout
4be9c459920a7c1cfe62d654327dae5c4bb6b284sf * parameter.
4be9c459920a7c1cfe62d654327dae5c4bb6b284sf * XXX: It would be possible to simulate LDAP_OPT_TIMEOUT by replacing all
4be9c459920a7c1cfe62d654327dae5c4bb6b284sf * XXX: synchronous ldap function calls with asynchronous calls and using
4be9c459920a7c1cfe62d654327dae5c4bb6b284sf * XXX: ldap_result() with a timeout.
4be9c459920a7c1cfe62d654327dae5c4bb6b284sf rc = apr_ldap_set_option(r->pool, ldc->ldap, LDAP_OPT_TIMEOUT,
4be9c459920a7c1cfe62d654327dae5c4bb6b284sf "LDAP: Could not set LDAP_OPT_TIMEOUT");
7dbf29be626018bc389ef94c1846aeac4b72633bsf * Replacement function for ldap_simple_bind_s() with a timeout.
7dbf29be626018bc389ef94c1846aeac4b72633bsf * To do this in a portable way, we have to use ldap_simple_bind() and
7dbf29be626018bc389ef94c1846aeac4b72633bsf * ldap_result().
7dbf29be626018bc389ef94c1846aeac4b72633bsf * Returns LDAP_SUCCESS on success; and an error code on failure
7dbf29be626018bc389ef94c1846aeac4b72633bsfstatic int uldap_simple_bind(util_ldap_connection_t *ldc, char *binddn,
7dbf29be626018bc389ef94c1846aeac4b72633bsf /* -1 is LDAP_SERVER_DOWN in openldap, use something else */
7dbf29be626018bc389ef94c1846aeac4b72633bsf ldc->reason = "LDAP: ldap_simple_bind() result retrieval failed";
7dbf29be626018bc389ef94c1846aeac4b72633bsf /* -1 is LDAP_SERVER_DOWN in openldap, use something else */
7dbf29be626018bc389ef94c1846aeac4b72633bsf else if (rc == 0) {
7dbf29be626018bc389ef94c1846aeac4b72633bsf } else if (ldap_parse_result(ldc->ldap, result, &rc, NULL, NULL, NULL,
7dbf29be626018bc389ef94c1846aeac4b72633bsf ldc->reason = "LDAP: ldap_simple_bind() parse result failed";
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes * Connect to the LDAP server and binds. Does not connect if already
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes * connected (i.e. ldc->ldap is non-NULL.) Does not bind if already bound.
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes * Returns LDAP_SUCCESS on success; and an error code on failure
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes /* sanity check for NULL */
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes /* If the connection is already bound, return
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes ldc->reason = "LDAP: connection open successful (already bound)";
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes /* create the ldap session handle
4be9c459920a7c1cfe62d654327dae5c4bb6b284sf st = (util_ldap_state_t *)ap_get_module_config(r->server->module_config,
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes /* loop trying to bind up to 10 times if LDAP_SERVER_DOWN error is
4be9c459920a7c1cfe62d654327dae5c4bb6b284sf * returned. If LDAP_TIMEOUT is returned on the first try, maybe the
4be9c459920a7c1cfe62d654327dae5c4bb6b284sf * connection was idle for a long time and has been dropped by a firewall.
7dbf29be626018bc389ef94c1846aeac4b72633bsf * In this case close the connection immediately and try again.
4be9c459920a7c1cfe62d654327dae5c4bb6b284sf * On Success or any other error, break out of the loop.
e8f95a682820a599fe41b22977010636be5c2717jim * NOTE: Looping is probably not a great idea. If the server isn't
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * responding the chances it will respond after a few tries are poor.
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * However, the original code looped and it only happens on
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * the error condition.
7dbf29be626018bc389ef94c1846aeac4b72633bsf rc = uldap_simple_bind(ldc, (char *)ldc->binddn, (char *)ldc->bindpw,
9c63a05713cb83a44a1590b4af33edeebf39f118sf "ldap_simple_bind() timed out on reused "
9c63a05713cb83a44a1590b4af33edeebf39f118sf "connection, dropped by firewall?");
9c63a05713cb83a44a1590b4af33edeebf39f118sf "attempt to re-init the connection");
9efd5708f6f0ab1992f6a5233eb622ad5e4eae18sf "ldap_simple_bind() failed with server down "
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes /* free the handle if there was an error
54d22ed1c429b903b029bbd62621f11a9e286137minfrin * Compare client certificate arrays.
54d22ed1c429b903b029bbd62621f11a9e286137minfrin * Returns 1 on compare failure, 0 otherwise.
e8f95a682820a599fe41b22977010636be5c2717jimstatic int compare_client_certs(apr_array_header_t *srcs,
54d22ed1c429b903b029bbd62621f11a9e286137minfrin /* arrays both NULL? if so, then equal */
54d22ed1c429b903b029bbd62621f11a9e286137minfrin /* arrays different length or either NULL? If so, then not equal */
54d22ed1c429b903b029bbd62621f11a9e286137minfrin if (srcs == NULL || dests == NULL || srcs->nelts != dests->nelts) {
54d22ed1c429b903b029bbd62621f11a9e286137minfrin /* run an actual comparison */
54d22ed1c429b903b029bbd62621f11a9e286137minfrin dest = (struct apr_ldap_opt_tls_cert_t *)dests->elts;
6999a76d8eb5ef6b4b295e51df0b2fb6064bd373covener /* One is passwordless? If so, then not equal */
6999a76d8eb5ef6b4b295e51df0b2fb6064bd373covener ((src[i].password == NULL) ^ (dest[i].password == NULL)) ||
6999a76d8eb5ef6b4b295e51df0b2fb6064bd373covener (src[i].password != NULL && dest[i].password != NULL &&
54d22ed1c429b903b029bbd62621f11a9e286137minfrin /* if we got here, the cert arrays were identical */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * Find an existing ldap connection struct that matches the
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * provided ldap connection parameters.
e8f95a682820a599fe41b22977010636be5c2717jim * If not found in the cache, a new ldc structure will be allocated
e8f95a682820a599fe41b22977010636be5c2717jim * from st->pool and returned to the caller. If found in the cache,
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe * a pointer to the existing ldc structure will be returned.
54d22ed1c429b903b029bbd62621f11a9e286137minfrin struct util_ldap_connection_t *l, *p; /* To traverse the linked list */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes (util_ldap_state_t *)ap_get_module_config(r->server->module_config,
9ad7b260be233be7d7b5576979825cac72e15498rederpj (util_ldap_config_t *) ap_get_module_config(r->per_dir_config, &ldap_module);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes /* mutex lock this function */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes /* Search for an exact connection match in the list that is not
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * being used.
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes if (APR_SUCCESS == apr_thread_mutex_trylock(l->lock)) {
ae1981fc94adf2b231e2d0e15d2f895b2138c969covener && !compare_client_certs(dc->client_certs, l->client_certs))
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes /* If this connection didn't match the criteria, then we
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * need to unlock the mutex so it is available to be reused.
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes /* If nothing found, search again, but we don't care about the
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * binddn and bindpw this time.
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes if (APR_SUCCESS == apr_thread_mutex_trylock(l->lock)) {
e8f95a682820a599fe41b22977010636be5c2717jim if ((l->port == port) && (strcmp(l->host, host) == 0) &&
560fd0658902ab57754616c172d8953e69fc4722bnicholes (l->deref == deref) && (l->secure == secureflag) &&
ae1981fc94adf2b231e2d0e15d2f895b2138c969covener !compare_client_certs(dc->client_certs, l->client_certs))
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes /* the bind credentials have changed */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes /* If this connection didn't match the criteria, then we
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * need to unlock the mutex so it is available to be reused.
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes/* artificially disable cache */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes/* l = NULL; */
0e05808dc59a321566303084c84b9826a4353cefrederpj /* If no connection was found after the second search, we
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * must create one.
0e05808dc59a321566303084c84b9826a4353cefrederpj if (apr_pool_create(&newpool, NULL) != APR_SUCCESS) {
ebe5305f8b22507374358f32b74d12fb50c05a25covener "util_ldap: Failed to create memory pool");
4e9c24785b525d2956e6e381015c0f2bd0a72f4bcovener * Add the new connection entry to the linked list. Note that we
4e9c24785b525d2956e6e381015c0f2bd0a72f4bcovener * don't actually establish an LDAP connection yet; that happens
4e9c24785b525d2956e6e381015c0f2bd0a72f4bcovener * the first time authentication is requested.
4e9c24785b525d2956e6e381015c0f2bd0a72f4bcovener /* create the details of this connection in the new pool */
4e9c24785b525d2956e6e381015c0f2bd0a72f4bcovener l = apr_pcalloc(newpool, sizeof(util_ldap_connection_t));
4e9c24785b525d2956e6e381015c0f2bd0a72f4bcovener apr_thread_mutex_create(&l->lock, APR_THREAD_MUTEX_DEFAULT, l->pool);
54d22ed1c429b903b029bbd62621f11a9e286137minfrin /* The security mode after parsing the URL will always be either
54d22ed1c429b903b029bbd62621f11a9e286137minfrin * APR_LDAP_NONE (ldap://) or APR_LDAP_SSL (ldaps://).
54d22ed1c429b903b029bbd62621f11a9e286137minfrin * If the security setting is NONE, override it to the security
54d22ed1c429b903b029bbd62621f11a9e286137minfrin * setting optionally supplied by the admin using LDAPTrustedMode
54d22ed1c429b903b029bbd62621f11a9e286137minfrin /* save away a copy of the client cert list that is presently valid */
ae1981fc94adf2b231e2d0e15d2f895b2138c969covener l->client_certs = apr_array_copy_hdr(l->pool, dc->client_certs);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes/* ------------------------------------------------------------------ */
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe * Compares two DNs to see if they're equal. The only way to do this correctly
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe * is to search for the dn and then do ldap_get_dn() on the result. This should
e8f95a682820a599fe41b22977010636be5c2717jim * match the initial dn, since it would have been also retrieved with
e8f95a682820a599fe41b22977010636be5c2717jim * ldap_get_dn(). This is expensive, so if the configuration value
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe * compare_dn_on_server is false, just does an ordinary strcmp.
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * The lock for the ldap cache should already be acquired.
e8f95a682820a599fe41b22977010636be5c2717jimstatic int uldap_cache_comparedn(request_rec *r, util_ldap_connection_t *ldc,
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes /* get cache entry (or create one) */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes curl = util_ald_cache_fetch(st->util_ldap_cache, &curnode);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes /* a simple compare? */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes /* unlock this read lock */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes ldc->reason = "DN Comparison FALSE (direct strcmp())";
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes ldc->reason = "DN Comparison TRUE (direct strcmp())";
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes /* no - it's a server side compare */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes /* is it in the compare cache? */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes node = util_ald_cache_fetch(curl->dn_compare_cache, &newnode);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes /* If it's in the cache, it's good */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes /* unlock this read lock */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes /* unlock this read lock */
43c3e6a4b559b76b750c245ee95e2782c15b4296jim /* too many failures */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes /* make a server connection */
f43b67c5a9d29b572eac916f8335cedc80c908bebnicholes if (LDAP_SUCCESS != (result = uldap_connection_open(r, ldc))) {
43c3e6a4b559b76b750c245ee95e2782c15b4296jim /* connect to server failed */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes /* search for reqdn */
37af4b0cf648275b68ff41c866c665b4ccf4667dcovener result = ldap_search_ext_s(ldc->ldap, (char *)reqdn, LDAP_SCOPE_BASE,
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe "failed with server down";
4be9c459920a7c1cfe62d654327dae5c4bb6b284sf * we are reusing a connection that doesn't seem to be active anymore
4be9c459920a7c1cfe62d654327dae5c4bb6b284sf * (firewall state drop?), let's try a new connection.
4be9c459920a7c1cfe62d654327dae5c4bb6b284sf "failed with timeout";
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes /* search for reqdn failed - no match */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes ldc->reason = "DN Comparison ldap_search_ext_s() failed";
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes /* compare unsuccessful */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes ldc->reason = "DN Comparison FALSE (checked on server)";
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes /* compare successful - add to the compare cache */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes node = util_ald_cache_fetch(curl->dn_compare_cache, &newnode);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes util_ald_cache_insert(curl->dn_compare_cache, &newnode);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes ldc->reason = "DN Comparison TRUE (checked on server)";
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * Does an generic ldap_compare operation. It accepts a cache that it will use
e8f95a682820a599fe41b22977010636be5c2717jim * to lookup the compare in the cache. We cache two kinds of compares
8445dae5cc606ba8ba04efc341cc1e081d95920drpluem * (require group compares) and (require user compares). Each compare has a
8445dae5cc606ba8ba04efc341cc1e081d95920drpluem * different cache node: require group includes the DN; require user does not
8445dae5cc606ba8ba04efc341cc1e081d95920drpluem * because the require user cache is owned by the
8113dac419143273351446c3ad653f3fe5ba5cfdwrowestatic int uldap_cache_compare(request_rec *r, util_ldap_connection_t *ldc,
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes /* get cache entry (or create one) */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes curl = util_ald_cache_fetch(st->util_ldap_cache, &curnode);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes /* make a comparison to the cache */
e8f95a682820a599fe41b22977010636be5c2717jim compare_nodep = util_ald_cache_fetch(curl->compare_cache,
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes /* found it... */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes if (curtime - compare_nodep->lastcompare > st->compare_cache_ttl) {
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes /* ...but it is too old */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes util_ald_cache_remove(curl->compare_cache, compare_nodep);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes /* ...and it is good */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes else if (LDAP_COMPARE_FALSE == compare_nodep->result) {
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes else if (LDAP_NO_SUCH_ATTRIBUTE == compare_nodep->result) {
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes ldc->reason = "Comparison no such attribute (cached)";
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj /* record the result code to return with the reason... */
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj /* and unlock this read lock */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes /* unlock this read lock */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes /* too many failures */
f43b67c5a9d29b572eac916f8335cedc80c908bebnicholes if (LDAP_SUCCESS != (result = uldap_connection_open(r, ldc))) {
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes /* connect failed */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes /* connection failed - try again */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes ldc->reason = "ldap_compare_s() failed with server down";
4be9c459920a7c1cfe62d654327dae5c4bb6b284sf * we are reusing a connection that doesn't seem to be active anymore
4be9c459920a7c1cfe62d654327dae5c4bb6b284sf * (firewall state drop?), let's try a new connection.
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes /* compare completed; caching result */
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe /* If the node doesn't exist then insert it, otherwise just update
e8f95a682820a599fe41b22977010636be5c2717jim * it with the last results
e8f95a682820a599fe41b22977010636be5c2717jim compare_nodep = util_ald_cache_fetch(curl->compare_cache,
e8f95a682820a599fe41b22977010636be5c2717jim || (strcmp(the_compare_node.dn, compare_nodep->dn) != 0)
e8f95a682820a599fe41b22977010636be5c2717jim || (strcmp(the_compare_node.attrib,compare_nodep->attrib) != 0)
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe || (strcmp(the_compare_node.value, compare_nodep->value) != 0))
9efd5708f6f0ab1992f6a5233eb622ad5e4eae18sf "cache_compare: Cache insertion failure.");
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes ldc->reason = "Comparison true (adding to cache)";
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes ldc->reason = "Comparison false (adding to cache)";
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes ldc->reason = "Comparison no such attribute (adding to cache)";
8445dae5cc606ba8ba04efc341cc1e081d95920drpluemstatic util_compare_subgroup_t* uldap_get_subgroups(request_rec *r,
8445dae5cc606ba8ba04efc341cc1e081d95920drpluem const char *url,
8445dae5cc606ba8ba04efc341cc1e081d95920drpluem const char *dn,
8869662bb1a4078297020e94ae5e928626d877c6rederpj apr_array_header_t *subgroups = apr_array_make(r->pool, 20, sizeof(char *));
8445dae5cc606ba8ba04efc341cc1e081d95920drpluem sgc_ents = (struct mod_auth_ldap_groupattr_entry_t *) subgroupclasses->elts;
8445dae5cc606ba8ba04efc341cc1e081d95920drpluem * 3.B. The cache didn't have any subgrouplist yet. Go check for subgroups.
8869662bb1a4078297020e94ae5e928626d877c6rederpj /* too many failures */
8869662bb1a4078297020e94ae5e928626d877c6rederpj if (LDAP_SUCCESS != (result = uldap_connection_open(r, ldc))) {
8869662bb1a4078297020e94ae5e928626d877c6rederpj /* connect failed */
8869662bb1a4078297020e94ae5e928626d877c6rederpj /* try to do the search */
8869662bb1a4078297020e94ae5e928626d877c6rederpj result = ldap_search_ext_s(ldc->ldap, (char *)dn, LDAP_SCOPE_BASE,
8445dae5cc606ba8ba04efc341cc1e081d95920drpluem ldc->reason = "ldap_search_ext_s() for subgroups failed with server"
4be9c459920a7c1cfe62d654327dae5c4bb6b284sf * we are reusing a connection that doesn't seem to be active anymore
4be9c459920a7c1cfe62d654327dae5c4bb6b284sf * (firewall state drop?), let's try a new connection.
4be9c459920a7c1cfe62d654327dae5c4bb6b284sf ldc->reason = "ldap_search_ext_s() for subgroups failed with timeout";
8869662bb1a4078297020e94ae5e928626d877c6rederpj /* if there is an error (including LDAP_NO_SUCH_OBJECT) return now */
8869662bb1a4078297020e94ae5e928626d877c6rederpj ldc->reason = "ldap_search_ext_s() for subgroups failed";
8869662bb1a4078297020e94ae5e928626d877c6rederpj * Get values for the provided sub-group attributes.
8869662bb1a4078297020e94ae5e928626d877c6rederpj /* Get *all* matching "member" values from this group. */
8869662bb1a4078297020e94ae5e928626d877c6rederpj values = ldap_get_values(ldc->ldap, entry, subgroupAttrs[indx]);
8445dae5cc606ba8ba04efc341cc1e081d95920drpluem * Now we are going to pare the subgroup members of this group
8445dae5cc606ba8ba04efc341cc1e081d95920drpluem * to *just* the subgroups, add them to the compare_nodep, and
8445dae5cc606ba8ba04efc341cc1e081d95920drpluem * then proceed to check the new level of subgroups.
8869662bb1a4078297020e94ae5e928626d877c6rederpj /* Check if this entry really is a group. */
8445dae5cc606ba8ba04efc341cc1e081d95920drpluem "objectClass",
8869662bb1a4078297020e94ae5e928626d877c6rederpj /* It's a group, so add it to the array. */
8869662bb1a4078297020e94ae5e928626d877c6rederpj char **newgrp = (char **) apr_array_push(subgroups);
8869662bb1a4078297020e94ae5e928626d877c6rederpj /* We need to fill in tmp_local_subgroups using the data from LDAP */
8869662bb1a4078297020e94ae5e928626d877c6rederpj res = apr_pcalloc(r->pool, sizeof(util_compare_subgroup_t));
8869662bb1a4078297020e94ae5e928626d877c6rederpj for (sgindex = 0; (group = apr_array_pop(subgroups)); sgindex++) {
8869662bb1a4078297020e94ae5e928626d877c6rederpj res->subgroupDNs[sgindex] = apr_pstrdup(r->pool, *group);
8445dae5cc606ba8ba04efc341cc1e081d95920drpluem * Does a recursive lookup operation to try to find a user within (cached)
8445dae5cc606ba8ba04efc341cc1e081d95920drpluem * nested groups. It accepts a cache that it will use to lookup previous
8445dae5cc606ba8ba04efc341cc1e081d95920drpluem * compare attempts. We cache two kinds of compares (require group compares)
8445dae5cc606ba8ba04efc341cc1e081d95920drpluem * and (require user compares). Each compare has a different cache node:
8445dae5cc606ba8ba04efc341cc1e081d95920drpluem * require group includes the DN; require user does not because the require
8445dae5cc606ba8ba04efc341cc1e081d95920drpluem * user cache is owned by the
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj * DON'T CALL THIS UNLESS YOU CALLED uldap_cache_compare FIRST!!!!!
8445dae5cc606ba8ba04efc341cc1e081d95920drpluem * 1. Call uldap_cache_compare for each subgroupclass value to check the
8445dae5cc606ba8ba04efc341cc1e081d95920drpluem * generic, user-agnostic, cached group entry. This will create a new generic
8445dae5cc606ba8ba04efc341cc1e081d95920drpluem * cache entry if there
8445dae5cc606ba8ba04efc341cc1e081d95920drpluem * wasn't one. If nothing returns LDAP_COMPARE_TRUE skip to step 5 since we
8445dae5cc606ba8ba04efc341cc1e081d95920drpluem * have no groups.
8445dae5cc606ba8ba04efc341cc1e081d95920drpluem * 2. Lock The cache and get the generic cache entry.
8445dae5cc606ba8ba04efc341cc1e081d95920drpluem * 3. Check if there is already a subgrouplist in this generic group's cache
8445dae5cc606ba8ba04efc341cc1e081d95920drpluem * A. If there is, go to step 4.
8445dae5cc606ba8ba04efc341cc1e081d95920drpluem * B. If there isn't:
8445dae5cc606ba8ba04efc341cc1e081d95920drpluem * i) Use ldap_search to get the full list
8445dae5cc606ba8ba04efc341cc1e081d95920drpluem * of subgroup "members" (which may include non-group "members").
8445dae5cc606ba8ba04efc341cc1e081d95920drpluem * ii) Use uldap_cache_compare to strip the list down to just groups.
8445dae5cc606ba8ba04efc341cc1e081d95920drpluem * iii) Lock and add this stripped down list to the cache of the generic
8445dae5cc606ba8ba04efc341cc1e081d95920drpluem * 4. Loop through the sgl and call uldap_cache_compare (using the user info)
8445dae5cc606ba8ba04efc341cc1e081d95920drpluem * subgroup to see if the subgroup contains the user and to get the subgroups
8445dae5cc606ba8ba04efc341cc1e081d95920drpluem * added to the
8445dae5cc606ba8ba04efc341cc1e081d95920drpluem * cache (with user-afinity, if they aren't already there).
8445dae5cc606ba8ba04efc341cc1e081d95920drpluem * A. If the user is in the subgroup, then we'll be returning
8445dae5cc606ba8ba04efc341cc1e081d95920drpluem * LDAP_COMPARE_TRUE.
8445dae5cc606ba8ba04efc341cc1e081d95920drpluem * B. if the user isn't in the subgroup (LDAP_COMPARE_FALSE via
8445dae5cc606ba8ba04efc341cc1e081d95920drpluem * uldap_cache_compare) then recursively call this function to get the
8445dae5cc606ba8ba04efc341cc1e081d95920drpluem * sub-subgroups added...
8445dae5cc606ba8ba04efc341cc1e081d95920drpluem * 5. Cleanup local allocations.
8445dae5cc606ba8ba04efc341cc1e081d95920drpluem * 6. Return the final result.
8445dae5cc606ba8ba04efc341cc1e081d95920drpluemstatic int uldap_cache_check_subgroups(request_rec *r,
0e05808dc59a321566303084c84b9826a4353cefrederpj int sgl_cached_empty = 0, sgindex = 0, base_sgcIndex = 0;
a9c4332dc6241dc11dd104826bd179d42ccc0f12fuankg (struct mod_auth_ldap_groupattr_entry_t *) subgroupclasses->elts;
8445dae5cc606ba8ba04efc341cc1e081d95920drpluem * Stop looking at deeper levels of nested groups if we have reached the
8445dae5cc606ba8ba04efc341cc1e081d95920drpluem * max. Since we already checked the top-level group in uldap_cache_compare,
8445dae5cc606ba8ba04efc341cc1e081d95920drpluem * we don't need to check it again here - so if max_subgroup_depth is set
8445dae5cc606ba8ba04efc341cc1e081d95920drpluem * to 0, we won't check it (i.e. that is why we check < rather than <=).
8445dae5cc606ba8ba04efc341cc1e081d95920drpluem * We'll be calling uldap_cache_compare from here to check if the user is
8445dae5cc606ba8ba04efc341cc1e081d95920drpluem * in the next level before we recurse into that next level looking for
8445dae5cc606ba8ba04efc341cc1e081d95920drpluem * more subgroups.
8445dae5cc606ba8ba04efc341cc1e081d95920drpluem * 1. Check the "groupiness" of the specified basedn. Stopping at the first
8445dae5cc606ba8ba04efc341cc1e081d95920drpluem * TRUE return.
8445dae5cc606ba8ba04efc341cc1e081d95920drpluem result = uldap_cache_compare(r, ldc, url, dn, "objectClass",
8445dae5cc606ba8ba04efc341cc1e081d95920drpluem * 2. Find previously created cache entry and check if there is already a
8445dae5cc606ba8ba04efc341cc1e081d95920drpluem * subgrouplist.
85da6b76d07b7af570cbbec208a87697ba9c44f5rederpj curl = util_ald_cache_fetch(st->util_ldap_cache, &curnode);
85da6b76d07b7af570cbbec208a87697ba9c44f5rederpj /* make a comparison to the cache */
85da6b76d07b7af570cbbec208a87697ba9c44f5rederpj the_compare_node.value = (char *)sgc_ents[base_sgcIndex].name;
8445dae5cc606ba8ba04efc341cc1e081d95920drpluem compare_nodep = util_ald_cache_fetch(curl->compare_cache,
8445dae5cc606ba8ba04efc341cc1e081d95920drpluem * Found the generic group entry... but the user isn't in this
8445dae5cc606ba8ba04efc341cc1e081d95920drpluem * group or we wouldn't be here.
0e05808dc59a321566303084c84b9826a4353cefrederpj /* Make a local copy of the subgroup list */
9efd5708f6f0ab1992f6a5233eb622ad5e4eae18sf "Making local copy of SGL for "
0e05808dc59a321566303084c84b9826a4353cefrederpj "group (%s)(objectClass=%s) ",
0e05808dc59a321566303084c84b9826a4353cefrederpj tmp_local_sgl->len = compare_nodep->subgroupList->len;
0e05808dc59a321566303084c84b9826a4353cefrederpj for (i = 0; i < compare_nodep->subgroupList->len; i++) {
85da6b76d07b7af570cbbec208a87697ba9c44f5rederpj /* No Cached SGL, retrieve from LDAP */
8445dae5cc606ba8ba04efc341cc1e081d95920drpluem tmp_local_sgl = uldap_get_subgroups(r, ldc, url, dn, subgroupAttrs,
85da6b76d07b7af570cbbec208a87697ba9c44f5rederpj /* No SGL aailable via LDAP either */
9efd5708f6f0ab1992f6a5233eb622ad5e4eae18sf ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, "no subgroups for %s",
8445dae5cc606ba8ba04efc341cc1e081d95920drpluem * Find the generic group cache entry and add the sgl we just retrieved.
85da6b76d07b7af570cbbec208a87697ba9c44f5rederpj the_compare_node.value = (char *)sgc_ents[base_sgcIndex].name;
8445dae5cc606ba8ba04efc341cc1e081d95920drpluem compare_nodep = util_ald_cache_fetch(curl->compare_cache,
0e05808dc59a321566303084c84b9826a4353cefrederpj * The group entry we want to attach our SGL to doesn't exist.
0e05808dc59a321566303084c84b9826a4353cefrederpj * We only got here if we verified this DN was actually a group
0e05808dc59a321566303084c84b9826a4353cefrederpj * based on the objectClass, but we can't call the compare function
0e05808dc59a321566303084c84b9826a4353cefrederpj * while we already hold the cache lock -- only the insert.
0e05808dc59a321566303084c84b9826a4353cefrederpj util_ald_cache_insert(curl->compare_cache, &the_compare_node);
0e05808dc59a321566303084c84b9826a4353cefrederpj compare_nodep = util_ald_cache_fetch(curl->compare_cache,
9efd5708f6f0ab1992f6a5233eb622ad5e4eae18sf "util_ldap: Couldn't retrieve group entry "
9efd5708f6f0ab1992f6a5233eb622ad5e4eae18sf "for %s from cache",
0e05808dc59a321566303084c84b9826a4353cefrederpj * We have a valid cache entry and a locally generated SGL.
0e05808dc59a321566303084c84b9826a4353cefrederpj * Attach the SGL to the cache entry
0e05808dc59a321566303084c84b9826a4353cefrederpj if (compare_nodep && !compare_nodep->sgl_processed) {
0e05808dc59a321566303084c84b9826a4353cefrederpj /* We looked up an SGL for a group and found it to be empty */
0e05808dc59a321566303084c84b9826a4353cefrederpj util_ald_sgl_dup(curl->compare_cache, tmp_local_sgl);
0e05808dc59a321566303084c84b9826a4353cefrederpj "Copying local SGL of len %d for group %s into cache",
0e05808dc59a321566303084c84b9826a4353cefrederpj "Copy of SGL failed to obtain shared memory, "
0e05808dc59a321566303084c84b9826a4353cefrederpj "couldn't update cache");
8445dae5cc606ba8ba04efc341cc1e081d95920drpluem * tmp_local_sgl has either been created, or copied out of the cache
8445dae5cc606ba8ba04efc341cc1e081d95920drpluem * If tmp_local_sgl is NULL, there are no subgroups to process and we'll
8445dae5cc606ba8ba04efc341cc1e081d95920drpluem * return false
85da6b76d07b7af570cbbec208a87697ba9c44f5rederpj while ((result != LDAP_COMPARE_TRUE) && (sgindex < tmp_local_sgl->len)) {
8445dae5cc606ba8ba04efc341cc1e081d95920drpluem * 4. Now loop through the subgroupList and call uldap_cache_compare
8445dae5cc606ba8ba04efc341cc1e081d95920drpluem * to check for the user.
85da6b76d07b7af570cbbec208a87697ba9c44f5rederpj result = uldap_cache_compare(r, ldc, url, group, attrib, value);
8445dae5cc606ba8ba04efc341cc1e081d95920drpluem * 4.A. We found the user in the subgroup. Return
8445dae5cc606ba8ba04efc341cc1e081d95920drpluem * LDAP_COMPARE_TRUE.
9efd5708f6f0ab1992f6a5233eb622ad5e4eae18sf "Found user %s in a subgroup (%s) at level %d of %d.",
8445dae5cc606ba8ba04efc341cc1e081d95920drpluem * 4.B. We didn't find the user in this subgroup, so recurse into
8445dae5cc606ba8ba04efc341cc1e081d95920drpluem * it and keep looking.
9efd5708f6f0ab1992f6a5233eb622ad5e4eae18sf "User %s not found in subgroup (%s) at level %d of "
85da6b76d07b7af570cbbec208a87697ba9c44f5rederpj result = uldap_cache_check_subgroups(r, ldc, url, group, attrib,
8113dac419143273351446c3ad653f3fe5ba5cfdwrowestatic int uldap_cache_checkuserid(request_rec *r, util_ldap_connection_t *ldc,
8113dac419143273351446c3ad653f3fe5ba5cfdwrowe const char ***retvals)
f05787953018140838ad51456c86c965d6a86267jim util_search_node_t *search_nodep; /* Cached search node */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes (util_ldap_state_t *)ap_get_module_config(r->server->module_config,
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes /* Get the cache node for this url */
e8f95a682820a599fe41b22977010636be5c2717jim curl = (util_url_node_t *)util_ald_cache_fetch(st->util_ldap_cache,
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes /* found entry in search cache... */
e8f95a682820a599fe41b22977010636be5c2717jim * Remove this item from the cache if its expired. If the sent
e8f95a682820a599fe41b22977010636be5c2717jim * password doesn't match the storepassword, the entry will
e8f95a682820a599fe41b22977010636be5c2717jim * be removed and readded later if the credentials pass
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe * authentication.
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes if ((curtime - search_nodep->lastbind) > st->search_cache_ttl) {
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes /* ...but entry is too old */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes util_ald_cache_remove(curl->search_cache, search_nodep);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes /* ...and entry is valid */
d64dd2fd4516c2b1b664c5e59c0628d9aff26984covener *retvals = apr_pcalloc(r->pool, sizeof(char *) * search_nodep->numvals);
d64dd2fd4516c2b1b664c5e59c0628d9aff26984covener (*retvals)[i] = apr_pstrdup(r->pool, search_nodep->vals[i]);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes ldc->reason = "Authentication successful (cached)";
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes /* unlock this read lock */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * At this point, there is no valid cached search, so lets do the search.
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe * If LDAP operation fails due to LDAP_SERVER_DOWN, control returns here.
f43b67c5a9d29b572eac916f8335cedc80c908bebnicholes if (LDAP_SUCCESS != (result = uldap_connection_open(r, ldc))) {
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes /* try do the search */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes ldc->reason = "ldap_search_ext_s() for user failed with server down";
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes /* if there is an error (including LDAP_NO_SUCH_OBJECT) return now */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes ldc->reason = "ldap_search_ext_s() for user failed";
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * We should have found exactly one entry; to find a different
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * number is an error.
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe "or more matches)";
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes /* Grab the dn, copy it into the pool, and free it again */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * A bind to the server with an empty password always succeeds, so
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * we check to ensure that the password is not empty. This implies
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * that users who actually do have empty passwords will never be
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * able to authenticate with this module. I don't see this as a big
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * Attempt to bind with the retrieved dn and the password. If the bind
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * fails, it means that the password is wrong (the dn obviously
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * exists, since we just retrieved it)
7dbf29be626018bc389ef94c1846aeac4b72633bsf result = uldap_simple_bind(ldc, (char *)*binddn, (char *)bindpw,
7dbf29be626018bc389ef94c1846aeac4b72633bsf ldc->reason = "ldap_simple_bind() to check user credentials "
7dbf29be626018bc389ef94c1846aeac4b72633bsf "failed with server down";
7dbf29be626018bc389ef94c1846aeac4b72633bsf ldc->reason = "ldap_simple_bind() to check user credentials "
7dbf29be626018bc389ef94c1846aeac4b72633bsf "timed out";
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes /* failure? if so - return */
7dbf29be626018bc389ef94c1846aeac4b72633bsf ldc->reason = "ldap_simple_bind() to check user credentials failed";
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * We have just bound the connection to a different user and password
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * combination, which might be reused unintentionally next time this
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * connection is used from the connection pool. To ensure no confusion,
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * we mark the connection as unbound.
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * Get values for the provided attributes.
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes while (attrs[k++]);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes vals = apr_pcalloc(r->pool, sizeof(char *) * (k+1));
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes while (attrs[i]) {
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes /* get values */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes values = ldap_get_values(ldc->ldap, entry, attrs[i]);
e8f95a682820a599fe41b22977010636be5c2717jim str = str ? apr_pstrcat(r->pool, str, "; ", values[j], NULL)
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * Add the new username to the search cache.
e8f95a682820a599fe41b22977010636be5c2717jim /* Search again to make sure that another thread didn't ready insert
e8f95a682820a599fe41b22977010636be5c2717jim * this node into the cache before we got here. If it does exist then
e8f95a682820a599fe41b22977010636be5c2717jim * update the lastbind
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes /* Nothing in cache, insert new entry */
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes util_ald_cache_insert(curl->search_cache, &the_search_node);
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes /* Entry in cache is invalid, remove it and insert new one */
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes util_ald_cache_remove(curl->search_cache, search_nodep);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes util_ald_cache_insert(curl->search_cache, &the_search_node);
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes /* Cache entry is valid, update lastbind */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes search_nodep->lastbind = the_search_node.lastbind;
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes * This function will return the DN of the entry matching userid.
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes * It is used to get the DN in case some other module than mod_auth_ldap
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes * has authenticated the user.
f43b67c5a9d29b572eac916f8335cedc80c908bebnicholes * The function is basically a copy of uldap_cache_checkuserid
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes * with password checking removed.
8113dac419143273351446c3ad653f3fe5ba5cfdwrowestatic int uldap_cache_getuserdn(request_rec *r, util_ldap_connection_t *ldc,
f05787953018140838ad51456c86c965d6a86267jim util_search_node_t *search_nodep; /* Cached search node */
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes (util_ldap_state_t *)ap_get_module_config(r->server->module_config,
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes /* Get the cache node for this url */
e8f95a682820a599fe41b22977010636be5c2717jim curl = (util_url_node_t *)util_ald_cache_fetch(st->util_ldap_cache,
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes /* found entry in search cache... */
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes * Remove this item from the cache if its expired.
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes if ((curtime - search_nodep->lastbind) > st->search_cache_ttl) {
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes /* ...but entry is too old */
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes util_ald_cache_remove(curl->search_cache, search_nodep);
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes /* ...and entry is valid */
d64dd2fd4516c2b1b664c5e59c0628d9aff26984covener *retvals = apr_pcalloc(r->pool, sizeof(char *) * search_nodep->numvals);
d64dd2fd4516c2b1b664c5e59c0628d9aff26984covener (*retvals)[i] = apr_pstrdup(r->pool, search_nodep->vals[i]);
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes /* unlock this read lock */
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes * At this point, there is no valid cached search, so lets do the search.
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe * If LDAP operation fails due to LDAP_SERVER_DOWN, control returns here.
f43b67c5a9d29b572eac916f8335cedc80c908bebnicholes if (LDAP_SUCCESS != (result = uldap_connection_open(r, ldc))) {
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes /* try do the search */
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes ldc->reason = "ldap_search_ext_s() for user failed with server down";
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes /* if there is an error (including LDAP_NO_SUCH_OBJECT) return now */
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes ldc->reason = "ldap_search_ext_s() for user failed";
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes * We should have found exactly one entry; to find a different
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes * number is an error.
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe "or more matches)";
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes /* Grab the dn, copy it into the pool, and free it again */
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes * Get values for the provided attributes.
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes while (attrs[k++]);
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes vals = apr_pcalloc(r->pool, sizeof(char *) * (k+1));
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes while (attrs[i]) {
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes /* get values */
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes values = ldap_get_values(ldc->ldap, entry, attrs[i]);
e8f95a682820a599fe41b22977010636be5c2717jim str = str ? apr_pstrcat(r->pool, str, "; ", values[j], NULL)
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes * Add the new username to the search cache.
e8f95a682820a599fe41b22977010636be5c2717jim /* Search again to make sure that another thread didn't ready insert
e8f95a682820a599fe41b22977010636be5c2717jim * this node into the cache before we got here. If it does exist then
e8f95a682820a599fe41b22977010636be5c2717jim * update the lastbind
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe search_nodep = util_ald_cache_fetch(curl->search_cache,
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes /* Nothing in cache, insert new entry */
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes util_ald_cache_insert(curl->search_cache, &the_search_node);
0c8aa496e9d7676ff8101783398f17c0da1900f7bnicholes * Don't update lastbind on entries with bindpw because
0c8aa496e9d7676ff8101783398f17c0da1900f7bnicholes * we haven't verified that password. It's OK to update
0c8aa496e9d7676ff8101783398f17c0da1900f7bnicholes * the entry if there is no password in it.
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes /* Cache entry is valid, update lastbind */
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes search_nodep->lastbind = the_search_node.lastbind;
e8f95a682820a599fe41b22977010636be5c2717jim * Reports if ssl support is enabled
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * 1 = enabled, 0 = not enabled
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes util_ldap_state_t *st = (util_ldap_state_t *)ap_get_module_config(
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes/* ---------------------------------------- */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes/* config directives */
e8f95a682820a599fe41b22977010636be5c2717jimstatic const char *util_ldap_set_cache_bytes(cmd_parms *cmd, void *dummy,
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe const char *bytes)
e8f95a682820a599fe41b22977010636be5c2717jim (util_ldap_state_t *)ap_get_module_config(cmd->server->module_config,
3effb85eb3124c6f02cd89e22ffed0fc9afaddb9bnicholes const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
9efd5708f6f0ab1992f6a5233eb622ad5e4eae18sf "ldap cache: Setting shared memory cache size to "
e8f95a682820a599fe41b22977010636be5c2717jimstatic const char *util_ldap_set_cache_file(cmd_parms *cmd, void *dummy,
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe const char *file)
e8f95a682820a599fe41b22977010636be5c2717jim (util_ldap_state_t *)ap_get_module_config(cmd->server->module_config,
3effb85eb3124c6f02cd89e22ffed0fc9afaddb9bnicholes const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes st->cache_file = ap_server_root_relative(st->pool, file);
e8f95a682820a599fe41b22977010636be5c2717jim "LDAP cache: Setting shared memory cache file to %s bytes.",
e8f95a682820a599fe41b22977010636be5c2717jimstatic const char *util_ldap_set_cache_ttl(cmd_parms *cmd, void *dummy,
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe const char *ttl)
e8f95a682820a599fe41b22977010636be5c2717jim (util_ldap_state_t *)ap_get_module_config(cmd->server->module_config,
3effb85eb3124c6f02cd89e22ffed0fc9afaddb9bnicholes const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
9efd5708f6f0ab1992f6a5233eb622ad5e4eae18sf "ldap cache: Setting cache TTL to %ld microseconds.",
e8f95a682820a599fe41b22977010636be5c2717jimstatic const char *util_ldap_set_cache_entries(cmd_parms *cmd, void *dummy,
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe const char *size)
e8f95a682820a599fe41b22977010636be5c2717jim (util_ldap_state_t *)ap_get_module_config(cmd->server->module_config,
3effb85eb3124c6f02cd89e22ffed0fc9afaddb9bnicholes const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
9efd5708f6f0ab1992f6a5233eb622ad5e4eae18sf "ldap cache: Setting search cache size to %ld entries.",
e8f95a682820a599fe41b22977010636be5c2717jimstatic const char *util_ldap_set_opcache_ttl(cmd_parms *cmd, void *dummy,
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe const char *ttl)
e8f95a682820a599fe41b22977010636be5c2717jim (util_ldap_state_t *)ap_get_module_config(cmd->server->module_config,
3effb85eb3124c6f02cd89e22ffed0fc9afaddb9bnicholes const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
9efd5708f6f0ab1992f6a5233eb622ad5e4eae18sf "ldap cache: Setting operation cache TTL to %ld microseconds.",
e8f95a682820a599fe41b22977010636be5c2717jimstatic const char *util_ldap_set_opcache_entries(cmd_parms *cmd, void *dummy,
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe const char *size)
e8f95a682820a599fe41b22977010636be5c2717jim (util_ldap_state_t *)ap_get_module_config(cmd->server->module_config,
3effb85eb3124c6f02cd89e22ffed0fc9afaddb9bnicholes const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
9efd5708f6f0ab1992f6a5233eb622ad5e4eae18sf "ldap cache: Setting operation cache size to %ld entries.",
54d22ed1c429b903b029bbd62621f11a9e286137minfrin * Parse the certificate type.
54d22ed1c429b903b029bbd62621f11a9e286137minfrin * The type can be one of the following:
54d22ed1c429b903b029bbd62621f11a9e286137minfrin * CA_DER, CA_BASE64, CA_CERT7_DB, CA_SECMOD, CERT_DER, CERT_BASE64,
54d22ed1c429b903b029bbd62621f11a9e286137minfrin * CERT_KEY3_DB, CERT_NICKNAME, KEY_DER, KEY_BASE64
54d22ed1c429b903b029bbd62621f11a9e286137minfrin * If no matches are found, APR_LDAP_CA_TYPE_UNKNOWN is returned.
88adce5ec0da39b41450ce1d5a77659168097e0cjortonstatic int util_ldap_parse_cert_type(const char *type)
54d22ed1c429b903b029bbd62621f11a9e286137minfrin /* Authority file in binary DER format */
54d22ed1c429b903b029bbd62621f11a9e286137minfrin /* Authority file in Base64 format */
54d22ed1c429b903b029bbd62621f11a9e286137minfrin /* Netscape certificate database file/directory */
54d22ed1c429b903b029bbd62621f11a9e286137minfrin /* Netscape secmod file/directory */
54d22ed1c429b903b029bbd62621f11a9e286137minfrin /* Client cert file in DER format */
54d22ed1c429b903b029bbd62621f11a9e286137minfrin /* Client cert file in Base64 format */
09338db7fdcf82ecc189195347da3a3ed5d0287abnicholes /* Client cert file in PKCS#12 format */
54d22ed1c429b903b029bbd62621f11a9e286137minfrin /* Netscape client cert database file/directory */
54d22ed1c429b903b029bbd62621f11a9e286137minfrin /* Netscape client cert nickname */
54d22ed1c429b903b029bbd62621f11a9e286137minfrin /* Client cert key file in DER format */
54d22ed1c429b903b029bbd62621f11a9e286137minfrin /* Client cert key file in Base64 format */
09338db7fdcf82ecc189195347da3a3ed5d0287abnicholes /* Client cert key file in PKCS#12 format */
54d22ed1c429b903b029bbd62621f11a9e286137minfrin * Set LDAPTrustedGlobalCert.
54d22ed1c429b903b029bbd62621f11a9e286137minfrin * This directive takes either two or three arguments:
54d22ed1c429b903b029bbd62621f11a9e286137minfrin * - certificate type
54d22ed1c429b903b029bbd62621f11a9e286137minfrin * - certificate file / directory / nickname
54d22ed1c429b903b029bbd62621f11a9e286137minfrin * - certificate password (optional)
54d22ed1c429b903b029bbd62621f11a9e286137minfrin * This directive may only be used globally.
e8f95a682820a599fe41b22977010636be5c2717jimstatic const char *util_ldap_set_trusted_global_cert(cmd_parms *cmd,
e8f95a682820a599fe41b22977010636be5c2717jim const char *type,
e8f95a682820a599fe41b22977010636be5c2717jim const char *file,
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe const char *password)
54d22ed1c429b903b029bbd62621f11a9e286137minfrin (util_ldap_state_t *)ap_get_module_config(cmd->server->module_config,
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
54d22ed1c429b903b029bbd62621f11a9e286137minfrin /* handle the certificate type */
54d22ed1c429b903b029bbd62621f11a9e286137minfrin return apr_psprintf(cmd->pool, "The certificate type %s is "
54d22ed1c429b903b029bbd62621f11a9e286137minfrin "not recognised. It should be one "
54d22ed1c429b903b029bbd62621f11a9e286137minfrin "of CA_DER, CA_BASE64, CA_CERT7_DB, "
54d22ed1c429b903b029bbd62621f11a9e286137minfrin "CA_SECMOD, CERT_DER, CERT_BASE64, "
54d22ed1c429b903b029bbd62621f11a9e286137minfrin "CERT_KEY3_DB, CERT_NICKNAME, "
54d22ed1c429b903b029bbd62621f11a9e286137minfrin return "Certificate type was not specified.";
796e4a7141265d8ed7036e4628161c6eafb2a789jorton ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, cmd->server,
54d22ed1c429b903b029bbd62621f11a9e286137minfrin "LDAP: SSL trusted global cert - %s (type %s)",
54d22ed1c429b903b029bbd62621f11a9e286137minfrin /* add the certificate to the global array */
d5cff0d8e871bf2528aadd8736fb50dc044b1e6dbnicholes cert = (apr_ldap_opt_tls_cert_t *)apr_array_push(st->global_certs);
54d22ed1c429b903b029bbd62621f11a9e286137minfrin /* if file is a file or path, fix the path */
54d22ed1c429b903b029bbd62621f11a9e286137minfrin cert->path = ap_server_root_relative(cmd->pool, file);
e8f95a682820a599fe41b22977010636be5c2717jim ((rv = apr_stat (&finfo, cert->path, APR_FINFO_MIN, cmd->pool))
54d22ed1c429b903b029bbd62621f11a9e286137minfrin ap_log_error(APLOG_MARK, APLOG_ERR, rv, cmd->server,
54d22ed1c429b903b029bbd62621f11a9e286137minfrin "LDAP: Could not open SSL trusted certificate "
54d22ed1c429b903b029bbd62621f11a9e286137minfrin "authority file - %s",
54d22ed1c429b903b029bbd62621f11a9e286137minfrin return "Invalid global certificate file path";
54d22ed1c429b903b029bbd62621f11a9e286137minfrin * Set LDAPTrustedClientCert.
54d22ed1c429b903b029bbd62621f11a9e286137minfrin * This directive takes either two or three arguments:
54d22ed1c429b903b029bbd62621f11a9e286137minfrin * - certificate type
54d22ed1c429b903b029bbd62621f11a9e286137minfrin * - certificate file / directory / nickname
54d22ed1c429b903b029bbd62621f11a9e286137minfrin * - certificate password (optional)
e8f95a682820a599fe41b22977010636be5c2717jimstatic const char *util_ldap_set_trusted_client_cert(cmd_parms *cmd,
e8f95a682820a599fe41b22977010636be5c2717jim const char *type,
e8f95a682820a599fe41b22977010636be5c2717jim const char *file,
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe const char *password)
54d22ed1c429b903b029bbd62621f11a9e286137minfrin /* handle the certificate type */
54d22ed1c429b903b029bbd62621f11a9e286137minfrin return apr_psprintf(cmd->pool, "The certificate type \"%s\" is "
54d22ed1c429b903b029bbd62621f11a9e286137minfrin "not recognised. It should be one "
ae1981fc94adf2b231e2d0e15d2f895b2138c969covener "of CA_DER, CA_BASE64, "
ae1981fc94adf2b231e2d0e15d2f895b2138c969covener "CERT_DER, CERT_BASE64, "
ae1981fc94adf2b231e2d0e15d2f895b2138c969covener "CERT_NICKNAME, CERT_PFX, "
e8f95a682820a599fe41b22977010636be5c2717jim "KEY_DER, KEY_BASE64, KEY_PFX",
54d22ed1c429b903b029bbd62621f11a9e286137minfrin return apr_psprintf(cmd->pool, "The certificate type \"%s\" is "
54d22ed1c429b903b029bbd62621f11a9e286137minfrin "only valid within a "
54d22ed1c429b903b029bbd62621f11a9e286137minfrin "LDAPTrustedGlobalCert directive. "
ae1981fc94adf2b231e2d0e15d2f895b2138c969covener "Only CA_DER, CA_BASE64, "
ae1981fc94adf2b231e2d0e15d2f895b2138c969covener "CERT_DER, CERT_BASE64, "
54d22ed1c429b903b029bbd62621f11a9e286137minfrin "CERT_NICKNAME, KEY_DER, and "
54d22ed1c429b903b029bbd62621f11a9e286137minfrin return "Certificate type was not specified.";
796e4a7141265d8ed7036e4628161c6eafb2a789jorton ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, cmd->server,
54d22ed1c429b903b029bbd62621f11a9e286137minfrin "LDAP: SSL trusted client cert - %s (type %s)",
ae1981fc94adf2b231e2d0e15d2f895b2138c969covener /* add the certificate to the client array */
ae1981fc94adf2b231e2d0e15d2f895b2138c969covener cert = (apr_ldap_opt_tls_cert_t *)apr_array_push(dc->client_certs);
54d22ed1c429b903b029bbd62621f11a9e286137minfrin /* if file is a file or path, fix the path */
54d22ed1c429b903b029bbd62621f11a9e286137minfrin cert->path = ap_server_root_relative(cmd->pool, file);
e8f95a682820a599fe41b22977010636be5c2717jim ((rv = apr_stat (&finfo, cert->path, APR_FINFO_MIN, cmd->pool))
54d22ed1c429b903b029bbd62621f11a9e286137minfrin ap_log_error(APLOG_MARK, APLOG_ERR, rv, cmd->server,
54d22ed1c429b903b029bbd62621f11a9e286137minfrin "LDAP: Could not open SSL client certificate "
54d22ed1c429b903b029bbd62621f11a9e286137minfrin "file - %s",
54d22ed1c429b903b029bbd62621f11a9e286137minfrin return "Invalid client certificate file path";
54d22ed1c429b903b029bbd62621f11a9e286137minfrin * Set LDAPTrustedMode.
54d22ed1c429b903b029bbd62621f11a9e286137minfrin * This directive sets what encryption mode to use on a connection:
54d22ed1c429b903b029bbd62621f11a9e286137minfrin * - None (No encryption)
54d22ed1c429b903b029bbd62621f11a9e286137minfrin * - SSL (SSL encryption)
54d22ed1c429b903b029bbd62621f11a9e286137minfrin * - STARTTLS (TLS encryption)
e8f95a682820a599fe41b22977010636be5c2717jimstatic const char *util_ldap_set_trusted_mode(cmd_parms *cmd, void *dummy,
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe const char *mode)
54d22ed1c429b903b029bbd62621f11a9e286137minfrin (util_ldap_state_t *)ap_get_module_config(cmd->server->module_config,
796e4a7141265d8ed7036e4628161c6eafb2a789jorton ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, cmd->server,
54d22ed1c429b903b029bbd62621f11a9e286137minfrin "LDAP: SSL trusted mode - %s",
54d22ed1c429b903b029bbd62621f11a9e286137minfrin return "Invalid LDAPTrustedMode setting: must be one of NONE, "
e8f95a682820a599fe41b22977010636be5c2717jimstatic const char *util_ldap_set_verify_srv_cert(cmd_parms *cmd,
141e1368614dc7564e1627671361b01b4869b491bnicholes (util_ldap_state_t *)ap_get_module_config(cmd->server->module_config,
cbbfa8f4222ecc7b2e0f16db3032d0118d6a0accbnicholes const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
796e4a7141265d8ed7036e4628161c6eafb2a789jorton ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, cmd->server,
e8f95a682820a599fe41b22977010636be5c2717jim "LDAP: SSL verify server certificate - %s",
e8f95a682820a599fe41b22977010636be5c2717jimstatic const char *util_ldap_set_connection_timeout(cmd_parms *cmd,
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe const char *ttl)
e8f95a682820a599fe41b22977010636be5c2717jim (util_ldap_state_t *)ap_get_module_config(cmd->server->module_config,
cbbfa8f4222ecc7b2e0f16db3032d0118d6a0accbnicholes const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
9efd5708f6f0ab1992f6a5233eb622ad5e4eae18sf "ldap connection: Setting connection timeout to %ld seconds.",
4990e910dd8574b9b40beda0cf1aaa72334d6837bnicholes ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, cmd->server,
d0fb19f6ddefe0d1b3c94eee44776a848ab0690drpluem "LDAP: Connection timeout option not supported by the "
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe "LDAP SDK in use." );
9ad7b260be233be7d7b5576979825cac72e15498rederpjstatic const char *util_ldap_set_chase_referrals(cmd_parms *cmd,
9ad7b260be233be7d7b5576979825cac72e15498rederpj ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, cmd->server,
cb304b0c01e893dc2c24ee83ca382d8a6861d0e4trawick "LDAP: Setting referral chasing %s",
128a5d93141a86e3afa151e921035a07297c9833rederpj (mode == AP_LDAP_CHASEREFERRALS_ON) ? "ON" : "OFF");
0f60998368b493f90120180a93fc2e1e74490872covenerstatic const char *util_ldap_set_debug_level(cmd_parms *cmd,
0f60998368b493f90120180a93fc2e1e74490872covener const char *arg) {
0f60998368b493f90120180a93fc2e1e74490872covener (util_ldap_state_t *)ap_get_module_config(cmd->server->module_config,
0f60998368b493f90120180a93fc2e1e74490872covener const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
0f60998368b493f90120180a93fc2e1e74490872covener return "This directive is not supported with the currently linked LDAP library";
9ad7b260be233be7d7b5576979825cac72e15498rederpjstatic const char *util_ldap_set_referral_hop_limit(cmd_parms *cmd,
9ad7b260be233be7d7b5576979825cac72e15498rederpj const char *hop_limit)
67c5e190a7b84528b8895d7ef7be81712d206805covener return "LDAPReferralHopLimit must be greater than zero (Use 'LDAPReferrals Off' to disable referral chasing)";
9ad7b260be233be7d7b5576979825cac72e15498rederpj ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, cmd->server,
9ad7b260be233be7d7b5576979825cac72e15498rederpj "LDAP: Limit chased referrals to maximum of %d hops.",
9ad7b260be233be7d7b5576979825cac72e15498rederpjstatic void *util_ldap_create_dir_config(apr_pool_t *p, char *d) {
9ad7b260be233be7d7b5576979825cac72e15498rederpj (util_ldap_config_t *) apr_pcalloc(p,sizeof(util_ldap_config_t));
128a5d93141a86e3afa151e921035a07297c9833rederpj /* defaults are AP_LDAP_CHASEREFERRALS_ON and AP_LDAP_DEFAULT_HOPLIMIT */
ae1981fc94adf2b231e2d0e15d2f895b2138c969covener dc->client_certs = apr_array_make(p, 10, sizeof(apr_ldap_opt_tls_cert_t));
4be9c459920a7c1cfe62d654327dae5c4bb6b284sfstatic const char *util_ldap_set_op_timeout(cmd_parms *cmd,
4be9c459920a7c1cfe62d654327dae5c4bb6b284sf const char *val)
4be9c459920a7c1cfe62d654327dae5c4bb6b284sf (util_ldap_state_t *)ap_get_module_config(cmd->server->module_config,
4be9c459920a7c1cfe62d654327dae5c4bb6b284sf const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
4be9c459920a7c1cfe62d654327dae5c4bb6b284sf return "Timeout not numerical";
4be9c459920a7c1cfe62d654327dae5c4bb6b284sf return "Timeout must be non-negative";
4be9c459920a7c1cfe62d654327dae5c4bb6b284sf st->opTimeout = apr_pcalloc(cmd->pool, sizeof(struct timeval));
9efd5708f6f0ab1992f6a5233eb622ad5e4eae18sf "ldap connection: Setting op timeout to %ld seconds.",
4be9c459920a7c1cfe62d654327dae5c4bb6b284sf "LDAP: LDAP_OPT_TIMEOUT option not supported by the "
4be9c459920a7c1cfe62d654327dae5c4bb6b284sf "LDAP library in use. Using LDAPTimeout value as search "
4be9c459920a7c1cfe62d654327dae5c4bb6b284sf "timeout only." );
8113dac419143273351446c3ad653f3fe5ba5cfdwrowestatic void *util_ldap_create_config(apr_pool_t *p, server_rec *s)
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes (util_ldap_state_t *)apr_pcalloc(p, sizeof(util_ldap_state_t));
a0b44ec81b32ffb946537d4e43e1c3a3f7594137gregames /* Create a per vhost pool for mod_ldap to use, serialized with
1233ffe2092021833c2a642f1017d6c332075469gregames * st->mutex (also one per vhost). both are replicated by fork(),
1233ffe2092021833c2a642f1017d6c332075469gregames * no shared memory managed by either.
490046d2a164ad86cc63bd789f32eaed663d239abnicholes apr_thread_mutex_create(&st->mutex, APR_THREAD_MUTEX_DEFAULT, st->pool);
54d22ed1c429b903b029bbd62621f11a9e286137minfrin st->global_certs = apr_array_make(p, 10, sizeof(apr_ldap_opt_tls_cert_t));
f2386b627177c7a80d38fed6ec0aed3c086909c1covener/* cache-related settings are not merged here, but in the post_config hook,
f2386b627177c7a80d38fed6ec0aed3c086909c1covener * since the cache has not yet sprung to life
e8f95a682820a599fe41b22977010636be5c2717jimstatic void *util_ldap_merge_config(apr_pool_t *p, void *basev,
54d22ed1c429b903b029bbd62621f11a9e286137minfrin util_ldap_state_t *st = apr_pcalloc(p, sizeof(util_ldap_state_t));
54d22ed1c429b903b029bbd62621f11a9e286137minfrin util_ldap_state_t *base = (util_ldap_state_t *) basev;
54d22ed1c429b903b029bbd62621f11a9e286137minfrin util_ldap_state_t *overrides = (util_ldap_state_t *) overridesv;
9c247afacdbb56fa794715f2ac218eb1cae39fe8bnicholes /* The cache settings can not be modified in a
9c247afacdbb56fa794715f2ac218eb1cae39fe8bnicholes virtual host since all server use the same
9c247afacdbb56fa794715f2ac218eb1cae39fe8bnicholes shared memory cache. */
9ab5933c174cb21de69e8305f80544cbe7ed2a7ccovener st->util_ldap_cache_lock = base->util_ldap_cache_lock;
e8f95a682820a599fe41b22977010636be5c2717jim st->global_certs = apr_array_append(p, base->global_certs,
e8f95a682820a599fe41b22977010636be5c2717jim st->secure = (overrides->secure_set == 0) ? base->secure
cbbfa8f4222ecc7b2e0f16db3032d0118d6a0accbnicholes /* These LDAP connection settings can not be overwritten in
cbbfa8f4222ecc7b2e0f16db3032d0118d6a0accbnicholes a virtual host. Once set in the base server, they must
cbbfa8f4222ecc7b2e0f16db3032d0118d6a0accbnicholes remain the same. None of the LDAP SDKs seem to be able
cbbfa8f4222ecc7b2e0f16db3032d0118d6a0accbnicholes to handle setting the verify_svr_cert flag on a
cbbfa8f4222ecc7b2e0f16db3032d0118d6a0accbnicholes per-connection basis. The OpenLDAP client appears to be
cbbfa8f4222ecc7b2e0f16db3032d0118d6a0accbnicholes able to handle the connection timeout per-connection
cbbfa8f4222ecc7b2e0f16db3032d0118d6a0accbnicholes but the Novell SDK cannot. Allowing the timeout to
cbbfa8f4222ecc7b2e0f16db3032d0118d6a0accbnicholes be set by each vhost is of little value so rather than
cbbfa8f4222ecc7b2e0f16db3032d0118d6a0accbnicholes trying to make special expections for one LDAP SDK, GLOBAL_ONLY
cbbfa8f4222ecc7b2e0f16db3032d0118d6a0accbnicholes is being enforced on this setting as well. */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholesstatic apr_status_t util_ldap_cleanup_module(void *data)
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes util_ldap_state_t *st = (util_ldap_state_t *)ap_get_module_config(
11f2c481e1d57bedb3f758565307501e9a2730ddtrawickstatic int util_ldap_pre_config(apr_pool_t *pconf, apr_pool_t *plog,
43997561b2302d13dee973998e77743a3ddd2374trawick result = ap_mutex_register(pconf, ldap_cache_mutex_type, NULL,
e8f95a682820a599fe41b22977010636be5c2717jimstatic int util_ldap_post_config(apr_pool_t *p, apr_pool_t *plog,
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes /* util_ldap_post_config() will be called twice. Don't bother
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * going through all of the initialization on the first call
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * because it will just be thrown away.*/
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes apr_pool_userdata_get(&data, userdata_key, s->process->pool);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes apr_pool_userdata_set((const void *)1, userdata_key,
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes /* If the cache file already exists then delete it. Otherwise we are
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * going to run into problems creating the shared memory. */
490046d2a164ad86cc63bd789f32eaed663d239abnicholes char *lck_file = apr_pstrcat(ptemp, st->cache_file, ".lck",
e8f95a682820a599fe41b22977010636be5c2717jim /* initializing cache if shared memory size is not zero and we already
e8f95a682820a599fe41b22977010636be5c2717jim * don't have shm address
e70cf415769ad0b3704e98b3f6da38e916ff7228jorton "LDAP cache: could not create shared memory segment");
024e70e05386a6367eb45d0d1cc406764520ff4cwrowe result = ap_global_mutex_create(&st->util_ldap_cache_lock, NULL,
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes /* merge config in all vhost */
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe "LDAP merging Shared Cache conf: shm=0x%pp rmm=0x%pp "
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe "LDAP cache: LDAPSharedCacheSize is zero, disabling "
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe "shared memory cache");
e8f95a682820a599fe41b22977010636be5c2717jim /* log the LDAP SDK used
e70cf415769ad0b3704e98b3f6da38e916ff7228jorton ap_log_error(APLOG_MARK, APLOG_INFO, 0, s, "%s", result->reason);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes apr_pool_cleanup_register(p, s, util_ldap_cleanup_module,
54d22ed1c429b903b029bbd62621f11a9e286137minfrin * Initialize SSL support, and log the result for the benefit of the admin.
54d22ed1c429b903b029bbd62621f11a9e286137minfrin * If SSL is not supported it is not necessarily an error, as the
54d22ed1c429b903b029bbd62621f11a9e286137minfrin * application may not want to use it.
ebe5305f8b22507374358f32b74d12fb50c05a25covener rc = apr_ldap_set_option(ptemp, NULL, APR_LDAP_OPT_TLS_CERT,
e70cf415769ad0b3704e98b3f6da38e916ff7228jorton "LDAP: SSL support available" );
e70cf415769ad0b3704e98b3f6da38e916ff7228jorton "LDAP: SSL support unavailable%s%s",
f7edd56768a46a01ae8b43c712c9eeef40e37f59bnicholes /* Initialize the rebind callback's cross reference list. */
0f60998368b493f90120180a93fc2e1e74490872covener result = ldap_set_option(NULL, AP_LDAP_OPT_DEBUG, &st->debug_level);
0f60998368b493f90120180a93fc2e1e74490872covener "LDAP: Could not set the LDAP library debug level to %d:(%d) %s",
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholesstatic void util_ldap_child_init(apr_pool_t *p, server_rec *s)
e8f95a682820a599fe41b22977010636be5c2717jim util_ldap_state_t *st = ap_get_module_config(s->module_config,
e8f95a682820a599fe41b22977010636be5c2717jim sts = apr_global_mutex_child_init(&st->util_ldap_cache_lock,
11f2c481e1d57bedb3f758565307501e9a2730ddtrawick apr_global_mutex_lockfile(st->util_ldap_cache_lock), p);
9efd5708f6f0ab1992f6a5233eb622ad5e4eae18sf "Failed to initialise global mutex %s in child process",
e8f95a682820a599fe41b22977010636be5c2717jim AP_INIT_TAKE1("LDAPSharedCacheSize", util_ldap_set_cache_bytes,
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe "Set the size of the shared memory cache (in bytes). Use "
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe "0 to disable the shared memory cache. (default: 100000)"),
e8f95a682820a599fe41b22977010636be5c2717jim AP_INIT_TAKE1("LDAPSharedCacheFile", util_ldap_set_cache_file,
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe "Set the file name for the shared memory cache."),
e8f95a682820a599fe41b22977010636be5c2717jim AP_INIT_TAKE1("LDAPCacheEntries", util_ldap_set_cache_entries,
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe "Set the maximum number of entries that are possible in the "
023ab66b169a239c82d6c36410ab43fe63561d11covener "LDAP search cache. Use 0 or -1 to disable the search cache "
023ab66b169a239c82d6c36410ab43fe63561d11covener "(default: 1024)"),
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe "Set the maximum time (in seconds) that an item can be "
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe "cached in the LDAP search cache. Use 0 for no limit. "
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe "(default 600)"),
e8f95a682820a599fe41b22977010636be5c2717jim AP_INIT_TAKE1("LDAPOpCacheEntries", util_ldap_set_opcache_entries,
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe "Set the maximum number of entries that are possible "
023ab66b169a239c82d6c36410ab43fe63561d11covener "in the LDAP compare cache. Use 0 or -1 to disable the compare cache "
023ab66b169a239c82d6c36410ab43fe63561d11covener "(default: 1024)"),
e8f95a682820a599fe41b22977010636be5c2717jim AP_INIT_TAKE1("LDAPOpCacheTTL", util_ldap_set_opcache_ttl,
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe "Set the maximum time (in seconds) that an item is cached "
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe "in the LDAP operation cache. Use 0 for no limit. "
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe "(default: 600)"),
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe AP_INIT_TAKE23("LDAPTrustedGlobalCert", util_ldap_set_trusted_global_cert,
c99be08e59d6c21cdc4aa79f645feec41e157b09rederpj "Takes three arguments; the first argument is the cert "
c99be08e59d6c21cdc4aa79f645feec41e157b09rederpj "type of the second argument, one of CA_DER, CA_BASE64, "
c99be08e59d6c21cdc4aa79f645feec41e157b09rederpj "CA_CERT7_DB, CA_SECMOD, CERT_DER, CERT_BASE64, CERT_KEY3_DB, "
c99be08e59d6c21cdc4aa79f645feec41e157b09rederpj "CERT_NICKNAME, KEY_DER, or KEY_BASE64. The second argument "
c99be08e59d6c21cdc4aa79f645feec41e157b09rederpj "specifes the file and/or directory containing the trusted CA "
c99be08e59d6c21cdc4aa79f645feec41e157b09rederpj "certificates (and global client certs for Netware) used to "
c99be08e59d6c21cdc4aa79f645feec41e157b09rederpj "validate the LDAP server. The third argument is an optional "
c99be08e59d6c21cdc4aa79f645feec41e157b09rederpj "passphrase if applicable."),
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe AP_INIT_TAKE23("LDAPTrustedClientCert", util_ldap_set_trusted_client_cert,
c99be08e59d6c21cdc4aa79f645feec41e157b09rederpj "Takes three arguments: the first argument is the certificate "
c99be08e59d6c21cdc4aa79f645feec41e157b09rederpj "type of the second argument, one of CA_DER, CA_BASE64, "
c99be08e59d6c21cdc4aa79f645feec41e157b09rederpj "CA_CERT7_DB, CA_SECMOD, CERT_DER, CERT_BASE64, CERT_KEY3_DB, "
c99be08e59d6c21cdc4aa79f645feec41e157b09rederpj "CERT_NICKNAME, KEY_DER, or KEY_BASE64. The second argument "
c99be08e59d6c21cdc4aa79f645feec41e157b09rederpj "specifies the file and/or directory containing the client "
c99be08e59d6c21cdc4aa79f645feec41e157b09rederpj "certificate, or certificate ID used to validate this LDAP "
c99be08e59d6c21cdc4aa79f645feec41e157b09rederpj "client. The third argument is an optional passphrase if "
c99be08e59d6c21cdc4aa79f645feec41e157b09rederpj "applicable."),
e8f95a682820a599fe41b22977010636be5c2717jim AP_INIT_TAKE1("LDAPTrustedMode", util_ldap_set_trusted_mode,
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe "Specify the type of security that should be applied to "
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe "an LDAP connection. One of; NONE, SSL or STARTTLS."),
e8f95a682820a599fe41b22977010636be5c2717jim AP_INIT_FLAG("LDAPVerifyServerCert", util_ldap_set_verify_srv_cert,
8445dae5cc606ba8ba04efc341cc1e081d95920drpluem "Set to 'ON' requires that the server certificate be verified"
8445dae5cc606ba8ba04efc341cc1e081d95920drpluem " before a secure LDAP connection can be establish. Default"
e8f95a682820a599fe41b22977010636be5c2717jim AP_INIT_TAKE1("LDAPConnectionTimeout", util_ldap_set_connection_timeout,
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe "Specify the LDAP socket connection timeout in seconds "
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe "(default: 10)"),
9ad7b260be233be7d7b5576979825cac72e15498rederpj AP_INIT_FLAG("LDAPReferrals", util_ldap_set_chase_referrals,
9ad7b260be233be7d7b5576979825cac72e15498rederpj "Choose whether referrals are chased ['ON'|'OFF']. Default 'ON'"),
9ad7b260be233be7d7b5576979825cac72e15498rederpj AP_INIT_TAKE1("LDAPReferralHopLimit", util_ldap_set_referral_hop_limit,
9ad7b260be233be7d7b5576979825cac72e15498rederpj "Limit the number of referral hops that LDAP can follow. "
87587593f1a53030e840acc0dec6cc881022ea40covener "(Integer value, Consult LDAP SDK documentation for applicability and defaults"),
0f60998368b493f90120180a93fc2e1e74490872covener AP_INIT_TAKE1("LDAPLibraryDebug", util_ldap_set_debug_level,
0f60998368b493f90120180a93fc2e1e74490872covener "Enable debugging in LDAP SDK (Default: off, values: SDK specific"),
4be9c459920a7c1cfe62d654327dae5c4bb6b284sf "Specify the LDAP bind/search timeout in seconds "
4be9c459920a7c1cfe62d654327dae5c4bb6b284sf "(0 = no limit). Default: 60"),
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholesstatic void util_ldap_register_hooks(apr_pool_t *p)
f43b67c5a9d29b572eac916f8335cedc80c908bebnicholes APR_REGISTER_OPTIONAL_FN(uldap_connection_unbind);
f43b67c5a9d29b572eac916f8335cedc80c908bebnicholes APR_REGISTER_OPTIONAL_FN(uldap_connection_cleanup);
f43b67c5a9d29b572eac916f8335cedc80c908bebnicholes APR_REGISTER_OPTIONAL_FN(uldap_cache_checkuserid);
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj APR_REGISTER_OPTIONAL_FN(uldap_cache_check_subgroups);
11f2c481e1d57bedb3f758565307501e9a2730ddtrawick ap_hook_pre_config(util_ldap_pre_config, NULL, NULL, APR_HOOK_MIDDLE);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes ap_hook_post_config(util_ldap_post_config,NULL,NULL,APR_HOOK_MIDDLE);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes ap_hook_handler(util_ldap_handler, NULL, NULL, APR_HOOK_MIDDLE);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes ap_hook_child_init(util_ldap_child_init, NULL, NULL, APR_HOOK_MIDDLE);
9ad7b260be233be7d7b5576979825cac72e15498rederpj util_ldap_create_dir_config, /* create dir config */
f05787953018140838ad51456c86c965d6a86267jim util_ldap_register_hooks, /* set up request processing hooks */