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 *
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * http://www.apache.org/licenses/LICENSE-2.0
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes *
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 */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes/*
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * util_ldap.c: LDAP things
e8f95a682820a599fe41b22977010636be5c2717jim *
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 */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes#include "httpd.h"
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes#include "http_config.h"
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes#include "http_core.h"
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes#include "http_log.h"
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes#include "http_protocol.h"
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes#include "http_request.h"
11f2c481e1d57bedb3f758565307501e9a2730ddtrawick#include "util_mutex.h"
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes#include "util_ldap.h"
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes#include "util_ldap_cache.h"
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
5c0419d51818eb02045cf923a9fe456127a44c60wrowe#include <apr_strings.h>
5c0419d51818eb02045cf923a9fe456127a44c60wrowe
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes#if APR_HAVE_UNISTD_H
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes#include <unistd.h>
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes#endif
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes#if !APR_HAS_LDAP
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes#error mod_ldap requires APR-util to have LDAP support built in
d266c3777146d36a4c23c17aad6f153aebea1bf4jorton#endif
d266c3777146d36a4c23c17aad6f153aebea1bf4jorton
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.
22f8da8087791fcb95b836c8a81937c5a9bba202bnicholes */
22f8da8087791fcb95b836c8a81937c5a9bba202bnicholes#ifndef APR_LDAP_SIZELIMIT
22f8da8087791fcb95b836c8a81937c5a9bba202bnicholes#define APR_LDAP_SIZELIMIT -1
cd3bbd6d2df78d6c75e5d159a81ef8bdd5f70df9trawick#endif
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
0f60998368b493f90120180a93fc2e1e74490872covener#ifdef LDAP_OPT_DEBUG_LEVEL
0f60998368b493f90120180a93fc2e1e74490872covener#define AP_LDAP_OPT_DEBUG LDAP_OPT_DEBUG_LEVEL
0f60998368b493f90120180a93fc2e1e74490872covener#else
0f60998368b493f90120180a93fc2e1e74490872covener#ifdef LDAP_OPT_DEBUG
0f60998368b493f90120180a93fc2e1e74490872covener#define AP_LDAP_OPT_DEBUG LDAP_OPT_DEBUG
0f60998368b493f90120180a93fc2e1e74490872covener#endif
0f60998368b493f90120180a93fc2e1e74490872covener#endif
0f60998368b493f90120180a93fc2e1e74490872covener
87587593f1a53030e840acc0dec6cc881022ea40covener#define AP_LDAP_HOPLIMIT_UNSET -1
87587593f1a53030e840acc0dec6cc881022ea40covener#define AP_LDAP_CHASEREFERRALS_OFF 0
87587593f1a53030e840acc0dec6cc881022ea40covener#define AP_LDAP_CHASEREFERRALS_ON 1
87587593f1a53030e840acc0dec6cc881022ea40covener
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholesmodule AP_MODULE_DECLARE_DATA ldap_module;
43997561b2302d13dee973998e77743a3ddd2374trawickstatic const char *ldap_cache_mutex_type = "ldap-cache";
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
0568280364eb026393be492ebc732795c4934643jorton#define LDAP_CACHE_LOCK() do { \
0568280364eb026393be492ebc732795c4934643jorton if (st->util_ldap_cache_lock) \
0568280364eb026393be492ebc732795c4934643jorton apr_global_mutex_lock(st->util_ldap_cache_lock); \
0568280364eb026393be492ebc732795c4934643jorton} while (0)
0568280364eb026393be492ebc732795c4934643jorton
0568280364eb026393be492ebc732795c4934643jorton#define LDAP_CACHE_UNLOCK() do { \
0568280364eb026393be492ebc732795c4934643jorton if (st->util_ldap_cache_lock) \
0568280364eb026393be492ebc732795c4934643jorton apr_global_mutex_unlock(st->util_ldap_cache_lock); \
0568280364eb026393be492ebc732795c4934643jorton} while (0)
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
4e9c24785b525d2956e6e381015c0f2bd0a72f4bcovenerstatic apr_status_t util_ldap_connection_remove (void *param);
4e9c24785b525d2956e6e381015c0f2bd0a72f4bcovener
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholesstatic void util_ldap_strdup (char **str, const char *newstr)
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes{
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes if (*str) {
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes free(*str);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes *str = NULL;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes if (newstr) {
796e4a7141265d8ed7036e4628161c6eafb2a789jorton *str = strdup(newstr);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes}
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes/*
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * Status Handler
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * --------------
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes *
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * This handler generates a status page about the current performance of
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * the LDAP cache. It is enabled as follows:
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes *
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * <Location /ldap-status>
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * SetHandler ldap-status
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * </Location>
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes *
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes */
8113dac419143273351446c3ad653f3fe5ba5cfdwrowestatic int util_ldap_handler(request_rec *r)
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes{
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe util_ldap_state_t *st = (util_ldap_state_t *)
e8f95a682820a599fe41b22977010636be5c2717jim ap_get_module_config(r->server->module_config,
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe &ldap_module);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes r->allowed |= (1 << M_GET);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes if (r->method_number != M_GET)
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes return DECLINED;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes if (strcmp(r->handler, "ldap-status")) {
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes return DECLINED;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
a1790fb35c4b352dab721370985c623a9f8f5062rpluem ap_set_content_type(r, "text/html; charset=ISO-8859-1");
713a2b68bac4aeb1e9c48785006c0732451039depquerna
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes if (r->header_only)
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes return OK;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes ap_rputs(DOCTYPE_HTML_3_2
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);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes util_ald_cache_display(r, st);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes return OK;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes}
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
4e9c24785b525d2956e6e381015c0f2bd0a72f4bcovener/* ------------------------------------------------------------------ */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes/*
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.
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes */
8113dac419143273351446c3ad653f3fe5ba5cfdwrowestatic void uldap_connection_close(util_ldap_connection_t *ldc)
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes{
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes /*
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * QUESTION:
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes *
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 *
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * For now we unbind the user when we finish with a connection, but
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * we don't have to...
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
4e9c24785b525d2956e6e381015c0f2bd0a72f4bcovener if (!ldc->keep) {
4e9c24785b525d2956e6e381015c0f2bd0a72f4bcovener util_ldap_connection_remove(ldc);
4e9c24785b525d2956e6e381015c0f2bd0a72f4bcovener }
4e9c24785b525d2956e6e381015c0f2bd0a72f4bcovener else {
4e9c24785b525d2956e6e381015c0f2bd0a72f4bcovener /* mark our connection as available for reuse */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes#if APR_HAS_THREADS
4e9c24785b525d2956e6e381015c0f2bd0a72f4bcovener apr_thread_mutex_unlock(ldc->lock);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes#endif
4e9c24785b525d2956e6e381015c0f2bd0a72f4bcovener }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes}
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes/*
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.
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes */
8113dac419143273351446c3ad653f3fe5ba5cfdwrowestatic apr_status_t uldap_connection_unbind(void *param)
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes{
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes util_ldap_connection_t *ldc = param;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes if (ldc) {
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes if (ldc->ldap) {
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes ldap_unbind_s(ldc->ldap);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes ldc->ldap = NULL;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes ldc->bound = 0;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes return APR_SUCCESS;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes}
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes/*
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.
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes */
8113dac419143273351446c3ad653f3fe5ba5cfdwrowestatic apr_status_t uldap_connection_cleanup(void *param)
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes{
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes util_ldap_connection_t *ldc = param;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes if (ldc) {
9ad7b260be233be7d7b5576979825cac72e15498rederpj /* Release the rebind info for this connection. No more referral rebinds required. */
9ad7b260be233be7d7b5576979825cac72e15498rederpj apr_ldap_rebind_remove(ldc->ldap);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes /* unbind and disconnect from the LDAP server */
f43b67c5a9d29b572eac916f8335cedc80c908bebnicholes uldap_connection_unbind(ldc);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes /* free the username and password */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes if (ldc->bindpw) {
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes free((void*)ldc->bindpw);
f2be127030aa4190033084f0a6add531c9bc41desf ldc->bindpw = NULL;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes if (ldc->binddn) {
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes free((void*)ldc->binddn);
f2be127030aa4190033084f0a6add531c9bc41desf ldc->binddn = NULL;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
3e6d7277b90d3011db832139afc20efb5f17e203rederpj /* ldc->reason is allocated from r->pool */
3e6d7277b90d3011db832139afc20efb5f17e203rederpj if (ldc->reason) {
3e6d7277b90d3011db832139afc20efb5f17e203rederpj ldc->reason = NULL;
3e6d7277b90d3011db832139afc20efb5f17e203rederpj }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes /* unlock this entry */
f43b67c5a9d29b572eac916f8335cedc80c908bebnicholes uldap_connection_close(ldc);
e8f95a682820a599fe41b22977010636be5c2717jim
f2be127030aa4190033084f0a6add531c9bc41desf }
4e9c24785b525d2956e6e381015c0f2bd0a72f4bcovener
4e9c24785b525d2956e6e381015c0f2bd0a72f4bcovener return APR_SUCCESS;
4e9c24785b525d2956e6e381015c0f2bd0a72f4bcovener}
4e9c24785b525d2956e6e381015c0f2bd0a72f4bcovener
4e9c24785b525d2956e6e381015c0f2bd0a72f4bcovener/*
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 *
4e9c24785b525d2956e6e381015c0f2bd0a72f4bcovener * The caller should hold the lock for this connection
4e9c24785b525d2956e6e381015c0f2bd0a72f4bcovener */
4e9c24785b525d2956e6e381015c0f2bd0a72f4bcovenerstatic apr_status_t util_ldap_connection_remove (void *param) {
4e9c24785b525d2956e6e381015c0f2bd0a72f4bcovener util_ldap_connection_t *ldc = param, *l = NULL, *prev = NULL;
6683642c1e0032eeeed5f99e8c14880692ef84c5sf util_ldap_state_t *st;
4e9c24785b525d2956e6e381015c0f2bd0a72f4bcovener
4e9c24785b525d2956e6e381015c0f2bd0a72f4bcovener if (!ldc) return APR_SUCCESS;
4e9c24785b525d2956e6e381015c0f2bd0a72f4bcovener
6683642c1e0032eeeed5f99e8c14880692ef84c5sf st = ldc->st;
6683642c1e0032eeeed5f99e8c14880692ef84c5sf
4e9c24785b525d2956e6e381015c0f2bd0a72f4bcovener uldap_connection_unbind(ldc);
4e9c24785b525d2956e6e381015c0f2bd0a72f4bcovener
4e9c24785b525d2956e6e381015c0f2bd0a72f4bcovener#if APR_HAS_THREADS
4e9c24785b525d2956e6e381015c0f2bd0a72f4bcovener apr_thread_mutex_lock(st->mutex);
4e9c24785b525d2956e6e381015c0f2bd0a72f4bcovener#endif
4e9c24785b525d2956e6e381015c0f2bd0a72f4bcovener
4e9c24785b525d2956e6e381015c0f2bd0a72f4bcovener /* Remove ldc from the list */
4e9c24785b525d2956e6e381015c0f2bd0a72f4bcovener for (l=st->connections; l; l=l->next) {
4e9c24785b525d2956e6e381015c0f2bd0a72f4bcovener if (l == ldc) {
4e9c24785b525d2956e6e381015c0f2bd0a72f4bcovener if (prev) {
4e9c24785b525d2956e6e381015c0f2bd0a72f4bcovener prev->next = l->next;
4e9c24785b525d2956e6e381015c0f2bd0a72f4bcovener }
4e9c24785b525d2956e6e381015c0f2bd0a72f4bcovener else {
4e9c24785b525d2956e6e381015c0f2bd0a72f4bcovener st->connections = l->next;
4e9c24785b525d2956e6e381015c0f2bd0a72f4bcovener }
4e9c24785b525d2956e6e381015c0f2bd0a72f4bcovener break;
4e9c24785b525d2956e6e381015c0f2bd0a72f4bcovener }
4e9c24785b525d2956e6e381015c0f2bd0a72f4bcovener prev = l;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
4e9c24785b525d2956e6e381015c0f2bd0a72f4bcovener /* Some unfortunate duplication between this method
4e9c24785b525d2956e6e381015c0f2bd0a72f4bcovener * and uldap_connection_cleanup()
4e9c24785b525d2956e6e381015c0f2bd0a72f4bcovener */
4e9c24785b525d2956e6e381015c0f2bd0a72f4bcovener if (ldc->bindpw) {
4e9c24785b525d2956e6e381015c0f2bd0a72f4bcovener free((void*)ldc->bindpw);
4e9c24785b525d2956e6e381015c0f2bd0a72f4bcovener }
4e9c24785b525d2956e6e381015c0f2bd0a72f4bcovener if (ldc->binddn) {
4e9c24785b525d2956e6e381015c0f2bd0a72f4bcovener free((void*)ldc->binddn);
4e9c24785b525d2956e6e381015c0f2bd0a72f4bcovener }
4e9c24785b525d2956e6e381015c0f2bd0a72f4bcovener
4e9c24785b525d2956e6e381015c0f2bd0a72f4bcovener#if APR_HAS_THREADS
4e9c24785b525d2956e6e381015c0f2bd0a72f4bcovener apr_thread_mutex_unlock(ldc->lock);
4e9c24785b525d2956e6e381015c0f2bd0a72f4bcovener apr_thread_mutex_unlock(st->mutex);
4e9c24785b525d2956e6e381015c0f2bd0a72f4bcovener#endif
4e9c24785b525d2956e6e381015c0f2bd0a72f4bcovener
4e9c24785b525d2956e6e381015c0f2bd0a72f4bcovener /* Destory the pool associated with this connection */
4e9c24785b525d2956e6e381015c0f2bd0a72f4bcovener
4e9c24785b525d2956e6e381015c0f2bd0a72f4bcovener apr_pool_destroy(ldc->pool);
4e9c24785b525d2956e6e381015c0f2bd0a72f4bcovener
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes return APR_SUCCESS;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes}
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholesstatic int uldap_connection_init(request_rec *r,
0e05808dc59a321566303084c84b9826a4353cefrederpj util_ldap_connection_t *ldc)
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes{
b08925593f214f621161742925dcf074a8047e0acovener int rc = 0, ldap_option = 0;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes int version = LDAP_VERSION3;
54d22ed1c429b903b029bbd62621f11a9e286137minfrin apr_ldap_err_t *result = NULL;
465bb68501690d7a47bfd2a6129580047d76d8f1rederpj#ifdef LDAP_OPT_NETWORK_TIMEOUT
4be9c459920a7c1cfe62d654327dae5c4bb6b284sf struct timeval connectionTimeout = {10,0}; /* 10 second connection timeout */
465bb68501690d7a47bfd2a6129580047d76d8f1rederpj#endif
e8f95a682820a599fe41b22977010636be5c2717jim util_ldap_state_t *st =
3dfeb02cfb853d8717ca0cc259b59fea610173f5bnicholes (util_ldap_state_t *)ap_get_module_config(r->server->module_config,
3dfeb02cfb853d8717ca0cc259b59fea610173f5bnicholes &ldap_module);
54d22ed1c429b903b029bbd62621f11a9e286137minfrin
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 */
ebe5305f8b22507374358f32b74d12fb50c05a25covener apr_ldap_init(r->pool, &(ldc->ldap),
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes ldc->host,
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes APR_LDAP_SSL == ldc->secure ? LDAPS_PORT : LDAP_PORT,
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes APR_LDAP_NONE,
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes &(result));
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
513b324e774c559b579896df131fd7c8471ed529rederpj if (NULL == result) {
513b324e774c559b579896df131fd7c8471ed529rederpj /* something really bad happened */
513b324e774c559b579896df131fd7c8471ed529rederpj ldc->bound = 0;
513b324e774c559b579896df131fd7c8471ed529rederpj if (NULL == ldc->reason) {
513b324e774c559b579896df131fd7c8471ed529rederpj ldc->reason = "LDAP: ldap initialization failed";
513b324e774c559b579896df131fd7c8471ed529rederpj }
513b324e774c559b579896df131fd7c8471ed529rederpj return(APR_EGENERAL);
513b324e774c559b579896df131fd7c8471ed529rederpj }
513b324e774c559b579896df131fd7c8471ed529rederpj
513b324e774c559b579896df131fd7c8471ed529rederpj if (result->rc) {
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes ldc->reason = result->reason;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes if (NULL == ldc->ldap)
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes {
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes ldc->bound = 0;
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes if (NULL == ldc->reason) {
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes ldc->reason = "LDAP: ldap initialization failed";
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes }
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes else {
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes ldc->reason = result->reason;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes return(result->rc);
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
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 if (rc != APR_SUCCESS) {
9ad7b260be233be7d7b5576979825cac72e15498rederpj ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server,
9ad7b260be233be7d7b5576979825cac72e15498rederpj "LDAP: Unable to add rebind cross reference entry. Out of memory?");
9ad7b260be233be7d7b5576979825cac72e15498rederpj uldap_connection_unbind(ldc);
9ad7b260be233be7d7b5576979825cac72e15498rederpj ldc->reason = "LDAP: Unable to add rebind cross reference entry.";
9ad7b260be233be7d7b5576979825cac72e15498rederpj return(rc);
9ad7b260be233be7d7b5576979825cac72e15498rederpj }
9ad7b260be233be7d7b5576979825cac72e15498rederpj
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes /* always default to LDAP V3 */
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes ldap_set_option(ldc->ldap, LDAP_OPT_PROTOCOL_VERSION, &version);
54d22ed1c429b903b029bbd62621f11a9e286137minfrin
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes /* set client certificates */
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes if (!apr_is_empty_array(ldc->client_certs)) {
ebe5305f8b22507374358f32b74d12fb50c05a25covener apr_ldap_set_option(r->pool, ldc->ldap, APR_LDAP_OPT_TLS_CERT,
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes ldc->client_certs, &(result));
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes if (LDAP_SUCCESS != result->rc) {
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes uldap_connection_unbind( ldc );
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes ldc->reason = result->reason;
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes return(result->rc);
54d22ed1c429b903b029bbd62621f11a9e286137minfrin }
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes }
54d22ed1c429b903b029bbd62621f11a9e286137minfrin
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes /* switch on SSL/TLS */
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes if (APR_LDAP_NONE != ldc->secure) {
ebe5305f8b22507374358f32b74d12fb50c05a25covener apr_ldap_set_option(r->pool, ldc->ldap,
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes APR_LDAP_OPT_TLS, &ldc->secure, &(result));
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes if (LDAP_SUCCESS != result->rc) {
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes uldap_connection_unbind( ldc );
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes ldc->reason = result->reason;
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes return(result->rc);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes /* Set the alias dereferencing option */
b08925593f214f621161742925dcf074a8047e0acovener ldap_option = ldc->deref;
b08925593f214f621161742925dcf074a8047e0acovener ldap_set_option(ldc->ldap, LDAP_OPT_DEREF, &ldap_option);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
9ad7b260be233be7d7b5576979825cac72e15498rederpj /* Set options for rebind and referrals. */
9ad7b260be233be7d7b5576979825cac72e15498rederpj ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,
9ad7b260be233be7d7b5576979825cac72e15498rederpj "LDAP: Setting referrals to %s.",
128a5d93141a86e3afa151e921035a07297c9833rederpj ((ldc->ChaseReferrals == AP_LDAP_CHASEREFERRALS_ON) ? "On" : "Off"));
9ad7b260be233be7d7b5576979825cac72e15498rederpj apr_ldap_set_option(r->pool, ldc->ldap,
9ad7b260be233be7d7b5576979825cac72e15498rederpj APR_LDAP_OPT_REFERRALS,
128a5d93141a86e3afa151e921035a07297c9833rederpj (void *)((ldc->ChaseReferrals == AP_LDAP_CHASEREFERRALS_ON) ?
128a5d93141a86e3afa151e921035a07297c9833rederpj LDAP_OPT_ON : LDAP_OPT_OFF),
9ad7b260be233be7d7b5576979825cac72e15498rederpj &(result));
9ad7b260be233be7d7b5576979825cac72e15498rederpj if (result->rc != LDAP_SUCCESS) {
9ad7b260be233be7d7b5576979825cac72e15498rederpj ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,
9ad7b260be233be7d7b5576979825cac72e15498rederpj "Unable to set LDAP_OPT_REFERRALS option to %s: %d.",
128a5d93141a86e3afa151e921035a07297c9833rederpj ((ldc->ChaseReferrals == AP_LDAP_CHASEREFERRALS_ON) ? "On" : "Off"),
9ad7b260be233be7d7b5576979825cac72e15498rederpj result->rc);
9ad7b260be233be7d7b5576979825cac72e15498rederpj result->reason = "Unable to set LDAP_OPT_REFERRALS.";
9ab21648975dff7e1b680daf8aea627227ba28f7trawick ldc->reason = result->reason;
9ad7b260be233be7d7b5576979825cac72e15498rederpj uldap_connection_unbind(ldc);
9ad7b260be233be7d7b5576979825cac72e15498rederpj return(result->rc);
9ad7b260be233be7d7b5576979825cac72e15498rederpj }
9ad7b260be233be7d7b5576979825cac72e15498rederpj
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 ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,
9ad7b260be233be7d7b5576979825cac72e15498rederpj "Setting referral hop limit to %d.",
9ad7b260be233be7d7b5576979825cac72e15498rederpj ldc->ReferralHopLimit);
9ad7b260be233be7d7b5576979825cac72e15498rederpj apr_ldap_set_option(r->pool, ldc->ldap,
9ad7b260be233be7d7b5576979825cac72e15498rederpj APR_LDAP_OPT_REFHOPLIMIT,
9ad7b260be233be7d7b5576979825cac72e15498rederpj (void *)&ldc->ReferralHopLimit,
9ad7b260be233be7d7b5576979825cac72e15498rederpj &(result));
9ad7b260be233be7d7b5576979825cac72e15498rederpj if (result->rc != LDAP_SUCCESS) {
9ad7b260be233be7d7b5576979825cac72e15498rederpj ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,
9ad7b260be233be7d7b5576979825cac72e15498rederpj "Unable to set LDAP_OPT_REFHOPLIMIT option to %d: %d.",
9ad7b260be233be7d7b5576979825cac72e15498rederpj ldc->ReferralHopLimit,
9ad7b260be233be7d7b5576979825cac72e15498rederpj result->rc);
9ad7b260be233be7d7b5576979825cac72e15498rederpj result->reason = "Unable to set LDAP_OPT_REFHOPLIMIT.";
9ab21648975dff7e1b680daf8aea627227ba28f7trawick ldc->reason = result->reason;
9ad7b260be233be7d7b5576979825cac72e15498rederpj uldap_connection_unbind(ldc);
9ad7b260be233be7d7b5576979825cac72e15498rederpj return(result->rc);
9ad7b260be233be7d7b5576979825cac72e15498rederpj }
9ad7b260be233be7d7b5576979825cac72e15498rederpj }
9ad7b260be233be7d7b5576979825cac72e15498rederpj
7add8f7fb048534390571801b7794f71cd9e127abnicholes/*XXX All of the #ifdef's need to be removed once apr-util 1.2 is released */
7add8f7fb048534390571801b7794f71cd9e127abnicholes#ifdef APR_LDAP_OPT_VERIFY_CERT
8445dae5cc606ba8ba04efc341cc1e081d95920drpluem apr_ldap_set_option(r->pool, ldc->ldap, APR_LDAP_OPT_VERIFY_CERT,
8445dae5cc606ba8ba04efc341cc1e081d95920drpluem &(st->verify_svr_cert), &(result));
7add8f7fb048534390571801b7794f71cd9e127abnicholes#else
7add8f7fb048534390571801b7794f71cd9e127abnicholes#if defined(LDAPSSL_VERIFY_SERVER)
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes if (st->verify_svr_cert) {
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes result->rc = ldapssl_set_verify_mode(LDAPSSL_VERIFY_SERVER);
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes }
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes else {
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes result->rc = ldapssl_set_verify_mode(LDAPSSL_VERIFY_NONE);
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes }
7add8f7fb048534390571801b7794f71cd9e127abnicholes#elif defined(LDAP_OPT_X_TLS_REQUIRE_CERT)
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes /* This is not a per-connection setting so just pass NULL for the
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes Ldap connection handle */
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes if (st->verify_svr_cert) {
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes int i = LDAP_OPT_X_TLS_DEMAND;
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes result->rc = ldap_set_option(NULL, LDAP_OPT_X_TLS_REQUIRE_CERT, &i);
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes }
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes else {
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes int i = LDAP_OPT_X_TLS_NEVER;
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes result->rc = ldap_set_option(NULL, LDAP_OPT_X_TLS_REQUIRE_CERT, &i);
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes }
7add8f7fb048534390571801b7794f71cd9e127abnicholes#endif
7add8f7fb048534390571801b7794f71cd9e127abnicholes#endif
141e1368614dc7564e1627671361b01b4869b491bnicholes
3dfeb02cfb853d8717ca0cc259b59fea610173f5bnicholes#ifdef LDAP_OPT_NETWORK_TIMEOUT
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes if (st->connectionTimeout > 0) {
4be9c459920a7c1cfe62d654327dae5c4bb6b284sf connectionTimeout.tv_sec = st->connectionTimeout;
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes }
e8f95a682820a599fe41b22977010636be5c2717jim
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes if (st->connectionTimeout >= 0) {
ebe5305f8b22507374358f32b74d12fb50c05a25covener rc = apr_ldap_set_option(r->pool, ldc->ldap, LDAP_OPT_NETWORK_TIMEOUT,
4be9c459920a7c1cfe62d654327dae5c4bb6b284sf (void *)&connectionTimeout, &(result));
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes if (APR_SUCCESS != rc) {
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server,
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes "LDAP: Could not set the connection timeout");
3dfeb02cfb853d8717ca0cc259b59fea610173f5bnicholes }
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes }
3dfeb02cfb853d8717ca0cc259b59fea610173f5bnicholes#endif
3dfeb02cfb853d8717ca0cc259b59fea610173f5bnicholes
4be9c459920a7c1cfe62d654327dae5c4bb6b284sf#ifdef LDAP_OPT_TIMEOUT
4be9c459920a7c1cfe62d654327dae5c4bb6b284sf /*
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 */
4be9c459920a7c1cfe62d654327dae5c4bb6b284sf if (st->opTimeout) {
4be9c459920a7c1cfe62d654327dae5c4bb6b284sf rc = apr_ldap_set_option(r->pool, ldc->ldap, LDAP_OPT_TIMEOUT,
4be9c459920a7c1cfe62d654327dae5c4bb6b284sf st->opTimeout, &(result));
4be9c459920a7c1cfe62d654327dae5c4bb6b284sf if (APR_SUCCESS != rc) {
4be9c459920a7c1cfe62d654327dae5c4bb6b284sf ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server,
4be9c459920a7c1cfe62d654327dae5c4bb6b284sf "LDAP: Could not set LDAP_OPT_TIMEOUT");
4be9c459920a7c1cfe62d654327dae5c4bb6b284sf }
4be9c459920a7c1cfe62d654327dae5c4bb6b284sf }
4be9c459920a7c1cfe62d654327dae5c4bb6b284sf#endif
4be9c459920a7c1cfe62d654327dae5c4bb6b284sf
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes return(rc);
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes}
e8f95a682820a599fe41b22977010636be5c2717jim
7dbf29be626018bc389ef94c1846aeac4b72633bsf/*
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 *
7dbf29be626018bc389ef94c1846aeac4b72633bsf * Returns LDAP_SUCCESS on success; and an error code on failure
7dbf29be626018bc389ef94c1846aeac4b72633bsf */
7dbf29be626018bc389ef94c1846aeac4b72633bsfstatic int uldap_simple_bind(util_ldap_connection_t *ldc, char *binddn,
7dbf29be626018bc389ef94c1846aeac4b72633bsf char* bindpw, struct timeval *timeout)
7dbf29be626018bc389ef94c1846aeac4b72633bsf{
7dbf29be626018bc389ef94c1846aeac4b72633bsf LDAPMessage *result;
7dbf29be626018bc389ef94c1846aeac4b72633bsf int rc;
7dbf29be626018bc389ef94c1846aeac4b72633bsf int msgid = ldap_simple_bind(ldc->ldap, binddn, bindpw);
7dbf29be626018bc389ef94c1846aeac4b72633bsf if (msgid == -1) {
7dbf29be626018bc389ef94c1846aeac4b72633bsf ldc->reason = "LDAP: ldap_simple_bind() failed";
7dbf29be626018bc389ef94c1846aeac4b72633bsf /* -1 is LDAP_SERVER_DOWN in openldap, use something else */
7dbf29be626018bc389ef94c1846aeac4b72633bsf return LDAP_OTHER;
7dbf29be626018bc389ef94c1846aeac4b72633bsf }
7dbf29be626018bc389ef94c1846aeac4b72633bsf rc = ldap_result(ldc->ldap, msgid, 0, timeout, &result);
7dbf29be626018bc389ef94c1846aeac4b72633bsf if (rc == -1) {
7dbf29be626018bc389ef94c1846aeac4b72633bsf ldc->reason = "LDAP: ldap_simple_bind() result retrieval failed";
7dbf29be626018bc389ef94c1846aeac4b72633bsf /* -1 is LDAP_SERVER_DOWN in openldap, use something else */
7dbf29be626018bc389ef94c1846aeac4b72633bsf rc = LDAP_OTHER;
7dbf29be626018bc389ef94c1846aeac4b72633bsf }
7dbf29be626018bc389ef94c1846aeac4b72633bsf else if (rc == 0) {
7dbf29be626018bc389ef94c1846aeac4b72633bsf ldc->reason = "LDAP: ldap_simple_bind() timed out";
7dbf29be626018bc389ef94c1846aeac4b72633bsf rc = LDAP_TIMEOUT;
7dbf29be626018bc389ef94c1846aeac4b72633bsf } else if (ldap_parse_result(ldc->ldap, result, &rc, NULL, NULL, NULL,
7dbf29be626018bc389ef94c1846aeac4b72633bsf NULL, 1) == -1) {
7dbf29be626018bc389ef94c1846aeac4b72633bsf ldc->reason = "LDAP: ldap_simple_bind() parse result failed";
7dbf29be626018bc389ef94c1846aeac4b72633bsf }
7dbf29be626018bc389ef94c1846aeac4b72633bsf return rc;
7dbf29be626018bc389ef94c1846aeac4b72633bsf}
7dbf29be626018bc389ef94c1846aeac4b72633bsf
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes/*
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 *
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes * Returns LDAP_SUCCESS on success; and an error code on failure
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes */
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholesstatic int uldap_connection_open(request_rec *r,
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes util_ldap_connection_t *ldc)
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes{
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes int rc = 0;
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes int failures = 0;
4be9c459920a7c1cfe62d654327dae5c4bb6b284sf int new_connection = 0;
4be9c459920a7c1cfe62d654327dae5c4bb6b284sf util_ldap_state_t *st;
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes /* sanity check for NULL */
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes if (!ldc) {
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes return -1;
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes }
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes /* If the connection is already bound, return
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes */
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes if (ldc->bound)
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes {
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes ldc->reason = "LDAP: connection open successful (already bound)";
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes return LDAP_SUCCESS;
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes }
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes /* create the ldap session handle
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes */
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes if (NULL == ldc->ldap)
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes {
4be9c459920a7c1cfe62d654327dae5c4bb6b284sf new_connection = 1;
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes rc = uldap_connection_init( r, ldc );
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes if (LDAP_SUCCESS != rc)
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes {
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes return rc;
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
4be9c459920a7c1cfe62d654327dae5c4bb6b284sf st = (util_ldap_state_t *)ap_get_module_config(r->server->module_config,
4be9c459920a7c1cfe62d654327dae5c4bb6b284sf &ldap_module);
4be9c459920a7c1cfe62d654327dae5c4bb6b284sf
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 *
4be9c459920a7c1cfe62d654327dae5c4bb6b284sf * On Success or any other error, break out of the loop.
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes *
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.
4be9c459920a7c1cfe62d654327dae5c4bb6b284sf */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes for (failures=0; failures<10; failures++)
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes {
7dbf29be626018bc389ef94c1846aeac4b72633bsf rc = uldap_simple_bind(ldc, (char *)ldc->binddn, (char *)ldc->bindpw,
7dbf29be626018bc389ef94c1846aeac4b72633bsf st->opTimeout);
4be9c459920a7c1cfe62d654327dae5c4bb6b284sf if ((AP_LDAP_IS_SERVER_DOWN(rc) && failures == 5) ||
4be9c459920a7c1cfe62d654327dae5c4bb6b284sf (rc == LDAP_TIMEOUT && failures == 0))
4be9c459920a7c1cfe62d654327dae5c4bb6b284sf {
9c63a05713cb83a44a1590b4af33edeebf39f118sf if (rc == LDAP_TIMEOUT && !new_connection) {
9c63a05713cb83a44a1590b4af33edeebf39f118sf ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r,
9c63a05713cb83a44a1590b4af33edeebf39f118sf "ldap_simple_bind() timed out on reused "
9c63a05713cb83a44a1590b4af33edeebf39f118sf "connection, dropped by firewall?");
9c63a05713cb83a44a1590b4af33edeebf39f118sf }
9c63a05713cb83a44a1590b4af33edeebf39f118sf ap_log_rerror(APLOG_MARK, APLOG_TRACE2, 0, r,
9c63a05713cb83a44a1590b4af33edeebf39f118sf "attempt to re-init the connection");
9c63a05713cb83a44a1590b4af33edeebf39f118sf uldap_connection_unbind( ldc );
9c63a05713cb83a44a1590b4af33edeebf39f118sf rc = uldap_connection_init( r, ldc );
9c63a05713cb83a44a1590b4af33edeebf39f118sf if (LDAP_SUCCESS != rc)
9c63a05713cb83a44a1590b4af33edeebf39f118sf {
9c63a05713cb83a44a1590b4af33edeebf39f118sf break;
9c63a05713cb83a44a1590b4af33edeebf39f118sf }
4be9c459920a7c1cfe62d654327dae5c4bb6b284sf }
4be9c459920a7c1cfe62d654327dae5c4bb6b284sf else if (!AP_LDAP_IS_SERVER_DOWN(rc)) {
4be9c459920a7c1cfe62d654327dae5c4bb6b284sf break;
4be9c459920a7c1cfe62d654327dae5c4bb6b284sf }
9efd5708f6f0ab1992f6a5233eb622ad5e4eae18sf ap_log_rerror(APLOG_MARK, APLOG_TRACE2, 0, r,
9efd5708f6f0ab1992f6a5233eb622ad5e4eae18sf "ldap_simple_bind() failed with server down "
9efd5708f6f0ab1992f6a5233eb622ad5e4eae18sf "(try %d)", failures + 1);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes /* free the handle if there was an error
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes */
54d22ed1c429b903b029bbd62621f11a9e286137minfrin if (LDAP_SUCCESS != rc)
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes {
9c63a05713cb83a44a1590b4af33edeebf39f118sf uldap_connection_unbind(ldc);
4be9c459920a7c1cfe62d654327dae5c4bb6b284sf ldc->reason = "LDAP: ldap_simple_bind() failed";
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes else {
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes ldc->bound = 1;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes ldc->reason = "LDAP: connection open successful";
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
54d22ed1c429b903b029bbd62621f11a9e286137minfrin return(rc);
54d22ed1c429b903b029bbd62621f11a9e286137minfrin}
54d22ed1c429b903b029bbd62621f11a9e286137minfrin
54d22ed1c429b903b029bbd62621f11a9e286137minfrin
54d22ed1c429b903b029bbd62621f11a9e286137minfrin/*
54d22ed1c429b903b029bbd62621f11a9e286137minfrin * Compare client certificate arrays.
54d22ed1c429b903b029bbd62621f11a9e286137minfrin *
54d22ed1c429b903b029bbd62621f11a9e286137minfrin * Returns 1 on compare failure, 0 otherwise.
54d22ed1c429b903b029bbd62621f11a9e286137minfrin */
e8f95a682820a599fe41b22977010636be5c2717jimstatic int compare_client_certs(apr_array_header_t *srcs,
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe apr_array_header_t *dests)
8a03cd420b800a2428f49f4617293de9b2387b20jorton{
54d22ed1c429b903b029bbd62621f11a9e286137minfrin int i = 0;
54d22ed1c429b903b029bbd62621f11a9e286137minfrin struct apr_ldap_opt_tls_cert_t *src, *dest;
54d22ed1c429b903b029bbd62621f11a9e286137minfrin
54d22ed1c429b903b029bbd62621f11a9e286137minfrin /* arrays both NULL? if so, then equal */
54d22ed1c429b903b029bbd62621f11a9e286137minfrin if (srcs == NULL && dests == NULL) {
54d22ed1c429b903b029bbd62621f11a9e286137minfrin return 0;
54d22ed1c429b903b029bbd62621f11a9e286137minfrin }
54d22ed1c429b903b029bbd62621f11a9e286137minfrin
54d22ed1c429b903b029bbd62621f11a9e286137minfrin /* arrays different length or either NULL? If so, then not equal */
54d22ed1c429b903b029bbd62621f11a9e286137minfrin if (srcs == NULL || dests == NULL || srcs->nelts != dests->nelts) {
54d22ed1c429b903b029bbd62621f11a9e286137minfrin return 1;
54d22ed1c429b903b029bbd62621f11a9e286137minfrin }
54d22ed1c429b903b029bbd62621f11a9e286137minfrin
54d22ed1c429b903b029bbd62621f11a9e286137minfrin /* run an actual comparison */
54d22ed1c429b903b029bbd62621f11a9e286137minfrin src = (struct apr_ldap_opt_tls_cert_t *)srcs->elts;
54d22ed1c429b903b029bbd62621f11a9e286137minfrin dest = (struct apr_ldap_opt_tls_cert_t *)dests->elts;
54d22ed1c429b903b029bbd62621f11a9e286137minfrin for (i = 0; i < srcs->nelts; i++) {
6999a76d8eb5ef6b4b295e51df0b2fb6064bd373covener if ((strcmp(src[i].path, dest[i].path)) ||
6999a76d8eb5ef6b4b295e51df0b2fb6064bd373covener (src[i].type != dest[i].type) ||
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 &&
6999a76d8eb5ef6b4b295e51df0b2fb6064bd373covener strcmp(src[i].password, dest[i].password))) {
54d22ed1c429b903b029bbd62621f11a9e286137minfrin return 1;
54d22ed1c429b903b029bbd62621f11a9e286137minfrin }
54d22ed1c429b903b029bbd62621f11a9e286137minfrin }
54d22ed1c429b903b029bbd62621f11a9e286137minfrin
54d22ed1c429b903b029bbd62621f11a9e286137minfrin /* if we got here, the cert arrays were identical */
54d22ed1c429b903b029bbd62621f11a9e286137minfrin return 0;
54d22ed1c429b903b029bbd62621f11a9e286137minfrin
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes}
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes/*
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * Find an existing ldap connection struct that matches the
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * provided ldap connection parameters.
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes *
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.
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes */
e8f95a682820a599fe41b22977010636be5c2717jimstatic util_ldap_connection_t *
8113dac419143273351446c3ad653f3fe5ba5cfdwrowe uldap_connection_find(request_rec *r,
8113dac419143273351446c3ad653f3fe5ba5cfdwrowe const char *host, int port,
8113dac419143273351446c3ad653f3fe5ba5cfdwrowe const char *binddn, const char *bindpw,
f0f6f1b90ab582896f8a7d56d85bd62a55e57d90covener deref_options deref, int secure)
8113dac419143273351446c3ad653f3fe5ba5cfdwrowe{
54d22ed1c429b903b029bbd62621f11a9e286137minfrin struct util_ldap_connection_t *l, *p; /* To traverse the linked list */
560fd0658902ab57754616c172d8953e69fc4722bnicholes int secureflag = secure;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
e8f95a682820a599fe41b22977010636be5c2717jim util_ldap_state_t *st =
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes (util_ldap_state_t *)ap_get_module_config(r->server->module_config,
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes &ldap_module);
9ad7b260be233be7d7b5576979825cac72e15498rederpj util_ldap_config_t *dc =
9ad7b260be233be7d7b5576979825cac72e15498rederpj (util_ldap_config_t *) ap_get_module_config(r->per_dir_config, &ldap_module);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes#if APR_HAS_THREADS
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes /* mutex lock this function */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes apr_thread_mutex_lock(st->mutex);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes#endif
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
560fd0658902ab57754616c172d8953e69fc4722bnicholes if (secure < APR_LDAP_NONE) {
560fd0658902ab57754616c172d8953e69fc4722bnicholes secureflag = st->secure;
560fd0658902ab57754616c172d8953e69fc4722bnicholes }
560fd0658902ab57754616c172d8953e69fc4722bnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes /* Search for an exact connection match in the list that is not
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * being used.
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes for (l=st->connections,p=NULL; l; l=l->next) {
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes#if APR_HAS_THREADS
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes if (APR_SUCCESS == apr_thread_mutex_trylock(l->lock)) {
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes#endif
e8f95a682820a599fe41b22977010636be5c2717jim if ( (l->port == port) && (strcmp(l->host, host) == 0)
e8f95a682820a599fe41b22977010636be5c2717jim && ((!l->binddn && !binddn) || (l->binddn && binddn
e8f95a682820a599fe41b22977010636be5c2717jim && !strcmp(l->binddn, binddn)))
e8f95a682820a599fe41b22977010636be5c2717jim && ((!l->bindpw && !bindpw) || (l->bindpw && bindpw
e8f95a682820a599fe41b22977010636be5c2717jim && !strcmp(l->bindpw, bindpw)))
e8f95a682820a599fe41b22977010636be5c2717jim && (l->deref == deref) && (l->secure == secureflag)
ae1981fc94adf2b231e2d0e15d2f895b2138c969covener && !compare_client_certs(dc->client_certs, l->client_certs))
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe {
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes break;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes#if APR_HAS_THREADS
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 */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes apr_thread_mutex_unlock(l->lock);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes#endif
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes p = l;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes /* If nothing found, search again, but we don't care about the
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * binddn and bindpw this time.
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes if (!l) {
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes for (l=st->connections,p=NULL; l; l=l->next) {
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes#if APR_HAS_THREADS
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes if (APR_SUCCESS == apr_thread_mutex_trylock(l->lock)) {
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes#endif
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))
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe {
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes /* the bind credentials have changed */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes l->bound = 0;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes util_ldap_strdup((char**)&(l->binddn), binddn);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes util_ldap_strdup((char**)&(l->bindpw), bindpw);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes break;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes#if APR_HAS_THREADS
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 */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes apr_thread_mutex_unlock(l->lock);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes#endif
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes p = l;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes/* artificially disable cache */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes/* l = NULL; */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
0e05808dc59a321566303084c84b9826a4353cefrederpj /* If no connection was found after the second search, we
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * must create one.
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes if (!l) {
4e9c24785b525d2956e6e381015c0f2bd0a72f4bcovener apr_pool_t *newpool;
0e05808dc59a321566303084c84b9826a4353cefrederpj if (apr_pool_create(&newpool, NULL) != APR_SUCCESS) {
ebe5305f8b22507374358f32b74d12fb50c05a25covener ap_log_rerror(APLOG_MARK, APLOG_CRIT, 0, r,
ebe5305f8b22507374358f32b74d12fb50c05a25covener "util_ldap: Failed to create memory pool");
ebe5305f8b22507374358f32b74d12fb50c05a25covener#if APR_HAS_THREADS
ebe5305f8b22507374358f32b74d12fb50c05a25covener apr_thread_mutex_unlock(st->mutex);
ebe5305f8b22507374358f32b74d12fb50c05a25covener#endif
ebe5305f8b22507374358f32b74d12fb50c05a25covener return NULL;
ebe5305f8b22507374358f32b74d12fb50c05a25covener }
4e9c24785b525d2956e6e381015c0f2bd0a72f4bcovener
4e9c24785b525d2956e6e381015c0f2bd0a72f4bcovener /*
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 */
4e9c24785b525d2956e6e381015c0f2bd0a72f4bcovener
4e9c24785b525d2956e6e381015c0f2bd0a72f4bcovener /* create the details of this connection in the new pool */
4e9c24785b525d2956e6e381015c0f2bd0a72f4bcovener l = apr_pcalloc(newpool, sizeof(util_ldap_connection_t));
4e9c24785b525d2956e6e381015c0f2bd0a72f4bcovener l->pool = newpool;
4e9c24785b525d2956e6e381015c0f2bd0a72f4bcovener l->st = st;
0e05808dc59a321566303084c84b9826a4353cefrederpj
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes#if APR_HAS_THREADS
4e9c24785b525d2956e6e381015c0f2bd0a72f4bcovener apr_thread_mutex_create(&l->lock, APR_THREAD_MUTEX_DEFAULT, l->pool);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes apr_thread_mutex_lock(l->lock);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes#endif
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes l->bound = 0;
4e9c24785b525d2956e6e381015c0f2bd0a72f4bcovener l->host = apr_pstrdup(l->pool, host);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes l->port = port;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes l->deref = deref;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes util_ldap_strdup((char**)&(l->binddn), binddn);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes util_ldap_strdup((char**)&(l->bindpw), bindpw);
9ad7b260be233be7d7b5576979825cac72e15498rederpj l->ChaseReferrals = dc->ChaseReferrals;
9ad7b260be233be7d7b5576979825cac72e15498rederpj l->ReferralHopLimit = dc->ReferralHopLimit;
54d22ed1c429b903b029bbd62621f11a9e286137minfrin
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 */
560fd0658902ab57754616c172d8953e69fc4722bnicholes l->secure = secureflag;
54d22ed1c429b903b029bbd62621f11a9e286137minfrin
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
4e9c24785b525d2956e6e381015c0f2bd0a72f4bcovener l->keep = 1;
4e9c24785b525d2956e6e381015c0f2bd0a72f4bcovener
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes if (p) {
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes p->next = l;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes else {
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes st->connections = l;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes#if APR_HAS_THREADS
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes apr_thread_mutex_unlock(st->mutex);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes#endif
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes return l;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes}
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes/* ------------------------------------------------------------------ */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
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 *
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * The lock for the ldap cache should already be acquired.
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes */
e8f95a682820a599fe41b22977010636be5c2717jimstatic int uldap_cache_comparedn(request_rec *r, util_ldap_connection_t *ldc,
e8f95a682820a599fe41b22977010636be5c2717jim const char *url, const char *dn,
8113dac419143273351446c3ad653f3fe5ba5cfdwrowe const char *reqdn, int compare_dn_on_server)
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes{
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes int result = 0;
e8f95a682820a599fe41b22977010636be5c2717jim util_url_node_t *curl;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes util_url_node_t curnode;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes util_dn_compare_node_t *node;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes util_dn_compare_node_t newnode;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes int failures = 0;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes LDAPMessage *res, *entry;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes char *searchdn;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe util_ldap_state_t *st = (util_ldap_state_t *)
e8f95a682820a599fe41b22977010636be5c2717jim ap_get_module_config(r->server->module_config,
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe &ldap_module);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes /* get cache entry (or create one) */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes LDAP_CACHE_LOCK();
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes curnode.url = url;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes curl = util_ald_cache_fetch(st->util_ldap_cache, &curnode);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes if (curl == NULL) {
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes curl = util_ald_create_caches(st, url);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes LDAP_CACHE_UNLOCK();
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes /* a simple compare? */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes if (!compare_dn_on_server) {
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes /* unlock this read lock */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes if (strcmp(dn, reqdn)) {
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes ldc->reason = "DN Comparison FALSE (direct strcmp())";
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes return LDAP_COMPARE_FALSE;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes else {
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes ldc->reason = "DN Comparison TRUE (direct strcmp())";
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes return LDAP_COMPARE_TRUE;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes if (curl) {
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes /* no - it's a server side compare */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes LDAP_CACHE_LOCK();
e8f95a682820a599fe41b22977010636be5c2717jim
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes /* is it in the compare cache? */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes newnode.reqdn = (char *)reqdn;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes node = util_ald_cache_fetch(curl->dn_compare_cache, &newnode);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes if (node != NULL) {
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes /* If it's in the cache, it's good */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes /* unlock this read lock */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes LDAP_CACHE_UNLOCK();
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes ldc->reason = "DN Comparison TRUE (cached)";
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes return LDAP_COMPARE_TRUE;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
e8f95a682820a599fe41b22977010636be5c2717jim
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes /* unlock this read lock */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes LDAP_CACHE_UNLOCK();
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholesstart_over:
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes if (failures++ > 10) {
43c3e6a4b559b76b750c245ee95e2782c15b4296jim /* too many failures */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes return result;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes /* make a server connection */
f43b67c5a9d29b572eac916f8335cedc80c908bebnicholes if (LDAP_SUCCESS != (result = uldap_connection_open(r, ldc))) {
43c3e6a4b559b76b750c245ee95e2782c15b4296jim /* connect to server failed */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes return result;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes /* search for reqdn */
37af4b0cf648275b68ff41c866c665b4ccf4667dcovener result = ldap_search_ext_s(ldc->ldap, (char *)reqdn, LDAP_SCOPE_BASE,
37af4b0cf648275b68ff41c866c665b4ccf4667dcovener "(objectclass=*)", NULL, 1,
4be9c459920a7c1cfe62d654327dae5c4bb6b284sf NULL, NULL, st->opTimeout, APR_LDAP_SIZELIMIT, &res);
37af4b0cf648275b68ff41c866c665b4ccf4667dcovener if (AP_LDAP_IS_SERVER_DOWN(result))
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe {
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe ldc->reason = "DN Comparison ldap_search_ext_s() "
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe "failed with server down";
f43b67c5a9d29b572eac916f8335cedc80c908bebnicholes uldap_connection_unbind(ldc);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes goto start_over;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
4be9c459920a7c1cfe62d654327dae5c4bb6b284sf if (result == LDAP_TIMEOUT && failures == 0) {
4be9c459920a7c1cfe62d654327dae5c4bb6b284sf /*
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 */
4be9c459920a7c1cfe62d654327dae5c4bb6b284sf ldc->reason = "DN Comparison ldap_search_ext_s() "
4be9c459920a7c1cfe62d654327dae5c4bb6b284sf "failed with timeout";
4be9c459920a7c1cfe62d654327dae5c4bb6b284sf uldap_connection_unbind(ldc);
4be9c459920a7c1cfe62d654327dae5c4bb6b284sf goto start_over;
4be9c459920a7c1cfe62d654327dae5c4bb6b284sf }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes if (result != LDAP_SUCCESS) {
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes /* search for reqdn failed - no match */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes ldc->reason = "DN Comparison ldap_search_ext_s() failed";
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes return result;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes entry = ldap_first_entry(ldc->ldap, res);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes searchdn = ldap_get_dn(ldc->ldap, entry);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes ldap_msgfree(res);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes if (strcmp(dn, searchdn) != 0) {
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes /* compare unsuccessful */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes ldc->reason = "DN Comparison FALSE (checked on server)";
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes result = LDAP_COMPARE_FALSE;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes else {
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes if (curl) {
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes /* compare successful - add to the compare cache */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes LDAP_CACHE_LOCK();
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes newnode.reqdn = (char *)reqdn;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes newnode.dn = (char *)dn;
e8f95a682820a599fe41b22977010636be5c2717jim
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes node = util_ald_cache_fetch(curl->dn_compare_cache, &newnode);
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe if ( (node == NULL)
e8f95a682820a599fe41b22977010636be5c2717jim || (strcmp(reqdn, node->reqdn) != 0)
e8f95a682820a599fe41b22977010636be5c2717jim || (strcmp(dn, node->dn) != 0))
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe {
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes util_ald_cache_insert(curl->dn_compare_cache, &newnode);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes LDAP_CACHE_UNLOCK();
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes ldc->reason = "DN Comparison TRUE (checked on server)";
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes result = LDAP_COMPARE_TRUE;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes ldap_memfree(searchdn);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes return result;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes}
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes/*
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
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes *
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes */
8113dac419143273351446c3ad653f3fe5ba5cfdwrowestatic int uldap_cache_compare(request_rec *r, util_ldap_connection_t *ldc,
8113dac419143273351446c3ad653f3fe5ba5cfdwrowe const char *url, const char *dn,
8113dac419143273351446c3ad653f3fe5ba5cfdwrowe const char *attrib, const char *value)
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes{
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes int result = 0;
e8f95a682820a599fe41b22977010636be5c2717jim util_url_node_t *curl;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes util_url_node_t curnode;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes util_compare_node_t *compare_nodep;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes util_compare_node_t the_compare_node;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes apr_time_t curtime = 0; /* silence gcc -Wall */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes int failures = 0;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe util_ldap_state_t *st = (util_ldap_state_t *)
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe ap_get_module_config(r->server->module_config,
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe &ldap_module);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes /* get cache entry (or create one) */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes LDAP_CACHE_LOCK();
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes curnode.url = url;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes curl = util_ald_cache_fetch(st->util_ldap_cache, &curnode);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes if (curl == NULL) {
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes curl = util_ald_create_caches(st, url);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes LDAP_CACHE_UNLOCK();
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes if (curl) {
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes /* make a comparison to the cache */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes LDAP_CACHE_LOCK();
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes curtime = apr_time_now();
e8f95a682820a599fe41b22977010636be5c2717jim
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes the_compare_node.dn = (char *)dn;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes the_compare_node.attrib = (char *)attrib;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes the_compare_node.value = (char *)value;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes the_compare_node.result = 0;
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj the_compare_node.sgl_processed = 0;
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj the_compare_node.subgroupList = NULL;
e8f95a682820a599fe41b22977010636be5c2717jim
e8f95a682820a599fe41b22977010636be5c2717jim compare_nodep = util_ald_cache_fetch(curl->compare_cache,
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe &the_compare_node);
e8f95a682820a599fe41b22977010636be5c2717jim
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes if (compare_nodep != NULL) {
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 }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes else {
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes /* ...and it is good */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes if (LDAP_COMPARE_TRUE == compare_nodep->result) {
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes ldc->reason = "Comparison true (cached)";
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes else if (LDAP_COMPARE_FALSE == compare_nodep->result) {
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes ldc->reason = "Comparison false (cached)";
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes else if (LDAP_NO_SUCH_ATTRIBUTE == compare_nodep->result) {
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes ldc->reason = "Comparison no such attribute (cached)";
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes else {
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes ldc->reason = "Comparison undefined (cached)";
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj /* record the result code to return with the reason... */
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj result = compare_nodep->result;
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj /* and unlock this read lock */
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj LDAP_CACHE_UNLOCK();
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj return result;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes /* unlock this read lock */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes LDAP_CACHE_UNLOCK();
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholesstart_over:
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes if (failures++ > 10) {
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes /* too many failures */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes return result;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj
f43b67c5a9d29b572eac916f8335cedc80c908bebnicholes if (LDAP_SUCCESS != (result = uldap_connection_open(r, ldc))) {
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes /* connect failed */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes return result;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
37af4b0cf648275b68ff41c866c665b4ccf4667dcovener result = ldap_compare_s(ldc->ldap,
37af4b0cf648275b68ff41c866c665b4ccf4667dcovener (char *)dn,
37af4b0cf648275b68ff41c866c665b4ccf4667dcovener (char *)attrib,
37af4b0cf648275b68ff41c866c665b4ccf4667dcovener (char *)value);
37af4b0cf648275b68ff41c866c665b4ccf4667dcovener if (AP_LDAP_IS_SERVER_DOWN(result)) {
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes /* connection failed - try again */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes ldc->reason = "ldap_compare_s() failed with server down";
f43b67c5a9d29b572eac916f8335cedc80c908bebnicholes uldap_connection_unbind(ldc);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes goto start_over;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
4be9c459920a7c1cfe62d654327dae5c4bb6b284sf if (result == LDAP_TIMEOUT && failures == 0) {
4be9c459920a7c1cfe62d654327dae5c4bb6b284sf /*
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 */
4be9c459920a7c1cfe62d654327dae5c4bb6b284sf ldc->reason = "ldap_compare_s() failed with timeout";
4be9c459920a7c1cfe62d654327dae5c4bb6b284sf uldap_connection_unbind(ldc);
4be9c459920a7c1cfe62d654327dae5c4bb6b284sf goto start_over;
4be9c459920a7c1cfe62d654327dae5c4bb6b284sf }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes ldc->reason = "Comparison complete";
e8f95a682820a599fe41b22977010636be5c2717jim if ((LDAP_COMPARE_TRUE == result) ||
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes (LDAP_COMPARE_FALSE == result) ||
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes (LDAP_NO_SUCH_ATTRIBUTE == result)) {
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes if (curl) {
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes /* compare completed; caching result */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes LDAP_CACHE_LOCK();
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes the_compare_node.lastcompare = curtime;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes the_compare_node.result = result;
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj the_compare_node.sgl_processed = 0;
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj the_compare_node.subgroupList = NULL;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe /* If the node doesn't exist then insert it, otherwise just update
e8f95a682820a599fe41b22977010636be5c2717jim * it with the last results
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe */
e8f95a682820a599fe41b22977010636be5c2717jim compare_nodep = util_ald_cache_fetch(curl->compare_cache,
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe &the_compare_node);
e8f95a682820a599fe41b22977010636be5c2717jim if ( (compare_nodep == NULL)
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))
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe {
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj void *junk;
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj
8445dae5cc606ba8ba04efc341cc1e081d95920drpluem junk = util_ald_cache_insert(curl->compare_cache,
8445dae5cc606ba8ba04efc341cc1e081d95920drpluem &the_compare_node);
9c63a05713cb83a44a1590b4af33edeebf39f118sf if (junk == NULL) {
8445dae5cc606ba8ba04efc341cc1e081d95920drpluem ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
9efd5708f6f0ab1992f6a5233eb622ad5e4eae18sf "cache_compare: Cache insertion failure.");
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes else {
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes compare_nodep->lastcompare = curtime;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes compare_nodep->result = result;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes LDAP_CACHE_UNLOCK();
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes if (LDAP_COMPARE_TRUE == result) {
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes ldc->reason = "Comparison true (adding to cache)";
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes return LDAP_COMPARE_TRUE;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes else if (LDAP_COMPARE_FALSE == result) {
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes ldc->reason = "Comparison false (adding to cache)";
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes return LDAP_COMPARE_FALSE;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes else {
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes ldc->reason = "Comparison no such attribute (adding to cache)";
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes return LDAP_NO_SUCH_ATTRIBUTE;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes return result;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes}
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
8869662bb1a4078297020e94ae5e928626d877c6rederpj
8445dae5cc606ba8ba04efc341cc1e081d95920drpluemstatic util_compare_subgroup_t* uldap_get_subgroups(request_rec *r,
8445dae5cc606ba8ba04efc341cc1e081d95920drpluem util_ldap_connection_t *ldc,
8445dae5cc606ba8ba04efc341cc1e081d95920drpluem const char *url,
8445dae5cc606ba8ba04efc341cc1e081d95920drpluem const char *dn,
8445dae5cc606ba8ba04efc341cc1e081d95920drpluem char **subgroupAttrs,
8445dae5cc606ba8ba04efc341cc1e081d95920drpluem apr_array_header_t *subgroupclasses)
8445dae5cc606ba8ba04efc341cc1e081d95920drpluem{
8869662bb1a4078297020e94ae5e928626d877c6rederpj int failures = 0;
8869662bb1a4078297020e94ae5e928626d877c6rederpj int result = LDAP_COMPARE_FALSE;
8869662bb1a4078297020e94ae5e928626d877c6rederpj util_compare_subgroup_t *res = NULL;
8869662bb1a4078297020e94ae5e928626d877c6rederpj LDAPMessage *sga_res, *entry;
8445dae5cc606ba8ba04efc341cc1e081d95920drpluem struct mod_auth_ldap_groupattr_entry_t *sgc_ents;
8869662bb1a4078297020e94ae5e928626d877c6rederpj apr_array_header_t *subgroups = apr_array_make(r->pool, 20, sizeof(char *));
8869662bb1a4078297020e94ae5e928626d877c6rederpj
8445dae5cc606ba8ba04efc341cc1e081d95920drpluem sgc_ents = (struct mod_auth_ldap_groupattr_entry_t *) subgroupclasses->elts;
8445dae5cc606ba8ba04efc341cc1e081d95920drpluem
8869662bb1a4078297020e94ae5e928626d877c6rederpj if (!subgroupAttrs) {
8869662bb1a4078297020e94ae5e928626d877c6rederpj return res;
8869662bb1a4078297020e94ae5e928626d877c6rederpj }
8869662bb1a4078297020e94ae5e928626d877c6rederpj
8869662bb1a4078297020e94ae5e928626d877c6rederpjstart_over:
8445dae5cc606ba8ba04efc341cc1e081d95920drpluem /*
8445dae5cc606ba8ba04efc341cc1e081d95920drpluem * 3.B. The cache didn't have any subgrouplist yet. Go check for subgroups.
8445dae5cc606ba8ba04efc341cc1e081d95920drpluem */
8869662bb1a4078297020e94ae5e928626d877c6rederpj if (failures++ > 10) {
8869662bb1a4078297020e94ae5e928626d877c6rederpj /* too many failures */
8869662bb1a4078297020e94ae5e928626d877c6rederpj return res;
8869662bb1a4078297020e94ae5e928626d877c6rederpj }
8869662bb1a4078297020e94ae5e928626d877c6rederpj
8869662bb1a4078297020e94ae5e928626d877c6rederpj if (LDAP_SUCCESS != (result = uldap_connection_open(r, ldc))) {
8869662bb1a4078297020e94ae5e928626d877c6rederpj /* connect failed */
8869662bb1a4078297020e94ae5e928626d877c6rederpj return res;
8869662bb1a4078297020e94ae5e928626d877c6rederpj }
8869662bb1a4078297020e94ae5e928626d877c6rederpj
8869662bb1a4078297020e94ae5e928626d877c6rederpj /* try to do the search */
8869662bb1a4078297020e94ae5e928626d877c6rederpj result = ldap_search_ext_s(ldc->ldap, (char *)dn, LDAP_SCOPE_BASE,
8869662bb1a4078297020e94ae5e928626d877c6rederpj (char *)"cn=*", subgroupAttrs, 0,
8869662bb1a4078297020e94ae5e928626d877c6rederpj NULL, NULL, NULL, APR_LDAP_SIZELIMIT, &sga_res);
6733d943c9e8d0f27dd077a04037e8c49eb090ffcovener if (AP_LDAP_IS_SERVER_DOWN(result)) {
8445dae5cc606ba8ba04efc341cc1e081d95920drpluem ldc->reason = "ldap_search_ext_s() for subgroups failed with server"
8445dae5cc606ba8ba04efc341cc1e081d95920drpluem " down";
8869662bb1a4078297020e94ae5e928626d877c6rederpj uldap_connection_unbind(ldc);
8869662bb1a4078297020e94ae5e928626d877c6rederpj goto start_over;
8869662bb1a4078297020e94ae5e928626d877c6rederpj }
4be9c459920a7c1cfe62d654327dae5c4bb6b284sf if (result == LDAP_TIMEOUT && failures == 0) {
4be9c459920a7c1cfe62d654327dae5c4bb6b284sf /*
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 */
4be9c459920a7c1cfe62d654327dae5c4bb6b284sf ldc->reason = "ldap_search_ext_s() for subgroups failed with timeout";
4be9c459920a7c1cfe62d654327dae5c4bb6b284sf uldap_connection_unbind(ldc);
4be9c459920a7c1cfe62d654327dae5c4bb6b284sf goto start_over;
4be9c459920a7c1cfe62d654327dae5c4bb6b284sf }
8869662bb1a4078297020e94ae5e928626d877c6rederpj
8869662bb1a4078297020e94ae5e928626d877c6rederpj /* if there is an error (including LDAP_NO_SUCH_OBJECT) return now */
8869662bb1a4078297020e94ae5e928626d877c6rederpj if (result != LDAP_SUCCESS) {
8869662bb1a4078297020e94ae5e928626d877c6rederpj ldc->reason = "ldap_search_ext_s() for subgroups failed";
8869662bb1a4078297020e94ae5e928626d877c6rederpj return res;
8869662bb1a4078297020e94ae5e928626d877c6rederpj }
8869662bb1a4078297020e94ae5e928626d877c6rederpj
8869662bb1a4078297020e94ae5e928626d877c6rederpj entry = ldap_first_entry(ldc->ldap, sga_res);
8869662bb1a4078297020e94ae5e928626d877c6rederpj
8869662bb1a4078297020e94ae5e928626d877c6rederpj /*
8869662bb1a4078297020e94ae5e928626d877c6rederpj * Get values for the provided sub-group attributes.
8869662bb1a4078297020e94ae5e928626d877c6rederpj */
8869662bb1a4078297020e94ae5e928626d877c6rederpj if (subgroupAttrs) {
8869662bb1a4078297020e94ae5e928626d877c6rederpj int indx = 0, tmp_sgcIndex;
8869662bb1a4078297020e94ae5e928626d877c6rederpj
8869662bb1a4078297020e94ae5e928626d877c6rederpj while (subgroupAttrs[indx]) {
8869662bb1a4078297020e94ae5e928626d877c6rederpj char **values;
8869662bb1a4078297020e94ae5e928626d877c6rederpj int val_index = 0;
8869662bb1a4078297020e94ae5e928626d877c6rederpj
8869662bb1a4078297020e94ae5e928626d877c6rederpj /* Get *all* matching "member" values from this group. */
8869662bb1a4078297020e94ae5e928626d877c6rederpj values = ldap_get_values(ldc->ldap, entry, subgroupAttrs[indx]);
8869662bb1a4078297020e94ae5e928626d877c6rederpj
8869662bb1a4078297020e94ae5e928626d877c6rederpj if (values) {
8869662bb1a4078297020e94ae5e928626d877c6rederpj val_index = 0;
8869662bb1a4078297020e94ae5e928626d877c6rederpj /*
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 */
8869662bb1a4078297020e94ae5e928626d877c6rederpj while (values[val_index]) {
8869662bb1a4078297020e94ae5e928626d877c6rederpj /* Check if this entry really is a group. */
8869662bb1a4078297020e94ae5e928626d877c6rederpj tmp_sgcIndex = 0;
8869662bb1a4078297020e94ae5e928626d877c6rederpj result = LDAP_COMPARE_FALSE;
8445dae5cc606ba8ba04efc341cc1e081d95920drpluem while ((tmp_sgcIndex < subgroupclasses->nelts)
8445dae5cc606ba8ba04efc341cc1e081d95920drpluem && (result != LDAP_COMPARE_TRUE)) {
8445dae5cc606ba8ba04efc341cc1e081d95920drpluem result = uldap_cache_compare(r, ldc, url,
8445dae5cc606ba8ba04efc341cc1e081d95920drpluem values[val_index],
8445dae5cc606ba8ba04efc341cc1e081d95920drpluem "objectClass",
8445dae5cc606ba8ba04efc341cc1e081d95920drpluem sgc_ents[tmp_sgcIndex].name
8445dae5cc606ba8ba04efc341cc1e081d95920drpluem );
8869662bb1a4078297020e94ae5e928626d877c6rederpj
8869662bb1a4078297020e94ae5e928626d877c6rederpj if (result != LDAP_COMPARE_TRUE) {
8869662bb1a4078297020e94ae5e928626d877c6rederpj tmp_sgcIndex++;
8869662bb1a4078297020e94ae5e928626d877c6rederpj }
8869662bb1a4078297020e94ae5e928626d877c6rederpj }
8869662bb1a4078297020e94ae5e928626d877c6rederpj /* It's a group, so add it to the array. */
8869662bb1a4078297020e94ae5e928626d877c6rederpj if (result == LDAP_COMPARE_TRUE) {
8869662bb1a4078297020e94ae5e928626d877c6rederpj char **newgrp = (char **) apr_array_push(subgroups);
8869662bb1a4078297020e94ae5e928626d877c6rederpj *newgrp = apr_pstrdup(r->pool, values[val_index]);
8869662bb1a4078297020e94ae5e928626d877c6rederpj }
8869662bb1a4078297020e94ae5e928626d877c6rederpj val_index++;
8869662bb1a4078297020e94ae5e928626d877c6rederpj }
8869662bb1a4078297020e94ae5e928626d877c6rederpj ldap_value_free(values);
8869662bb1a4078297020e94ae5e928626d877c6rederpj }
8869662bb1a4078297020e94ae5e928626d877c6rederpj indx++;
8869662bb1a4078297020e94ae5e928626d877c6rederpj }
8869662bb1a4078297020e94ae5e928626d877c6rederpj }
8869662bb1a4078297020e94ae5e928626d877c6rederpj
8869662bb1a4078297020e94ae5e928626d877c6rederpj ldap_msgfree(sga_res);
8869662bb1a4078297020e94ae5e928626d877c6rederpj
8869662bb1a4078297020e94ae5e928626d877c6rederpj if (subgroups->nelts > 0) {
8869662bb1a4078297020e94ae5e928626d877c6rederpj /* We need to fill in tmp_local_subgroups using the data from LDAP */
8869662bb1a4078297020e94ae5e928626d877c6rederpj int sgindex;
8869662bb1a4078297020e94ae5e928626d877c6rederpj char **group;
8869662bb1a4078297020e94ae5e928626d877c6rederpj res = apr_pcalloc(r->pool, sizeof(util_compare_subgroup_t));
8445dae5cc606ba8ba04efc341cc1e081d95920drpluem res->subgroupDNs = apr_pcalloc(r->pool,
8445dae5cc606ba8ba04efc341cc1e081d95920drpluem sizeof(char *) * (subgroups->nelts));
8869662bb1a4078297020e94ae5e928626d877c6rederpj for (sgindex = 0; (group = apr_array_pop(subgroups)); sgindex++) {
8869662bb1a4078297020e94ae5e928626d877c6rederpj res->subgroupDNs[sgindex] = apr_pstrdup(r->pool, *group);
8869662bb1a4078297020e94ae5e928626d877c6rederpj }
8869662bb1a4078297020e94ae5e928626d877c6rederpj res->len = sgindex;
8869662bb1a4078297020e94ae5e928626d877c6rederpj }
8869662bb1a4078297020e94ae5e928626d877c6rederpj
8869662bb1a4078297020e94ae5e928626d877c6rederpj return res;
8869662bb1a4078297020e94ae5e928626d877c6rederpj}
8869662bb1a4078297020e94ae5e928626d877c6rederpj
8869662bb1a4078297020e94ae5e928626d877c6rederpj
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj/*
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 *
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj * DON'T CALL THIS UNLESS YOU CALLED uldap_cache_compare FIRST!!!!!
8445dae5cc606ba8ba04efc341cc1e081d95920drpluem *
8445dae5cc606ba8ba04efc341cc1e081d95920drpluem *
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 * entry.
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 * group.
8445dae5cc606ba8ba04efc341cc1e081d95920drpluem * 4. Loop through the sgl and call uldap_cache_compare (using the user info)
8445dae5cc606ba8ba04efc341cc1e081d95920drpluem * for each
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.
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj */
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj
8445dae5cc606ba8ba04efc341cc1e081d95920drpluemstatic int uldap_cache_check_subgroups(request_rec *r,
8445dae5cc606ba8ba04efc341cc1e081d95920drpluem util_ldap_connection_t *ldc,
11ca38a20ab9b2d00258f745620e2724838e7e21rederpj const char *url, const char *dn,
11ca38a20ab9b2d00258f745620e2724838e7e21rederpj const char *attrib, const char *value,
8445dae5cc606ba8ba04efc341cc1e081d95920drpluem char **subgroupAttrs,
8445dae5cc606ba8ba04efc341cc1e081d95920drpluem apr_array_header_t *subgroupclasses,
8445dae5cc606ba8ba04efc341cc1e081d95920drpluem int cur_subgroup_depth,
8445dae5cc606ba8ba04efc341cc1e081d95920drpluem int max_subgroup_depth)
11ca38a20ab9b2d00258f745620e2724838e7e21rederpj{
11ca38a20ab9b2d00258f745620e2724838e7e21rederpj int result = LDAP_COMPARE_FALSE;
11ca38a20ab9b2d00258f745620e2724838e7e21rederpj util_url_node_t *curl;
11ca38a20ab9b2d00258f745620e2724838e7e21rederpj util_url_node_t curnode;
11ca38a20ab9b2d00258f745620e2724838e7e21rederpj util_compare_node_t *compare_nodep;
11ca38a20ab9b2d00258f745620e2724838e7e21rederpj util_compare_node_t the_compare_node;
11ca38a20ab9b2d00258f745620e2724838e7e21rederpj util_compare_subgroup_t *tmp_local_sgl = NULL;
0e05808dc59a321566303084c84b9826a4353cefrederpj int sgl_cached_empty = 0, sgindex = 0, base_sgcIndex = 0;
a9c4332dc6241dc11dd104826bd179d42ccc0f12fuankg struct mod_auth_ldap_groupattr_entry_t *sgc_ents =
a9c4332dc6241dc11dd104826bd179d42ccc0f12fuankg (struct mod_auth_ldap_groupattr_entry_t *) subgroupclasses->elts;
11ca38a20ab9b2d00258f745620e2724838e7e21rederpj util_ldap_state_t *st = (util_ldap_state_t *)
11ca38a20ab9b2d00258f745620e2724838e7e21rederpj ap_get_module_config(r->server->module_config,
11ca38a20ab9b2d00258f745620e2724838e7e21rederpj &ldap_module);
11ca38a20ab9b2d00258f745620e2724838e7e21rederpj
8445dae5cc606ba8ba04efc341cc1e081d95920drpluem /*
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.
11ca38a20ab9b2d00258f745620e2724838e7e21rederpj */
85da6b76d07b7af570cbbec208a87697ba9c44f5rederpj if (cur_subgroup_depth >= max_subgroup_depth) {
85da6b76d07b7af570cbbec208a87697ba9c44f5rederpj return LDAP_COMPARE_FALSE;
85da6b76d07b7af570cbbec208a87697ba9c44f5rederpj }
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj
8445dae5cc606ba8ba04efc341cc1e081d95920drpluem /*
8445dae5cc606ba8ba04efc341cc1e081d95920drpluem * 1. Check the "groupiness" of the specified basedn. Stopping at the first
8445dae5cc606ba8ba04efc341cc1e081d95920drpluem * TRUE return.
8445dae5cc606ba8ba04efc341cc1e081d95920drpluem */
8445dae5cc606ba8ba04efc341cc1e081d95920drpluem while ((base_sgcIndex < subgroupclasses->nelts)
8445dae5cc606ba8ba04efc341cc1e081d95920drpluem && (result != LDAP_COMPARE_TRUE)) {
8445dae5cc606ba8ba04efc341cc1e081d95920drpluem result = uldap_cache_compare(r, ldc, url, dn, "objectClass",
8445dae5cc606ba8ba04efc341cc1e081d95920drpluem sgc_ents[base_sgcIndex].name);
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj if (result != LDAP_COMPARE_TRUE) {
85da6b76d07b7af570cbbec208a87697ba9c44f5rederpj base_sgcIndex++;
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj }
85da6b76d07b7af570cbbec208a87697ba9c44f5rederpj }
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj
85da6b76d07b7af570cbbec208a87697ba9c44f5rederpj if (result != LDAP_COMPARE_TRUE) {
85da6b76d07b7af570cbbec208a87697ba9c44f5rederpj ldc->reason = "DN failed group verification.";
85da6b76d07b7af570cbbec208a87697ba9c44f5rederpj return result;
85da6b76d07b7af570cbbec208a87697ba9c44f5rederpj }
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj
8445dae5cc606ba8ba04efc341cc1e081d95920drpluem /*
8445dae5cc606ba8ba04efc341cc1e081d95920drpluem * 2. Find previously created cache entry and check if there is already a
8445dae5cc606ba8ba04efc341cc1e081d95920drpluem * subgrouplist.
8445dae5cc606ba8ba04efc341cc1e081d95920drpluem */
85da6b76d07b7af570cbbec208a87697ba9c44f5rederpj LDAP_CACHE_LOCK();
85da6b76d07b7af570cbbec208a87697ba9c44f5rederpj curnode.url = url;
85da6b76d07b7af570cbbec208a87697ba9c44f5rederpj curl = util_ald_cache_fetch(st->util_ldap_cache, &curnode);
85da6b76d07b7af570cbbec208a87697ba9c44f5rederpj LDAP_CACHE_UNLOCK();
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj
85da6b76d07b7af570cbbec208a87697ba9c44f5rederpj if (curl && curl->compare_cache) {
85da6b76d07b7af570cbbec208a87697ba9c44f5rederpj /* make a comparison to the cache */
85da6b76d07b7af570cbbec208a87697ba9c44f5rederpj LDAP_CACHE_LOCK();
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj
85da6b76d07b7af570cbbec208a87697ba9c44f5rederpj the_compare_node.dn = (char *)dn;
85da6b76d07b7af570cbbec208a87697ba9c44f5rederpj the_compare_node.attrib = (char *)"objectClass";
85da6b76d07b7af570cbbec208a87697ba9c44f5rederpj the_compare_node.value = (char *)sgc_ents[base_sgcIndex].name;
85da6b76d07b7af570cbbec208a87697ba9c44f5rederpj the_compare_node.result = 0;
85da6b76d07b7af570cbbec208a87697ba9c44f5rederpj the_compare_node.sgl_processed = 0;
85da6b76d07b7af570cbbec208a87697ba9c44f5rederpj the_compare_node.subgroupList = NULL;
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj
8445dae5cc606ba8ba04efc341cc1e081d95920drpluem compare_nodep = util_ald_cache_fetch(curl->compare_cache,
8445dae5cc606ba8ba04efc341cc1e081d95920drpluem &the_compare_node);
85da6b76d07b7af570cbbec208a87697ba9c44f5rederpj
85da6b76d07b7af570cbbec208a87697ba9c44f5rederpj if (compare_nodep != NULL) {
8445dae5cc606ba8ba04efc341cc1e081d95920drpluem /*
8445dae5cc606ba8ba04efc341cc1e081d95920drpluem * Found the generic group entry... but the user isn't in this
8445dae5cc606ba8ba04efc341cc1e081d95920drpluem * group or we wouldn't be here.
8445dae5cc606ba8ba04efc341cc1e081d95920drpluem */
0e05808dc59a321566303084c84b9826a4353cefrederpj if (compare_nodep->sgl_processed) {
0e05808dc59a321566303084c84b9826a4353cefrederpj if (compare_nodep->subgroupList) {
0e05808dc59a321566303084c84b9826a4353cefrederpj /* Make a local copy of the subgroup list */
0e05808dc59a321566303084c84b9826a4353cefrederpj int i;
0e05808dc59a321566303084c84b9826a4353cefrederpj ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
9efd5708f6f0ab1992f6a5233eb622ad5e4eae18sf "Making local copy of SGL for "
0e05808dc59a321566303084c84b9826a4353cefrederpj "group (%s)(objectClass=%s) ",
9efd5708f6f0ab1992f6a5233eb622ad5e4eae18sf dn, (char *)sgc_ents[base_sgcIndex].name);
0e05808dc59a321566303084c84b9826a4353cefrederpj tmp_local_sgl = apr_pcalloc(r->pool,
0e05808dc59a321566303084c84b9826a4353cefrederpj sizeof(util_compare_subgroup_t));
0e05808dc59a321566303084c84b9826a4353cefrederpj tmp_local_sgl->len = compare_nodep->subgroupList->len;
0e05808dc59a321566303084c84b9826a4353cefrederpj tmp_local_sgl->subgroupDNs =
0e05808dc59a321566303084c84b9826a4353cefrederpj apr_pcalloc(r->pool,
0e05808dc59a321566303084c84b9826a4353cefrederpj sizeof(char *) * compare_nodep->subgroupList->len);
0e05808dc59a321566303084c84b9826a4353cefrederpj for (i = 0; i < compare_nodep->subgroupList->len; i++) {
0e05808dc59a321566303084c84b9826a4353cefrederpj tmp_local_sgl->subgroupDNs[i] =
0e05808dc59a321566303084c84b9826a4353cefrederpj apr_pstrdup(r->pool,
0e05808dc59a321566303084c84b9826a4353cefrederpj compare_nodep->subgroupList->subgroupDNs[i]);
0e05808dc59a321566303084c84b9826a4353cefrederpj }
0e05808dc59a321566303084c84b9826a4353cefrederpj }
0e05808dc59a321566303084c84b9826a4353cefrederpj else {
0e05808dc59a321566303084c84b9826a4353cefrederpj sgl_cached_empty = 1;
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj }
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj }
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj }
85da6b76d07b7af570cbbec208a87697ba9c44f5rederpj LDAP_CACHE_UNLOCK();
85da6b76d07b7af570cbbec208a87697ba9c44f5rederpj }
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj
0e05808dc59a321566303084c84b9826a4353cefrederpj if (!tmp_local_sgl && !sgl_cached_empty) {
85da6b76d07b7af570cbbec208a87697ba9c44f5rederpj /* No Cached SGL, retrieve from LDAP */
8445dae5cc606ba8ba04efc341cc1e081d95920drpluem ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
9efd5708f6f0ab1992f6a5233eb622ad5e4eae18sf "no cached SGL for %s, retrieving from LDAP", dn);
8445dae5cc606ba8ba04efc341cc1e081d95920drpluem tmp_local_sgl = uldap_get_subgroups(r, ldc, url, dn, subgroupAttrs,
8445dae5cc606ba8ba04efc341cc1e081d95920drpluem subgroupclasses);
85da6b76d07b7af570cbbec208a87697ba9c44f5rederpj if (!tmp_local_sgl) {
85da6b76d07b7af570cbbec208a87697ba9c44f5rederpj /* No SGL aailable via LDAP either */
9efd5708f6f0ab1992f6a5233eb622ad5e4eae18sf ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, "no subgroups for %s",
9efd5708f6f0ab1992f6a5233eb622ad5e4eae18sf dn);
85da6b76d07b7af570cbbec208a87697ba9c44f5rederpj }
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj
0e05808dc59a321566303084c84b9826a4353cefrederpj if (curl && curl->compare_cache) {
8445dae5cc606ba8ba04efc341cc1e081d95920drpluem /*
8445dae5cc606ba8ba04efc341cc1e081d95920drpluem * Find the generic group cache entry and add the sgl we just retrieved.
8445dae5cc606ba8ba04efc341cc1e081d95920drpluem */
85da6b76d07b7af570cbbec208a87697ba9c44f5rederpj LDAP_CACHE_LOCK();
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj
85da6b76d07b7af570cbbec208a87697ba9c44f5rederpj the_compare_node.dn = (char *)dn;
85da6b76d07b7af570cbbec208a87697ba9c44f5rederpj the_compare_node.attrib = (char *)"objectClass";
85da6b76d07b7af570cbbec208a87697ba9c44f5rederpj the_compare_node.value = (char *)sgc_ents[base_sgcIndex].name;
85da6b76d07b7af570cbbec208a87697ba9c44f5rederpj the_compare_node.result = 0;
85da6b76d07b7af570cbbec208a87697ba9c44f5rederpj the_compare_node.sgl_processed = 0;
85da6b76d07b7af570cbbec208a87697ba9c44f5rederpj the_compare_node.subgroupList = NULL;
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj
8445dae5cc606ba8ba04efc341cc1e081d95920drpluem compare_nodep = util_ald_cache_fetch(curl->compare_cache,
8445dae5cc606ba8ba04efc341cc1e081d95920drpluem &the_compare_node);
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj
85da6b76d07b7af570cbbec208a87697ba9c44f5rederpj if (compare_nodep == NULL) {
8445dae5cc606ba8ba04efc341cc1e081d95920drpluem /*
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.
8445dae5cc606ba8ba04efc341cc1e081d95920drpluem */
0e05808dc59a321566303084c84b9826a4353cefrederpj ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
9efd5708f6f0ab1992f6a5233eb622ad5e4eae18sf "Cache entry for %s doesn't exist", dn);
0e05808dc59a321566303084c84b9826a4353cefrederpj the_compare_node.result = LDAP_COMPARE_TRUE;
0e05808dc59a321566303084c84b9826a4353cefrederpj util_ald_cache_insert(curl->compare_cache, &the_compare_node);
0e05808dc59a321566303084c84b9826a4353cefrederpj compare_nodep = util_ald_cache_fetch(curl->compare_cache,
0e05808dc59a321566303084c84b9826a4353cefrederpj &the_compare_node);
0e05808dc59a321566303084c84b9826a4353cefrederpj if (compare_nodep == NULL) {
0e05808dc59a321566303084c84b9826a4353cefrederpj ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
9efd5708f6f0ab1992f6a5233eb622ad5e4eae18sf "util_ldap: Couldn't retrieve group entry "
9efd5708f6f0ab1992f6a5233eb622ad5e4eae18sf "for %s from cache",
9efd5708f6f0ab1992f6a5233eb622ad5e4eae18sf dn);
0e05808dc59a321566303084c84b9826a4353cefrederpj }
85da6b76d07b7af570cbbec208a87697ba9c44f5rederpj }
0e05808dc59a321566303084c84b9826a4353cefrederpj
40a1aee60a66f7c8dbd0835fdd4f09334e12fc15rpluem /*
0e05808dc59a321566303084c84b9826a4353cefrederpj * We have a valid cache entry and a locally generated SGL.
0e05808dc59a321566303084c84b9826a4353cefrederpj * Attach the SGL to the cache entry
40a1aee60a66f7c8dbd0835fdd4f09334e12fc15rpluem */
0e05808dc59a321566303084c84b9826a4353cefrederpj if (compare_nodep && !compare_nodep->sgl_processed) {
0e05808dc59a321566303084c84b9826a4353cefrederpj if (!tmp_local_sgl) {
0e05808dc59a321566303084c84b9826a4353cefrederpj /* We looked up an SGL for a group and found it to be empty */
0e05808dc59a321566303084c84b9826a4353cefrederpj if (compare_nodep->subgroupList == NULL) {
0e05808dc59a321566303084c84b9826a4353cefrederpj compare_nodep->sgl_processed = 1;
0e05808dc59a321566303084c84b9826a4353cefrederpj }
0e05808dc59a321566303084c84b9826a4353cefrederpj }
0e05808dc59a321566303084c84b9826a4353cefrederpj else {
0e05808dc59a321566303084c84b9826a4353cefrederpj util_compare_subgroup_t *sgl_copy =
0e05808dc59a321566303084c84b9826a4353cefrederpj util_ald_sgl_dup(curl->compare_cache, tmp_local_sgl);
0e05808dc59a321566303084c84b9826a4353cefrederpj ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,
0e05808dc59a321566303084c84b9826a4353cefrederpj "Copying local SGL of len %d for group %s into cache",
0e05808dc59a321566303084c84b9826a4353cefrederpj tmp_local_sgl->len, dn);
0e05808dc59a321566303084c84b9826a4353cefrederpj if (sgl_copy) {
0e05808dc59a321566303084c84b9826a4353cefrederpj if (compare_nodep->subgroupList) {
0e05808dc59a321566303084c84b9826a4353cefrederpj util_ald_sgl_free(curl->compare_cache,
0e05808dc59a321566303084c84b9826a4353cefrederpj &(compare_nodep->subgroupList));
0e05808dc59a321566303084c84b9826a4353cefrederpj }
0e05808dc59a321566303084c84b9826a4353cefrederpj compare_nodep->subgroupList = sgl_copy;
0e05808dc59a321566303084c84b9826a4353cefrederpj compare_nodep->sgl_processed = 1;
0e05808dc59a321566303084c84b9826a4353cefrederpj }
0e05808dc59a321566303084c84b9826a4353cefrederpj else {
0e05808dc59a321566303084c84b9826a4353cefrederpj ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server,
0e05808dc59a321566303084c84b9826a4353cefrederpj "Copy of SGL failed to obtain shared memory, "
0e05808dc59a321566303084c84b9826a4353cefrederpj "couldn't update cache");
0e05808dc59a321566303084c84b9826a4353cefrederpj }
0e05808dc59a321566303084c84b9826a4353cefrederpj }
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj }
85da6b76d07b7af570cbbec208a87697ba9c44f5rederpj LDAP_CACHE_UNLOCK();
0e05808dc59a321566303084c84b9826a4353cefrederpj }
85da6b76d07b7af570cbbec208a87697ba9c44f5rederpj }
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj
8445dae5cc606ba8ba04efc341cc1e081d95920drpluem /*
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
8445dae5cc606ba8ba04efc341cc1e081d95920drpluem */
85da6b76d07b7af570cbbec208a87697ba9c44f5rederpj result = LDAP_COMPARE_FALSE;
85da6b76d07b7af570cbbec208a87697ba9c44f5rederpj if (!tmp_local_sgl) {
85da6b76d07b7af570cbbec208a87697ba9c44f5rederpj return result;
85da6b76d07b7af570cbbec208a87697ba9c44f5rederpj }
85da6b76d07b7af570cbbec208a87697ba9c44f5rederpj
85da6b76d07b7af570cbbec208a87697ba9c44f5rederpj while ((result != LDAP_COMPARE_TRUE) && (sgindex < tmp_local_sgl->len)) {
85da6b76d07b7af570cbbec208a87697ba9c44f5rederpj const char *group = NULL;
85da6b76d07b7af570cbbec208a87697ba9c44f5rederpj group = tmp_local_sgl->subgroupDNs[sgindex];
8445dae5cc606ba8ba04efc341cc1e081d95920drpluem /*
8445dae5cc606ba8ba04efc341cc1e081d95920drpluem * 4. Now loop through the subgroupList and call uldap_cache_compare
8445dae5cc606ba8ba04efc341cc1e081d95920drpluem * to check for the user.
8445dae5cc606ba8ba04efc341cc1e081d95920drpluem */
85da6b76d07b7af570cbbec208a87697ba9c44f5rederpj result = uldap_cache_compare(r, ldc, url, group, attrib, value);
85da6b76d07b7af570cbbec208a87697ba9c44f5rederpj if (result == LDAP_COMPARE_TRUE) {
8445dae5cc606ba8ba04efc341cc1e081d95920drpluem /*
8445dae5cc606ba8ba04efc341cc1e081d95920drpluem * 4.A. We found the user in the subgroup. Return
8445dae5cc606ba8ba04efc341cc1e081d95920drpluem * LDAP_COMPARE_TRUE.
8445dae5cc606ba8ba04efc341cc1e081d95920drpluem */
9efd5708f6f0ab1992f6a5233eb622ad5e4eae18sf ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
9efd5708f6f0ab1992f6a5233eb622ad5e4eae18sf "Found user %s in a subgroup (%s) at level %d of %d.",
9efd5708f6f0ab1992f6a5233eb622ad5e4eae18sf r->user, group, cur_subgroup_depth+1,
9efd5708f6f0ab1992f6a5233eb622ad5e4eae18sf max_subgroup_depth);
85da6b76d07b7af570cbbec208a87697ba9c44f5rederpj }
85da6b76d07b7af570cbbec208a87697ba9c44f5rederpj else {
8445dae5cc606ba8ba04efc341cc1e081d95920drpluem /*
8445dae5cc606ba8ba04efc341cc1e081d95920drpluem * 4.B. We didn't find the user in this subgroup, so recurse into
8445dae5cc606ba8ba04efc341cc1e081d95920drpluem * it and keep looking.
8445dae5cc606ba8ba04efc341cc1e081d95920drpluem */
9efd5708f6f0ab1992f6a5233eb622ad5e4eae18sf ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
9efd5708f6f0ab1992f6a5233eb622ad5e4eae18sf "User %s not found in subgroup (%s) at level %d of "
9efd5708f6f0ab1992f6a5233eb622ad5e4eae18sf "%d.", r->user, group, cur_subgroup_depth+1,
9efd5708f6f0ab1992f6a5233eb622ad5e4eae18sf max_subgroup_depth);
85da6b76d07b7af570cbbec208a87697ba9c44f5rederpj result = uldap_cache_check_subgroups(r, ldc, url, group, attrib,
8445dae5cc606ba8ba04efc341cc1e081d95920drpluem value, subgroupAttrs,
8445dae5cc606ba8ba04efc341cc1e081d95920drpluem subgroupclasses,
8445dae5cc606ba8ba04efc341cc1e081d95920drpluem cur_subgroup_depth+1,
8445dae5cc606ba8ba04efc341cc1e081d95920drpluem max_subgroup_depth);
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj }
85da6b76d07b7af570cbbec208a87697ba9c44f5rederpj sgindex++;
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj }
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj return result;
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj}
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj
8113dac419143273351446c3ad653f3fe5ba5cfdwrowestatic int uldap_cache_checkuserid(request_rec *r, util_ldap_connection_t *ldc,
e8f95a682820a599fe41b22977010636be5c2717jim const char *url, const char *basedn,
8113dac419143273351446c3ad653f3fe5ba5cfdwrowe int scope, char **attrs, const char *filter,
e8f95a682820a599fe41b22977010636be5c2717jim const char *bindpw, const char **binddn,
8113dac419143273351446c3ad653f3fe5ba5cfdwrowe const char ***retvals)
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes{
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes const char **vals = NULL;
8bdea88407c848c1c2693655e2f8b23abde12307bnicholes int numvals = 0;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes int result = 0;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes LDAPMessage *res, *entry;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes char *dn;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes int count;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes int failures = 0;
f05787953018140838ad51456c86c965d6a86267jim util_url_node_t *curl; /* Cached URL node */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes util_url_node_t curnode;
f05787953018140838ad51456c86c965d6a86267jim util_search_node_t *search_nodep; /* Cached search node */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes util_search_node_t the_search_node;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes apr_time_t curtime;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
e8f95a682820a599fe41b22977010636be5c2717jim util_ldap_state_t *st =
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes (util_ldap_state_t *)ap_get_module_config(r->server->module_config,
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes &ldap_module);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes /* Get the cache node for this url */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes LDAP_CACHE_LOCK();
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes curnode.url = url;
e8f95a682820a599fe41b22977010636be5c2717jim curl = (util_url_node_t *)util_ald_cache_fetch(st->util_ldap_cache,
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe &curnode);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes if (curl == NULL) {
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes curl = util_ald_create_caches(st, url);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes LDAP_CACHE_UNLOCK();
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes if (curl) {
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes LDAP_CACHE_LOCK();
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes the_search_node.username = filter;
e8f95a682820a599fe41b22977010636be5c2717jim search_nodep = util_ald_cache_fetch(curl->search_cache,
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe &the_search_node);
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes if (search_nodep != NULL) {
e8f95a682820a599fe41b22977010636be5c2717jim
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes /* found entry in search cache... */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes curtime = apr_time_now();
e8f95a682820a599fe41b22977010636be5c2717jim
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes /*
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 */
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 }
e8f95a682820a599fe41b22977010636be5c2717jim else if ( (search_nodep->bindpw)
e8f95a682820a599fe41b22977010636be5c2717jim && (search_nodep->bindpw[0] != '\0')
e8f95a682820a599fe41b22977010636be5c2717jim && (strcmp(search_nodep->bindpw, bindpw) == 0))
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe {
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes /* ...and entry is valid */
c4f16f709c79bb7e2ddffb532bc7708eab9a9691covener *binddn = apr_pstrdup(r->pool, search_nodep->dn);
c4f16f709c79bb7e2ddffb532bc7708eab9a9691covener if (attrs) {
d64dd2fd4516c2b1b664c5e59c0628d9aff26984covener int i;
d64dd2fd4516c2b1b664c5e59c0628d9aff26984covener *retvals = apr_pcalloc(r->pool, sizeof(char *) * search_nodep->numvals);
d64dd2fd4516c2b1b664c5e59c0628d9aff26984covener for (i = 0; i < search_nodep->numvals; i++) {
d64dd2fd4516c2b1b664c5e59c0628d9aff26984covener (*retvals)[i] = apr_pstrdup(r->pool, search_nodep->vals[i]);
c4f16f709c79bb7e2ddffb532bc7708eab9a9691covener }
c4f16f709c79bb7e2ddffb532bc7708eab9a9691covener }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes LDAP_CACHE_UNLOCK();
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes ldc->reason = "Authentication successful (cached)";
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes return LDAP_SUCCESS;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes /* unlock this read lock */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes LDAP_CACHE_UNLOCK();
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
e8f95a682820a599fe41b22977010636be5c2717jim /*
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * At this point, there is no valid cached search, so lets do the search.
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes /*
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe * If LDAP operation fails due to LDAP_SERVER_DOWN, control returns here.
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholesstart_over:
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes if (failures++ > 10) {
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes return result;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
f43b67c5a9d29b572eac916f8335cedc80c908bebnicholes if (LDAP_SUCCESS != (result = uldap_connection_open(r, ldc))) {
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes return result;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes /* try do the search */
37af4b0cf648275b68ff41c866c665b4ccf4667dcovener result = ldap_search_ext_s(ldc->ldap,
37af4b0cf648275b68ff41c866c665b4ccf4667dcovener (char *)basedn, scope,
37af4b0cf648275b68ff41c866c665b4ccf4667dcovener (char *)filter, attrs, 0,
4be9c459920a7c1cfe62d654327dae5c4bb6b284sf NULL, NULL, st->opTimeout, APR_LDAP_SIZELIMIT, &res);
37af4b0cf648275b68ff41c866c665b4ccf4667dcovener if (AP_LDAP_IS_SERVER_DOWN(result))
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe {
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes ldc->reason = "ldap_search_ext_s() for user failed with server down";
f43b67c5a9d29b572eac916f8335cedc80c908bebnicholes uldap_connection_unbind(ldc);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes goto start_over;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes /* if there is an error (including LDAP_NO_SUCH_OBJECT) return now */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes if (result != LDAP_SUCCESS) {
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes ldc->reason = "ldap_search_ext_s() for user failed";
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes return result;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
e8f95a682820a599fe41b22977010636be5c2717jim /*
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * We should have found exactly one entry; to find a different
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * number is an error.
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes count = ldap_count_entries(ldc->ldap, res);
e8f95a682820a599fe41b22977010636be5c2717jim if (count != 1)
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes {
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes if (count == 0 )
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes ldc->reason = "User not found";
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes else
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe ldc->reason = "User is not unique (search found two "
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe "or more matches)";
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes ldap_msgfree(res);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes return LDAP_NO_SUCH_OBJECT;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes entry = ldap_first_entry(ldc->ldap, res);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes /* Grab the dn, copy it into the pool, and free it again */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes dn = ldap_get_dn(ldc->ldap, entry);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes *binddn = apr_pstrdup(r->pool, dn);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes ldap_memfree(dn);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
e8f95a682820a599fe41b22977010636be5c2717jim /*
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 * problem.
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes */
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes if (!bindpw || strlen(bindpw) <= 0) {
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes ldap_msgfree(res);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes ldc->reason = "Empty password not allowed";
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes return LDAP_INVALID_CREDENTIALS;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
e8f95a682820a599fe41b22977010636be5c2717jim /*
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)
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes */
7dbf29be626018bc389ef94c1846aeac4b72633bsf result = uldap_simple_bind(ldc, (char *)*binddn, (char *)bindpw,
7dbf29be626018bc389ef94c1846aeac4b72633bsf st->opTimeout);
7dbf29be626018bc389ef94c1846aeac4b72633bsf if (AP_LDAP_IS_SERVER_DOWN(result) ||
7dbf29be626018bc389ef94c1846aeac4b72633bsf (result == LDAP_TIMEOUT && failures == 0)) {
7dbf29be626018bc389ef94c1846aeac4b72633bsf if (AP_LDAP_IS_SERVER_DOWN(result))
7dbf29be626018bc389ef94c1846aeac4b72633bsf ldc->reason = "ldap_simple_bind() to check user credentials "
7dbf29be626018bc389ef94c1846aeac4b72633bsf "failed with server down";
7dbf29be626018bc389ef94c1846aeac4b72633bsf else
7dbf29be626018bc389ef94c1846aeac4b72633bsf ldc->reason = "ldap_simple_bind() to check user credentials "
7dbf29be626018bc389ef94c1846aeac4b72633bsf "timed out";
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes ldap_msgfree(res);
f43b67c5a9d29b572eac916f8335cedc80c908bebnicholes uldap_connection_unbind(ldc);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes goto start_over;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes /* failure? if so - return */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes if (result != LDAP_SUCCESS) {
7dbf29be626018bc389ef94c1846aeac4b72633bsf ldc->reason = "ldap_simple_bind() to check user credentials failed";
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes ldap_msgfree(res);
f43b67c5a9d29b572eac916f8335cedc80c908bebnicholes uldap_connection_unbind(ldc);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes return result;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes else {
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes /*
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 */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes ldc->bound = 0;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes /*
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * Get values for the provided attributes.
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes if (attrs) {
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes int k = 0;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes int i = 0;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes while (attrs[k++]);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes vals = apr_pcalloc(r->pool, sizeof(char *) * (k+1));
8bdea88407c848c1c2693655e2f8b23abde12307bnicholes numvals = k;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes while (attrs[i]) {
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes char **values;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes int j = 0;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes char *str = NULL;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes /* get values */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes values = ldap_get_values(ldc->ldap, entry, attrs[i]);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes while (values && values[j]) {
e8f95a682820a599fe41b22977010636be5c2717jim str = str ? apr_pstrcat(r->pool, str, "; ", values[j], NULL)
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe : apr_pstrdup(r->pool, values[j]);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes j++;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes ldap_value_free(values);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes vals[i] = str;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes i++;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes *retvals = vals;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
e8f95a682820a599fe41b22977010636be5c2717jim /*
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * Add the new username to the search cache.
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes if (curl) {
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes LDAP_CACHE_LOCK();
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes the_search_node.username = filter;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes the_search_node.dn = *binddn;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes the_search_node.bindpw = bindpw;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes the_search_node.lastbind = apr_time_now();
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes the_search_node.vals = vals;
8bdea88407c848c1c2693655e2f8b23abde12307bnicholes the_search_node.numvals = numvals;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
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 */
e8f95a682820a599fe41b22977010636be5c2717jim search_nodep = util_ald_cache_fetch(curl->search_cache,
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe &the_search_node);
e8f95a682820a599fe41b22977010636be5c2717jim if ((search_nodep == NULL) ||
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes (strcmp(*binddn, search_nodep->dn) != 0)) {
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes /* Nothing in cache, insert new entry */
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes util_ald_cache_insert(curl->search_cache, &the_search_node);
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes }
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes else if ((!search_nodep->bindpw) ||
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes (strcmp(bindpw, search_nodep->bindpw) != 0)) {
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
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);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes else {
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes /* Cache entry is valid, update lastbind */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes search_nodep->lastbind = the_search_node.lastbind;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes LDAP_CACHE_UNLOCK();
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes ldap_msgfree(res);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes ldc->reason = "Authentication successful";
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes return LDAP_SUCCESS;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes}
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
8113dac419143273351446c3ad653f3fe5ba5cfdwrowe/*
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.
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes */
8113dac419143273351446c3ad653f3fe5ba5cfdwrowestatic int uldap_cache_getuserdn(request_rec *r, util_ldap_connection_t *ldc,
e8f95a682820a599fe41b22977010636be5c2717jim const char *url, const char *basedn,
e8f95a682820a599fe41b22977010636be5c2717jim int scope, char **attrs, const char *filter,
8113dac419143273351446c3ad653f3fe5ba5cfdwrowe const char **binddn, const char ***retvals)
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes{
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes const char **vals = NULL;
8bdea88407c848c1c2693655e2f8b23abde12307bnicholes int numvals = 0;
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes int result = 0;
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes LDAPMessage *res, *entry;
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes char *dn;
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes int count;
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes int failures = 0;
f05787953018140838ad51456c86c965d6a86267jim util_url_node_t *curl; /* Cached URL node */
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes util_url_node_t curnode;
f05787953018140838ad51456c86c965d6a86267jim util_search_node_t *search_nodep; /* Cached search node */
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes util_search_node_t the_search_node;
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes apr_time_t curtime;
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes
e8f95a682820a599fe41b22977010636be5c2717jim util_ldap_state_t *st =
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes (util_ldap_state_t *)ap_get_module_config(r->server->module_config,
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes &ldap_module);
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes /* Get the cache node for this url */
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes LDAP_CACHE_LOCK();
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes curnode.url = url;
e8f95a682820a599fe41b22977010636be5c2717jim curl = (util_url_node_t *)util_ald_cache_fetch(st->util_ldap_cache,
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe &curnode);
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes if (curl == NULL) {
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes curl = util_ald_create_caches(st, url);
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes }
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes LDAP_CACHE_UNLOCK();
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes if (curl) {
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes LDAP_CACHE_LOCK();
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes the_search_node.username = filter;
e8f95a682820a599fe41b22977010636be5c2717jim search_nodep = util_ald_cache_fetch(curl->search_cache,
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe &the_search_node);
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes if (search_nodep != NULL) {
e8f95a682820a599fe41b22977010636be5c2717jim
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes /* found entry in search cache... */
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes curtime = apr_time_now();
e8f95a682820a599fe41b22977010636be5c2717jim
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes /*
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes * Remove this item from the cache if its expired.
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes */
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 }
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes else {
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes /* ...and entry is valid */
c4f16f709c79bb7e2ddffb532bc7708eab9a9691covener *binddn = apr_pstrdup(r->pool, search_nodep->dn);
c4f16f709c79bb7e2ddffb532bc7708eab9a9691covener if (attrs) {
d64dd2fd4516c2b1b664c5e59c0628d9aff26984covener int i;
d64dd2fd4516c2b1b664c5e59c0628d9aff26984covener *retvals = apr_pcalloc(r->pool, sizeof(char *) * search_nodep->numvals);
d64dd2fd4516c2b1b664c5e59c0628d9aff26984covener for (i = 0; i < search_nodep->numvals; i++) {
d64dd2fd4516c2b1b664c5e59c0628d9aff26984covener (*retvals)[i] = apr_pstrdup(r->pool, search_nodep->vals[i]);
c4f16f709c79bb7e2ddffb532bc7708eab9a9691covener }
c4f16f709c79bb7e2ddffb532bc7708eab9a9691covener }
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes LDAP_CACHE_UNLOCK();
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes ldc->reason = "Search successful (cached)";
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes return LDAP_SUCCESS;
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes }
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes }
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes /* unlock this read lock */
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes LDAP_CACHE_UNLOCK();
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes }
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes
e8f95a682820a599fe41b22977010636be5c2717jim /*
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes * At this point, there is no valid cached search, so lets do the search.
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes */
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes /*
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe * If LDAP operation fails due to LDAP_SERVER_DOWN, control returns here.
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes */
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholesstart_over:
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes if (failures++ > 10) {
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes return result;
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes }
f43b67c5a9d29b572eac916f8335cedc80c908bebnicholes if (LDAP_SUCCESS != (result = uldap_connection_open(r, ldc))) {
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes return result;
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes }
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes /* try do the search */
37af4b0cf648275b68ff41c866c665b4ccf4667dcovener result = ldap_search_ext_s(ldc->ldap,
37af4b0cf648275b68ff41c866c665b4ccf4667dcovener (char *)basedn, scope,
37af4b0cf648275b68ff41c866c665b4ccf4667dcovener (char *)filter, attrs, 0,
4be9c459920a7c1cfe62d654327dae5c4bb6b284sf NULL, NULL, st->opTimeout, APR_LDAP_SIZELIMIT, &res);
37af4b0cf648275b68ff41c866c665b4ccf4667dcovener if (AP_LDAP_IS_SERVER_DOWN(result))
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe {
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes ldc->reason = "ldap_search_ext_s() for user failed with server down";
f43b67c5a9d29b572eac916f8335cedc80c908bebnicholes uldap_connection_unbind(ldc);
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes goto start_over;
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes }
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes /* if there is an error (including LDAP_NO_SUCH_OBJECT) return now */
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes if (result != LDAP_SUCCESS) {
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes ldc->reason = "ldap_search_ext_s() for user failed";
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes return result;
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes }
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes
e8f95a682820a599fe41b22977010636be5c2717jim /*
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes * We should have found exactly one entry; to find a different
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes * number is an error.
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes */
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes count = ldap_count_entries(ldc->ldap, res);
e8f95a682820a599fe41b22977010636be5c2717jim if (count != 1)
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes {
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes if (count == 0 )
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes ldc->reason = "User not found";
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes else
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe ldc->reason = "User is not unique (search found two "
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe "or more matches)";
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes ldap_msgfree(res);
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes return LDAP_NO_SUCH_OBJECT;
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes }
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes entry = ldap_first_entry(ldc->ldap, res);
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes /* Grab the dn, copy it into the pool, and free it again */
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes dn = ldap_get_dn(ldc->ldap, entry);
490046d2a164ad86cc63bd789f32eaed663d239abnicholes *binddn = apr_pstrdup(r->pool, dn);
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes ldap_memfree(dn);
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes /*
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes * Get values for the provided attributes.
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes */
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes if (attrs) {
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes int k = 0;
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes int i = 0;
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes while (attrs[k++]);
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes vals = apr_pcalloc(r->pool, sizeof(char *) * (k+1));
8bdea88407c848c1c2693655e2f8b23abde12307bnicholes numvals = k;
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes while (attrs[i]) {
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes char **values;
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes int j = 0;
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes char *str = NULL;
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes /* get values */
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes values = ldap_get_values(ldc->ldap, entry, attrs[i]);
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes while (values && values[j]) {
e8f95a682820a599fe41b22977010636be5c2717jim str = str ? apr_pstrcat(r->pool, str, "; ", values[j], NULL)
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe : apr_pstrdup(r->pool, values[j]);
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes j++;
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes }
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes ldap_value_free(values);
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes vals[i] = str;
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes i++;
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes }
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes *retvals = vals;
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes }
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes
e8f95a682820a599fe41b22977010636be5c2717jim /*
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes * Add the new username to the search cache.
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes */
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes if (curl) {
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes LDAP_CACHE_LOCK();
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes the_search_node.username = filter;
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes the_search_node.dn = *binddn;
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes the_search_node.bindpw = NULL;
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes the_search_node.lastbind = apr_time_now();
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes the_search_node.vals = vals;
8bdea88407c848c1c2693655e2f8b23abde12307bnicholes the_search_node.numvals = numvals;
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes
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 */
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe search_nodep = util_ald_cache_fetch(curl->search_cache,
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe &the_search_node);
e8f95a682820a599fe41b22977010636be5c2717jim if ((search_nodep == NULL) ||
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes (strcmp(*binddn, search_nodep->dn) != 0)) {
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes /* Nothing in cache, insert new entry */
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes util_ald_cache_insert(curl->search_cache, &the_search_node);
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes }
0c8aa496e9d7676ff8101783398f17c0da1900f7bnicholes /*
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.
0c8aa496e9d7676ff8101783398f17c0da1900f7bnicholes */
0c8aa496e9d7676ff8101783398f17c0da1900f7bnicholes else if (!search_nodep->bindpw) {
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes /* Cache entry is valid, update lastbind */
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes search_nodep->lastbind = the_search_node.lastbind;
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes }
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes LDAP_CACHE_UNLOCK();
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes }
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes ldap_msgfree(res);
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes ldc->reason = "Search successful";
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes return LDAP_SUCCESS;
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes}
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes/*
e8f95a682820a599fe41b22977010636be5c2717jim * Reports if ssl support is enabled
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes *
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * 1 = enabled, 0 = not enabled
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes */
8113dac419143273351446c3ad653f3fe5ba5cfdwrowestatic int uldap_ssl_supported(request_rec *r)
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes{
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes util_ldap_state_t *st = (util_ldap_state_t *)ap_get_module_config(
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes r->server->module_config, &ldap_module);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
54d22ed1c429b903b029bbd62621f11a9e286137minfrin return(st->ssl_supported);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes}
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes/* ---------------------------------------- */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes/* config directives */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
e8f95a682820a599fe41b22977010636be5c2717jimstatic const char *util_ldap_set_cache_bytes(cmd_parms *cmd, void *dummy,
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe const char *bytes)
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes{
e8f95a682820a599fe41b22977010636be5c2717jim util_ldap_state_t *st =
e8f95a682820a599fe41b22977010636be5c2717jim (util_ldap_state_t *)ap_get_module_config(cmd->server->module_config,
43c3e6a4b559b76b750c245ee95e2782c15b4296jim &ldap_module);
3effb85eb3124c6f02cd89e22ffed0fc9afaddb9bnicholes const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
3effb85eb3124c6f02cd89e22ffed0fc9afaddb9bnicholes
3effb85eb3124c6f02cd89e22ffed0fc9afaddb9bnicholes if (err != NULL) {
3effb85eb3124c6f02cd89e22ffed0fc9afaddb9bnicholes return err;
3effb85eb3124c6f02cd89e22ffed0fc9afaddb9bnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes st->cache_bytes = atol(bytes);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
e8f95a682820a599fe41b22977010636be5c2717jim ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, cmd->server,
9efd5708f6f0ab1992f6a5233eb622ad5e4eae18sf "ldap cache: Setting shared memory cache size to "
9efd5708f6f0ab1992f6a5233eb622ad5e4eae18sf "%" APR_SIZE_T_FMT " bytes.",
9efd5708f6f0ab1992f6a5233eb622ad5e4eae18sf st->cache_bytes);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes return NULL;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes}
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
e8f95a682820a599fe41b22977010636be5c2717jimstatic const char *util_ldap_set_cache_file(cmd_parms *cmd, void *dummy,
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe const char *file)
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes{
e8f95a682820a599fe41b22977010636be5c2717jim util_ldap_state_t *st =
e8f95a682820a599fe41b22977010636be5c2717jim (util_ldap_state_t *)ap_get_module_config(cmd->server->module_config,
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes &ldap_module);
3effb85eb3124c6f02cd89e22ffed0fc9afaddb9bnicholes const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
3effb85eb3124c6f02cd89e22ffed0fc9afaddb9bnicholes
3effb85eb3124c6f02cd89e22ffed0fc9afaddb9bnicholes if (err != NULL) {
3effb85eb3124c6f02cd89e22ffed0fc9afaddb9bnicholes return err;
3effb85eb3124c6f02cd89e22ffed0fc9afaddb9bnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes if (file) {
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes st->cache_file = ap_server_root_relative(st->pool, file);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes else {
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes st->cache_file = NULL;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
e8f95a682820a599fe41b22977010636be5c2717jim ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, cmd->server,
e8f95a682820a599fe41b22977010636be5c2717jim "LDAP cache: Setting shared memory cache file to %s bytes.",
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes st->cache_file);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes return NULL;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes}
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
e8f95a682820a599fe41b22977010636be5c2717jimstatic const char *util_ldap_set_cache_ttl(cmd_parms *cmd, void *dummy,
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe const char *ttl)
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes{
e8f95a682820a599fe41b22977010636be5c2717jim util_ldap_state_t *st =
e8f95a682820a599fe41b22977010636be5c2717jim (util_ldap_state_t *)ap_get_module_config(cmd->server->module_config,
43c3e6a4b559b76b750c245ee95e2782c15b4296jim &ldap_module);
3effb85eb3124c6f02cd89e22ffed0fc9afaddb9bnicholes const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
3effb85eb3124c6f02cd89e22ffed0fc9afaddb9bnicholes
3effb85eb3124c6f02cd89e22ffed0fc9afaddb9bnicholes if (err != NULL) {
3effb85eb3124c6f02cd89e22ffed0fc9afaddb9bnicholes return err;
3effb85eb3124c6f02cd89e22ffed0fc9afaddb9bnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes st->search_cache_ttl = atol(ttl) * 1000000;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
e8f95a682820a599fe41b22977010636be5c2717jim ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, cmd->server,
9efd5708f6f0ab1992f6a5233eb622ad5e4eae18sf "ldap cache: Setting cache TTL to %ld microseconds.",
9efd5708f6f0ab1992f6a5233eb622ad5e4eae18sf st->search_cache_ttl);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes return NULL;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes}
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
e8f95a682820a599fe41b22977010636be5c2717jimstatic const char *util_ldap_set_cache_entries(cmd_parms *cmd, void *dummy,
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe const char *size)
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes{
e8f95a682820a599fe41b22977010636be5c2717jim util_ldap_state_t *st =
e8f95a682820a599fe41b22977010636be5c2717jim (util_ldap_state_t *)ap_get_module_config(cmd->server->module_config,
43c3e6a4b559b76b750c245ee95e2782c15b4296jim &ldap_module);
3effb85eb3124c6f02cd89e22ffed0fc9afaddb9bnicholes const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
3effb85eb3124c6f02cd89e22ffed0fc9afaddb9bnicholes if (err != NULL) {
3effb85eb3124c6f02cd89e22ffed0fc9afaddb9bnicholes return err;
3effb85eb3124c6f02cd89e22ffed0fc9afaddb9bnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes st->search_cache_size = atol(size);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes if (st->search_cache_size < 0) {
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes st->search_cache_size = 0;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
e8f95a682820a599fe41b22977010636be5c2717jim ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, cmd->server,
9efd5708f6f0ab1992f6a5233eb622ad5e4eae18sf "ldap cache: Setting search cache size to %ld entries.",
9efd5708f6f0ab1992f6a5233eb622ad5e4eae18sf st->search_cache_size);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes return NULL;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes}
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
e8f95a682820a599fe41b22977010636be5c2717jimstatic const char *util_ldap_set_opcache_ttl(cmd_parms *cmd, void *dummy,
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe const char *ttl)
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes{
e8f95a682820a599fe41b22977010636be5c2717jim util_ldap_state_t *st =
e8f95a682820a599fe41b22977010636be5c2717jim (util_ldap_state_t *)ap_get_module_config(cmd->server->module_config,
43c3e6a4b559b76b750c245ee95e2782c15b4296jim &ldap_module);
3effb85eb3124c6f02cd89e22ffed0fc9afaddb9bnicholes const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
3effb85eb3124c6f02cd89e22ffed0fc9afaddb9bnicholes
3effb85eb3124c6f02cd89e22ffed0fc9afaddb9bnicholes if (err != NULL) {
3effb85eb3124c6f02cd89e22ffed0fc9afaddb9bnicholes return err;
3effb85eb3124c6f02cd89e22ffed0fc9afaddb9bnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes st->compare_cache_ttl = atol(ttl) * 1000000;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
e8f95a682820a599fe41b22977010636be5c2717jim ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, cmd->server,
9efd5708f6f0ab1992f6a5233eb622ad5e4eae18sf "ldap cache: Setting operation cache TTL to %ld microseconds.",
9efd5708f6f0ab1992f6a5233eb622ad5e4eae18sf st->compare_cache_ttl);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes return NULL;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes}
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
e8f95a682820a599fe41b22977010636be5c2717jimstatic const char *util_ldap_set_opcache_entries(cmd_parms *cmd, void *dummy,
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe const char *size)
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes{
e8f95a682820a599fe41b22977010636be5c2717jim util_ldap_state_t *st =
e8f95a682820a599fe41b22977010636be5c2717jim (util_ldap_state_t *)ap_get_module_config(cmd->server->module_config,
43c3e6a4b559b76b750c245ee95e2782c15b4296jim &ldap_module);
3effb85eb3124c6f02cd89e22ffed0fc9afaddb9bnicholes const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
3effb85eb3124c6f02cd89e22ffed0fc9afaddb9bnicholes
3effb85eb3124c6f02cd89e22ffed0fc9afaddb9bnicholes if (err != NULL) {
3effb85eb3124c6f02cd89e22ffed0fc9afaddb9bnicholes return err;
3effb85eb3124c6f02cd89e22ffed0fc9afaddb9bnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes st->compare_cache_size = atol(size);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes if (st->compare_cache_size < 0) {
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes st->compare_cache_size = 0;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
e8f95a682820a599fe41b22977010636be5c2717jim ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, cmd->server,
9efd5708f6f0ab1992f6a5233eb622ad5e4eae18sf "ldap cache: Setting operation cache size to %ld entries.",
9efd5708f6f0ab1992f6a5233eb622ad5e4eae18sf st->compare_cache_size);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes return NULL;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes}
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
54d22ed1c429b903b029bbd62621f11a9e286137minfrin
54d22ed1c429b903b029bbd62621f11a9e286137minfrin/**
54d22ed1c429b903b029bbd62621f11a9e286137minfrin * Parse the certificate type.
54d22ed1c429b903b029bbd62621f11a9e286137minfrin *
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 *
54d22ed1c429b903b029bbd62621f11a9e286137minfrin * If no matches are found, APR_LDAP_CA_TYPE_UNKNOWN is returned.
54d22ed1c429b903b029bbd62621f11a9e286137minfrin */
88adce5ec0da39b41450ce1d5a77659168097e0cjortonstatic int util_ldap_parse_cert_type(const char *type)
88adce5ec0da39b41450ce1d5a77659168097e0cjorton{
54d22ed1c429b903b029bbd62621f11a9e286137minfrin /* Authority file in binary DER format */
54d22ed1c429b903b029bbd62621f11a9e286137minfrin if (0 == strcasecmp("CA_DER", type)) {
54d22ed1c429b903b029bbd62621f11a9e286137minfrin return APR_LDAP_CA_TYPE_DER;
54d22ed1c429b903b029bbd62621f11a9e286137minfrin }
54d22ed1c429b903b029bbd62621f11a9e286137minfrin
54d22ed1c429b903b029bbd62621f11a9e286137minfrin /* Authority file in Base64 format */
54d22ed1c429b903b029bbd62621f11a9e286137minfrin else if (0 == strcasecmp("CA_BASE64", type)) {
54d22ed1c429b903b029bbd62621f11a9e286137minfrin return APR_LDAP_CA_TYPE_BASE64;
54d22ed1c429b903b029bbd62621f11a9e286137minfrin }
54d22ed1c429b903b029bbd62621f11a9e286137minfrin
54d22ed1c429b903b029bbd62621f11a9e286137minfrin /* Netscape certificate database file/directory */
54d22ed1c429b903b029bbd62621f11a9e286137minfrin else if (0 == strcasecmp("CA_CERT7_DB", type)) {
54d22ed1c429b903b029bbd62621f11a9e286137minfrin return APR_LDAP_CA_TYPE_CERT7_DB;
54d22ed1c429b903b029bbd62621f11a9e286137minfrin }
54d22ed1c429b903b029bbd62621f11a9e286137minfrin
54d22ed1c429b903b029bbd62621f11a9e286137minfrin /* Netscape secmod file/directory */
54d22ed1c429b903b029bbd62621f11a9e286137minfrin else if (0 == strcasecmp("CA_SECMOD", type)) {
54d22ed1c429b903b029bbd62621f11a9e286137minfrin return APR_LDAP_CA_TYPE_SECMOD;
54d22ed1c429b903b029bbd62621f11a9e286137minfrin }
54d22ed1c429b903b029bbd62621f11a9e286137minfrin
54d22ed1c429b903b029bbd62621f11a9e286137minfrin /* Client cert file in DER format */
54d22ed1c429b903b029bbd62621f11a9e286137minfrin else if (0 == strcasecmp("CERT_DER", type)) {
54d22ed1c429b903b029bbd62621f11a9e286137minfrin return APR_LDAP_CERT_TYPE_DER;
54d22ed1c429b903b029bbd62621f11a9e286137minfrin }
54d22ed1c429b903b029bbd62621f11a9e286137minfrin
54d22ed1c429b903b029bbd62621f11a9e286137minfrin /* Client cert file in Base64 format */
54d22ed1c429b903b029bbd62621f11a9e286137minfrin else if (0 == strcasecmp("CERT_BASE64", type)) {
54d22ed1c429b903b029bbd62621f11a9e286137minfrin return APR_LDAP_CERT_TYPE_BASE64;
54d22ed1c429b903b029bbd62621f11a9e286137minfrin }
54d22ed1c429b903b029bbd62621f11a9e286137minfrin
09338db7fdcf82ecc189195347da3a3ed5d0287abnicholes /* Client cert file in PKCS#12 format */
09338db7fdcf82ecc189195347da3a3ed5d0287abnicholes else if (0 == strcasecmp("CERT_PFX", type)) {
09338db7fdcf82ecc189195347da3a3ed5d0287abnicholes return APR_LDAP_CERT_TYPE_PFX;
09338db7fdcf82ecc189195347da3a3ed5d0287abnicholes }
09338db7fdcf82ecc189195347da3a3ed5d0287abnicholes
54d22ed1c429b903b029bbd62621f11a9e286137minfrin /* Netscape client cert database file/directory */
54d22ed1c429b903b029bbd62621f11a9e286137minfrin else if (0 == strcasecmp("CERT_KEY3_DB", type)) {
54d22ed1c429b903b029bbd62621f11a9e286137minfrin return APR_LDAP_CERT_TYPE_KEY3_DB;
54d22ed1c429b903b029bbd62621f11a9e286137minfrin }
54d22ed1c429b903b029bbd62621f11a9e286137minfrin
54d22ed1c429b903b029bbd62621f11a9e286137minfrin /* Netscape client cert nickname */
54d22ed1c429b903b029bbd62621f11a9e286137minfrin else if (0 == strcasecmp("CERT_NICKNAME", type)) {
54d22ed1c429b903b029bbd62621f11a9e286137minfrin return APR_LDAP_CERT_TYPE_NICKNAME;
54d22ed1c429b903b029bbd62621f11a9e286137minfrin }
54d22ed1c429b903b029bbd62621f11a9e286137minfrin
54d22ed1c429b903b029bbd62621f11a9e286137minfrin /* Client cert key file in DER format */
54d22ed1c429b903b029bbd62621f11a9e286137minfrin else if (0 == strcasecmp("KEY_DER", type)) {
54d22ed1c429b903b029bbd62621f11a9e286137minfrin return APR_LDAP_KEY_TYPE_DER;
54d22ed1c429b903b029bbd62621f11a9e286137minfrin }
54d22ed1c429b903b029bbd62621f11a9e286137minfrin
54d22ed1c429b903b029bbd62621f11a9e286137minfrin /* Client cert key file in Base64 format */
54d22ed1c429b903b029bbd62621f11a9e286137minfrin else if (0 == strcasecmp("KEY_BASE64", type)) {
54d22ed1c429b903b029bbd62621f11a9e286137minfrin return APR_LDAP_KEY_TYPE_BASE64;
54d22ed1c429b903b029bbd62621f11a9e286137minfrin }
54d22ed1c429b903b029bbd62621f11a9e286137minfrin
09338db7fdcf82ecc189195347da3a3ed5d0287abnicholes /* Client cert key file in PKCS#12 format */
09338db7fdcf82ecc189195347da3a3ed5d0287abnicholes else if (0 == strcasecmp("KEY_PFX", type)) {
09338db7fdcf82ecc189195347da3a3ed5d0287abnicholes return APR_LDAP_KEY_TYPE_PFX;
09338db7fdcf82ecc189195347da3a3ed5d0287abnicholes }
09338db7fdcf82ecc189195347da3a3ed5d0287abnicholes
54d22ed1c429b903b029bbd62621f11a9e286137minfrin else {
54d22ed1c429b903b029bbd62621f11a9e286137minfrin return APR_LDAP_CA_TYPE_UNKNOWN;
54d22ed1c429b903b029bbd62621f11a9e286137minfrin }
54d22ed1c429b903b029bbd62621f11a9e286137minfrin
54d22ed1c429b903b029bbd62621f11a9e286137minfrin}
54d22ed1c429b903b029bbd62621f11a9e286137minfrin
54d22ed1c429b903b029bbd62621f11a9e286137minfrin
54d22ed1c429b903b029bbd62621f11a9e286137minfrin/**
54d22ed1c429b903b029bbd62621f11a9e286137minfrin * Set LDAPTrustedGlobalCert.
54d22ed1c429b903b029bbd62621f11a9e286137minfrin *
54d22ed1c429b903b029bbd62621f11a9e286137minfrin * This directive takes either two or three arguments:
54d22ed1c429b903b029bbd62621f11a9e286137minfrin * - certificate type
54d22ed1c429b903b029bbd62621f11a9e286137minfrin * - certificate file / directory / nickname
54d22ed1c429b903b029bbd62621f11a9e286137minfrin * - certificate password (optional)
54d22ed1c429b903b029bbd62621f11a9e286137minfrin *
54d22ed1c429b903b029bbd62621f11a9e286137minfrin * This directive may only be used globally.
54d22ed1c429b903b029bbd62621f11a9e286137minfrin */
e8f95a682820a599fe41b22977010636be5c2717jimstatic const char *util_ldap_set_trusted_global_cert(cmd_parms *cmd,
e8f95a682820a599fe41b22977010636be5c2717jim void *dummy,
e8f95a682820a599fe41b22977010636be5c2717jim const char *type,
e8f95a682820a599fe41b22977010636be5c2717jim const char *file,
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe const char *password)
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes{
54d22ed1c429b903b029bbd62621f11a9e286137minfrin util_ldap_state_t *st =
54d22ed1c429b903b029bbd62621f11a9e286137minfrin (util_ldap_state_t *)ap_get_module_config(cmd->server->module_config,
54d22ed1c429b903b029bbd62621f11a9e286137minfrin &ldap_module);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
5aa455d45abacfa675c88d4ff53fbe97c44ce545bnicholes apr_finfo_t finfo;
1223ef8a85a044b5e3a8df29391a66530153aefcbnicholes apr_status_t rv;
54d22ed1c429b903b029bbd62621f11a9e286137minfrin int cert_type = 0;
d5cff0d8e871bf2528aadd8736fb50dc044b1e6dbnicholes apr_ldap_opt_tls_cert_t *cert;
5aa455d45abacfa675c88d4ff53fbe97c44ce545bnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes if (err != NULL) {
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes return err;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
54d22ed1c429b903b029bbd62621f11a9e286137minfrin /* handle the certificate type */
54d22ed1c429b903b029bbd62621f11a9e286137minfrin if (type) {
54d22ed1c429b903b029bbd62621f11a9e286137minfrin cert_type = util_ldap_parse_cert_type(type);
54d22ed1c429b903b029bbd62621f11a9e286137minfrin if (APR_LDAP_CA_TYPE_UNKNOWN == cert_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 "KEY_DER, KEY_BASE64", type);
54d22ed1c429b903b029bbd62621f11a9e286137minfrin }
54d22ed1c429b903b029bbd62621f11a9e286137minfrin }
54d22ed1c429b903b029bbd62621f11a9e286137minfrin else {
54d22ed1c429b903b029bbd62621f11a9e286137minfrin return "Certificate type was not specified.";
54d22ed1c429b903b029bbd62621f11a9e286137minfrin }
54d22ed1c429b903b029bbd62621f11a9e286137minfrin
796e4a7141265d8ed7036e4628161c6eafb2a789jorton ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, cmd->server,
54d22ed1c429b903b029bbd62621f11a9e286137minfrin "LDAP: SSL trusted global cert - %s (type %s)",
54d22ed1c429b903b029bbd62621f11a9e286137minfrin file, type);
54d22ed1c429b903b029bbd62621f11a9e286137minfrin
54d22ed1c429b903b029bbd62621f11a9e286137minfrin /* add the certificate to the global array */
d5cff0d8e871bf2528aadd8736fb50dc044b1e6dbnicholes cert = (apr_ldap_opt_tls_cert_t *)apr_array_push(st->global_certs);
54d22ed1c429b903b029bbd62621f11a9e286137minfrin cert->type = cert_type;
54d22ed1c429b903b029bbd62621f11a9e286137minfrin cert->path = file;
54d22ed1c429b903b029bbd62621f11a9e286137minfrin cert->password = password;
54d22ed1c429b903b029bbd62621f11a9e286137minfrin
54d22ed1c429b903b029bbd62621f11a9e286137minfrin /* if file is a file or path, fix the path */
54d22ed1c429b903b029bbd62621f11a9e286137minfrin if (cert_type != APR_LDAP_CA_TYPE_UNKNOWN &&
54d22ed1c429b903b029bbd62621f11a9e286137minfrin cert_type != APR_LDAP_CERT_TYPE_NICKNAME) {
54d22ed1c429b903b029bbd62621f11a9e286137minfrin
54d22ed1c429b903b029bbd62621f11a9e286137minfrin cert->path = ap_server_root_relative(cmd->pool, file);
54d22ed1c429b903b029bbd62621f11a9e286137minfrin if (cert->path &&
e8f95a682820a599fe41b22977010636be5c2717jim ((rv = apr_stat (&finfo, cert->path, APR_FINFO_MIN, cmd->pool))
e8f95a682820a599fe41b22977010636be5c2717jim != APR_SUCCESS))
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe {
54d22ed1c429b903b029bbd62621f11a9e286137minfrin ap_log_error(APLOG_MARK, APLOG_ERR, rv, cmd->server,
54d22ed1c429b903b029bbd62621f11a9e286137minfrin "LDAP: Could not open SSL trusted certificate "
54d22ed1c429b903b029bbd62621f11a9e286137minfrin "authority file - %s",
54d22ed1c429b903b029bbd62621f11a9e286137minfrin cert->path == NULL ? file : cert->path);
54d22ed1c429b903b029bbd62621f11a9e286137minfrin return "Invalid global certificate file path";
54d22ed1c429b903b029bbd62621f11a9e286137minfrin }
5aa455d45abacfa675c88d4ff53fbe97c44ce545bnicholes }
5aa455d45abacfa675c88d4ff53fbe97c44ce545bnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes return(NULL);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes}
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
54d22ed1c429b903b029bbd62621f11a9e286137minfrin/**
54d22ed1c429b903b029bbd62621f11a9e286137minfrin * Set LDAPTrustedClientCert.
54d22ed1c429b903b029bbd62621f11a9e286137minfrin *
54d22ed1c429b903b029bbd62621f11a9e286137minfrin * This directive takes either two or three arguments:
54d22ed1c429b903b029bbd62621f11a9e286137minfrin * - certificate type
54d22ed1c429b903b029bbd62621f11a9e286137minfrin * - certificate file / directory / nickname
54d22ed1c429b903b029bbd62621f11a9e286137minfrin * - certificate password (optional)
54d22ed1c429b903b029bbd62621f11a9e286137minfrin */
e8f95a682820a599fe41b22977010636be5c2717jimstatic const char *util_ldap_set_trusted_client_cert(cmd_parms *cmd,
e8f95a682820a599fe41b22977010636be5c2717jim void *config,
e8f95a682820a599fe41b22977010636be5c2717jim const char *type,
e8f95a682820a599fe41b22977010636be5c2717jim const char *file,
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe const char *password)
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes{
ae1981fc94adf2b231e2d0e15d2f895b2138c969covener util_ldap_config_t *dc = config;
54d22ed1c429b903b029bbd62621f11a9e286137minfrin apr_finfo_t finfo;
54d22ed1c429b903b029bbd62621f11a9e286137minfrin apr_status_t rv;
54d22ed1c429b903b029bbd62621f11a9e286137minfrin int cert_type = 0;
d5cff0d8e871bf2528aadd8736fb50dc044b1e6dbnicholes apr_ldap_opt_tls_cert_t *cert;
54d22ed1c429b903b029bbd62621f11a9e286137minfrin
54d22ed1c429b903b029bbd62621f11a9e286137minfrin /* handle the certificate type */
54d22ed1c429b903b029bbd62621f11a9e286137minfrin if (type) {
54d22ed1c429b903b029bbd62621f11a9e286137minfrin cert_type = util_ldap_parse_cert_type(type);
54d22ed1c429b903b029bbd62621f11a9e286137minfrin if (APR_LDAP_CA_TYPE_UNKNOWN == cert_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",
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe type);
54d22ed1c429b903b029bbd62621f11a9e286137minfrin }
ae1981fc94adf2b231e2d0e15d2f895b2138c969covener else if ( APR_LDAP_CA_TYPE_CERT7_DB == cert_type ||
54d22ed1c429b903b029bbd62621f11a9e286137minfrin APR_LDAP_CA_TYPE_SECMOD == cert_type ||
09338db7fdcf82ecc189195347da3a3ed5d0287abnicholes APR_LDAP_CERT_TYPE_PFX == cert_type ||
54d22ed1c429b903b029bbd62621f11a9e286137minfrin APR_LDAP_CERT_TYPE_KEY3_DB == cert_type) {
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 "KEY_BASE64 may be used.", type);
54d22ed1c429b903b029bbd62621f11a9e286137minfrin }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
54d22ed1c429b903b029bbd62621f11a9e286137minfrin else {
54d22ed1c429b903b029bbd62621f11a9e286137minfrin return "Certificate type was not specified.";
54d22ed1c429b903b029bbd62621f11a9e286137minfrin }
54d22ed1c429b903b029bbd62621f11a9e286137minfrin
796e4a7141265d8ed7036e4628161c6eafb2a789jorton ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, cmd->server,
54d22ed1c429b903b029bbd62621f11a9e286137minfrin "LDAP: SSL trusted client cert - %s (type %s)",
54d22ed1c429b903b029bbd62621f11a9e286137minfrin file, type);
54d22ed1c429b903b029bbd62621f11a9e286137minfrin
ae1981fc94adf2b231e2d0e15d2f895b2138c969covener /* add the certificate to the client array */
ae1981fc94adf2b231e2d0e15d2f895b2138c969covener cert = (apr_ldap_opt_tls_cert_t *)apr_array_push(dc->client_certs);
e8f95a682820a599fe41b22977010636be5c2717jim cert->type = cert_type;
54d22ed1c429b903b029bbd62621f11a9e286137minfrin cert->path = file;
54d22ed1c429b903b029bbd62621f11a9e286137minfrin cert->password = password;
54d22ed1c429b903b029bbd62621f11a9e286137minfrin
54d22ed1c429b903b029bbd62621f11a9e286137minfrin /* if file is a file or path, fix the path */
54d22ed1c429b903b029bbd62621f11a9e286137minfrin if (cert_type != APR_LDAP_CA_TYPE_UNKNOWN &&
54d22ed1c429b903b029bbd62621f11a9e286137minfrin cert_type != APR_LDAP_CERT_TYPE_NICKNAME) {
54d22ed1c429b903b029bbd62621f11a9e286137minfrin
54d22ed1c429b903b029bbd62621f11a9e286137minfrin cert->path = ap_server_root_relative(cmd->pool, file);
54d22ed1c429b903b029bbd62621f11a9e286137minfrin if (cert->path &&
e8f95a682820a599fe41b22977010636be5c2717jim ((rv = apr_stat (&finfo, cert->path, APR_FINFO_MIN, cmd->pool))
e8f95a682820a599fe41b22977010636be5c2717jim != APR_SUCCESS))
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe {
54d22ed1c429b903b029bbd62621f11a9e286137minfrin ap_log_error(APLOG_MARK, APLOG_ERR, rv, cmd->server,
54d22ed1c429b903b029bbd62621f11a9e286137minfrin "LDAP: Could not open SSL client certificate "
54d22ed1c429b903b029bbd62621f11a9e286137minfrin "file - %s",
54d22ed1c429b903b029bbd62621f11a9e286137minfrin cert->path == NULL ? file : cert->path);
54d22ed1c429b903b029bbd62621f11a9e286137minfrin return "Invalid client certificate file path";
54d22ed1c429b903b029bbd62621f11a9e286137minfrin }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
54d22ed1c429b903b029bbd62621f11a9e286137minfrin }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
54d22ed1c429b903b029bbd62621f11a9e286137minfrin return(NULL);
54d22ed1c429b903b029bbd62621f11a9e286137minfrin}
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
54d22ed1c429b903b029bbd62621f11a9e286137minfrin/**
54d22ed1c429b903b029bbd62621f11a9e286137minfrin * Set LDAPTrustedMode.
e8f95a682820a599fe41b22977010636be5c2717jim *
54d22ed1c429b903b029bbd62621f11a9e286137minfrin * This directive sets what encryption mode to use on a connection:
54d22ed1c429b903b029bbd62621f11a9e286137minfrin * - None (No encryption)
54d22ed1c429b903b029bbd62621f11a9e286137minfrin * - SSL (SSL encryption)
54d22ed1c429b903b029bbd62621f11a9e286137minfrin * - STARTTLS (TLS encryption)
e8f95a682820a599fe41b22977010636be5c2717jim */
e8f95a682820a599fe41b22977010636be5c2717jimstatic const char *util_ldap_set_trusted_mode(cmd_parms *cmd, void *dummy,
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe const char *mode)
54d22ed1c429b903b029bbd62621f11a9e286137minfrin{
54d22ed1c429b903b029bbd62621f11a9e286137minfrin util_ldap_state_t *st =
54d22ed1c429b903b029bbd62621f11a9e286137minfrin (util_ldap_state_t *)ap_get_module_config(cmd->server->module_config,
54d22ed1c429b903b029bbd62621f11a9e286137minfrin &ldap_module);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
796e4a7141265d8ed7036e4628161c6eafb2a789jorton ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, cmd->server,
54d22ed1c429b903b029bbd62621f11a9e286137minfrin "LDAP: SSL trusted mode - %s",
54d22ed1c429b903b029bbd62621f11a9e286137minfrin mode);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
54d22ed1c429b903b029bbd62621f11a9e286137minfrin if (0 == strcasecmp("NONE", mode)) {
54d22ed1c429b903b029bbd62621f11a9e286137minfrin st->secure = APR_LDAP_NONE;
54d22ed1c429b903b029bbd62621f11a9e286137minfrin }
54d22ed1c429b903b029bbd62621f11a9e286137minfrin else if (0 == strcasecmp("SSL", mode)) {
54d22ed1c429b903b029bbd62621f11a9e286137minfrin st->secure = APR_LDAP_SSL;
54d22ed1c429b903b029bbd62621f11a9e286137minfrin }
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe else if ( (0 == strcasecmp("TLS", mode))
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe || (0 == strcasecmp("STARTTLS", mode))) {
54d22ed1c429b903b029bbd62621f11a9e286137minfrin st->secure = APR_LDAP_STARTTLS;
54d22ed1c429b903b029bbd62621f11a9e286137minfrin }
54d22ed1c429b903b029bbd62621f11a9e286137minfrin else {
54d22ed1c429b903b029bbd62621f11a9e286137minfrin return "Invalid LDAPTrustedMode setting: must be one of NONE, "
54d22ed1c429b903b029bbd62621f11a9e286137minfrin "SSL, or TLS/STARTTLS";
54d22ed1c429b903b029bbd62621f11a9e286137minfrin }
54d22ed1c429b903b029bbd62621f11a9e286137minfrin
54d22ed1c429b903b029bbd62621f11a9e286137minfrin st->secure_set = 1;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes return(NULL);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes}
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
e8f95a682820a599fe41b22977010636be5c2717jimstatic const char *util_ldap_set_verify_srv_cert(cmd_parms *cmd,
e8f95a682820a599fe41b22977010636be5c2717jim void *dummy,
141e1368614dc7564e1627671361b01b4869b491bnicholes int mode)
141e1368614dc7564e1627671361b01b4869b491bnicholes{
141e1368614dc7564e1627671361b01b4869b491bnicholes util_ldap_state_t *st =
141e1368614dc7564e1627671361b01b4869b491bnicholes (util_ldap_state_t *)ap_get_module_config(cmd->server->module_config,
141e1368614dc7564e1627671361b01b4869b491bnicholes &ldap_module);
cbbfa8f4222ecc7b2e0f16db3032d0118d6a0accbnicholes const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
cbbfa8f4222ecc7b2e0f16db3032d0118d6a0accbnicholes
cbbfa8f4222ecc7b2e0f16db3032d0118d6a0accbnicholes if (err != NULL) {
cbbfa8f4222ecc7b2e0f16db3032d0118d6a0accbnicholes return err;
cbbfa8f4222ecc7b2e0f16db3032d0118d6a0accbnicholes }
141e1368614dc7564e1627671361b01b4869b491bnicholes
796e4a7141265d8ed7036e4628161c6eafb2a789jorton ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, cmd->server,
e8f95a682820a599fe41b22977010636be5c2717jim "LDAP: SSL verify server certificate - %s",
141e1368614dc7564e1627671361b01b4869b491bnicholes mode?"TRUE":"FALSE");
141e1368614dc7564e1627671361b01b4869b491bnicholes
141e1368614dc7564e1627671361b01b4869b491bnicholes st->verify_svr_cert = mode;
141e1368614dc7564e1627671361b01b4869b491bnicholes
141e1368614dc7564e1627671361b01b4869b491bnicholes return(NULL);
141e1368614dc7564e1627671361b01b4869b491bnicholes}
141e1368614dc7564e1627671361b01b4869b491bnicholes
141e1368614dc7564e1627671361b01b4869b491bnicholes
e8f95a682820a599fe41b22977010636be5c2717jimstatic const char *util_ldap_set_connection_timeout(cmd_parms *cmd,
e8f95a682820a599fe41b22977010636be5c2717jim void *dummy,
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe const char *ttl)
0894cd17fe3f614bf01dbf84f1414756bd5a34c3bnicholes{
465bb68501690d7a47bfd2a6129580047d76d8f1rederpj#ifdef LDAP_OPT_NETWORK_TIMEOUT
e8f95a682820a599fe41b22977010636be5c2717jim util_ldap_state_t *st =
e8f95a682820a599fe41b22977010636be5c2717jim (util_ldap_state_t *)ap_get_module_config(cmd->server->module_config,
43c3e6a4b559b76b750c245ee95e2782c15b4296jim &ldap_module);
465bb68501690d7a47bfd2a6129580047d76d8f1rederpj#endif
cbbfa8f4222ecc7b2e0f16db3032d0118d6a0accbnicholes const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
cbbfa8f4222ecc7b2e0f16db3032d0118d6a0accbnicholes
cbbfa8f4222ecc7b2e0f16db3032d0118d6a0accbnicholes if (err != NULL) {
cbbfa8f4222ecc7b2e0f16db3032d0118d6a0accbnicholes return err;
cbbfa8f4222ecc7b2e0f16db3032d0118d6a0accbnicholes }
0894cd17fe3f614bf01dbf84f1414756bd5a34c3bnicholes
1c9fe70e77b36d36ae34997fe25fe47beacf8709bnicholes#ifdef LDAP_OPT_NETWORK_TIMEOUT
0894cd17fe3f614bf01dbf84f1414756bd5a34c3bnicholes st->connectionTimeout = atol(ttl);
0894cd17fe3f614bf01dbf84f1414756bd5a34c3bnicholes
e8f95a682820a599fe41b22977010636be5c2717jim ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, cmd->server,
9efd5708f6f0ab1992f6a5233eb622ad5e4eae18sf "ldap connection: Setting connection timeout to %ld seconds.",
9efd5708f6f0ab1992f6a5233eb622ad5e4eae18sf st->connectionTimeout);
1c9fe70e77b36d36ae34997fe25fe47beacf8709bnicholes#else
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." );
1c9fe70e77b36d36ae34997fe25fe47beacf8709bnicholes#endif
0894cd17fe3f614bf01dbf84f1414756bd5a34c3bnicholes
0894cd17fe3f614bf01dbf84f1414756bd5a34c3bnicholes return NULL;
0894cd17fe3f614bf01dbf84f1414756bd5a34c3bnicholes}
0894cd17fe3f614bf01dbf84f1414756bd5a34c3bnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
9ad7b260be233be7d7b5576979825cac72e15498rederpjstatic const char *util_ldap_set_chase_referrals(cmd_parms *cmd,
9ad7b260be233be7d7b5576979825cac72e15498rederpj void *config,
9ad7b260be233be7d7b5576979825cac72e15498rederpj int mode)
9ad7b260be233be7d7b5576979825cac72e15498rederpj{
9ad7b260be233be7d7b5576979825cac72e15498rederpj util_ldap_config_t *dc = config;
9ad7b260be233be7d7b5576979825cac72e15498rederpj
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");
9ad7b260be233be7d7b5576979825cac72e15498rederpj
9ad7b260be233be7d7b5576979825cac72e15498rederpj dc->ChaseReferrals = mode;
9ad7b260be233be7d7b5576979825cac72e15498rederpj
9ad7b260be233be7d7b5576979825cac72e15498rederpj return(NULL);
9ad7b260be233be7d7b5576979825cac72e15498rederpj}
9ad7b260be233be7d7b5576979825cac72e15498rederpj
0f60998368b493f90120180a93fc2e1e74490872covenerstatic const char *util_ldap_set_debug_level(cmd_parms *cmd,
0f60998368b493f90120180a93fc2e1e74490872covener void *config,
0f60998368b493f90120180a93fc2e1e74490872covener const char *arg) {
0f60998368b493f90120180a93fc2e1e74490872covener util_ldap_state_t *st =
0f60998368b493f90120180a93fc2e1e74490872covener (util_ldap_state_t *)ap_get_module_config(cmd->server->module_config,
0f60998368b493f90120180a93fc2e1e74490872covener &ldap_module);
0f60998368b493f90120180a93fc2e1e74490872covener
0f60998368b493f90120180a93fc2e1e74490872covener const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
0f60998368b493f90120180a93fc2e1e74490872covener if (err != NULL) {
0f60998368b493f90120180a93fc2e1e74490872covener return err;
0f60998368b493f90120180a93fc2e1e74490872covener }
0f60998368b493f90120180a93fc2e1e74490872covener
0f60998368b493f90120180a93fc2e1e74490872covener#ifndef AP_LDAP_OPT_DEBUG
0f60998368b493f90120180a93fc2e1e74490872covener return "This directive is not supported with the currently linked LDAP library";
0f60998368b493f90120180a93fc2e1e74490872covener#endif
0f60998368b493f90120180a93fc2e1e74490872covener
0f60998368b493f90120180a93fc2e1e74490872covener st->debug_level = atoi(arg);
0f60998368b493f90120180a93fc2e1e74490872covener return NULL;
0f60998368b493f90120180a93fc2e1e74490872covener}
0f60998368b493f90120180a93fc2e1e74490872covener
9ad7b260be233be7d7b5576979825cac72e15498rederpjstatic const char *util_ldap_set_referral_hop_limit(cmd_parms *cmd,
9ad7b260be233be7d7b5576979825cac72e15498rederpj void *config,
9ad7b260be233be7d7b5576979825cac72e15498rederpj const char *hop_limit)
9ad7b260be233be7d7b5576979825cac72e15498rederpj{
9ad7b260be233be7d7b5576979825cac72e15498rederpj util_ldap_config_t *dc = config;
9ad7b260be233be7d7b5576979825cac72e15498rederpj
9ad7b260be233be7d7b5576979825cac72e15498rederpj dc->ReferralHopLimit = atol(hop_limit);
9ad7b260be233be7d7b5576979825cac72e15498rederpj
67c5e190a7b84528b8895d7ef7be81712d206805covener if (dc->ReferralHopLimit <= 0) {
67c5e190a7b84528b8895d7ef7be81712d206805covener return "LDAPReferralHopLimit must be greater than zero (Use 'LDAPReferrals Off' to disable referral chasing)";
67c5e190a7b84528b8895d7ef7be81712d206805covener }
67c5e190a7b84528b8895d7ef7be81712d206805covener
9ad7b260be233be7d7b5576979825cac72e15498rederpj ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, cmd->server,
9ad7b260be233be7d7b5576979825cac72e15498rederpj "LDAP: Limit chased referrals to maximum of %d hops.",
9ad7b260be233be7d7b5576979825cac72e15498rederpj dc->ReferralHopLimit);
9ad7b260be233be7d7b5576979825cac72e15498rederpj
9ad7b260be233be7d7b5576979825cac72e15498rederpj return NULL;
9ad7b260be233be7d7b5576979825cac72e15498rederpj}
9ad7b260be233be7d7b5576979825cac72e15498rederpj
9ad7b260be233be7d7b5576979825cac72e15498rederpjstatic void *util_ldap_create_dir_config(apr_pool_t *p, char *d) {
9ad7b260be233be7d7b5576979825cac72e15498rederpj util_ldap_config_t *dc =
9ad7b260be233be7d7b5576979825cac72e15498rederpj (util_ldap_config_t *) apr_pcalloc(p,sizeof(util_ldap_config_t));
9ad7b260be233be7d7b5576979825cac72e15498rederpj
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));
128a5d93141a86e3afa151e921035a07297c9833rederpj dc->ChaseReferrals = AP_LDAP_CHASEREFERRALS_ON;
87587593f1a53030e840acc0dec6cc881022ea40covener dc->ReferralHopLimit = AP_LDAP_HOPLIMIT_UNSET;
9ad7b260be233be7d7b5576979825cac72e15498rederpj
9ad7b260be233be7d7b5576979825cac72e15498rederpj return dc;
9ad7b260be233be7d7b5576979825cac72e15498rederpj}
9ad7b260be233be7d7b5576979825cac72e15498rederpj
4be9c459920a7c1cfe62d654327dae5c4bb6b284sfstatic const char *util_ldap_set_op_timeout(cmd_parms *cmd,
4be9c459920a7c1cfe62d654327dae5c4bb6b284sf void *dummy,
4be9c459920a7c1cfe62d654327dae5c4bb6b284sf const char *val)
4be9c459920a7c1cfe62d654327dae5c4bb6b284sf{
4be9c459920a7c1cfe62d654327dae5c4bb6b284sf long timeout;
4be9c459920a7c1cfe62d654327dae5c4bb6b284sf char *endptr;
4be9c459920a7c1cfe62d654327dae5c4bb6b284sf util_ldap_state_t *st =
4be9c459920a7c1cfe62d654327dae5c4bb6b284sf (util_ldap_state_t *)ap_get_module_config(cmd->server->module_config,
4be9c459920a7c1cfe62d654327dae5c4bb6b284sf &ldap_module);
4be9c459920a7c1cfe62d654327dae5c4bb6b284sf const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
4be9c459920a7c1cfe62d654327dae5c4bb6b284sf
4be9c459920a7c1cfe62d654327dae5c4bb6b284sf if (err != NULL) {
4be9c459920a7c1cfe62d654327dae5c4bb6b284sf return err;
4be9c459920a7c1cfe62d654327dae5c4bb6b284sf }
4be9c459920a7c1cfe62d654327dae5c4bb6b284sf
4be9c459920a7c1cfe62d654327dae5c4bb6b284sf timeout = strtol(val, &endptr, 10);
4be9c459920a7c1cfe62d654327dae5c4bb6b284sf if ((val == endptr) || (*endptr != '\0')) {
4be9c459920a7c1cfe62d654327dae5c4bb6b284sf return "Timeout not numerical";
4be9c459920a7c1cfe62d654327dae5c4bb6b284sf }
4be9c459920a7c1cfe62d654327dae5c4bb6b284sf if (timeout < 0) {
4be9c459920a7c1cfe62d654327dae5c4bb6b284sf return "Timeout must be non-negative";
4be9c459920a7c1cfe62d654327dae5c4bb6b284sf }
4be9c459920a7c1cfe62d654327dae5c4bb6b284sf
4be9c459920a7c1cfe62d654327dae5c4bb6b284sf if (timeout) {
4be9c459920a7c1cfe62d654327dae5c4bb6b284sf if (!st->opTimeout) {
4be9c459920a7c1cfe62d654327dae5c4bb6b284sf st->opTimeout = apr_pcalloc(cmd->pool, sizeof(struct timeval));
4be9c459920a7c1cfe62d654327dae5c4bb6b284sf }
4be9c459920a7c1cfe62d654327dae5c4bb6b284sf st->opTimeout->tv_sec = timeout;
4be9c459920a7c1cfe62d654327dae5c4bb6b284sf }
4be9c459920a7c1cfe62d654327dae5c4bb6b284sf else {
4be9c459920a7c1cfe62d654327dae5c4bb6b284sf st->opTimeout = NULL;
4be9c459920a7c1cfe62d654327dae5c4bb6b284sf }
4be9c459920a7c1cfe62d654327dae5c4bb6b284sf
4be9c459920a7c1cfe62d654327dae5c4bb6b284sf ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, cmd->server,
9efd5708f6f0ab1992f6a5233eb622ad5e4eae18sf "ldap connection: Setting op timeout to %ld seconds.",
9efd5708f6f0ab1992f6a5233eb622ad5e4eae18sf timeout);
4be9c459920a7c1cfe62d654327dae5c4bb6b284sf
4be9c459920a7c1cfe62d654327dae5c4bb6b284sf#ifndef LDAP_OPT_TIMEOUT
4be9c459920a7c1cfe62d654327dae5c4bb6b284sf
4be9c459920a7c1cfe62d654327dae5c4bb6b284sf ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, cmd->server,
4be9c459920a7c1cfe62d654327dae5c4bb6b284sf "LDAP: LDAP_OPT_TIMEOUT option not supported by the "
4be9c459920a7c1cfe62d654327dae5c4bb6b284sf "LDAP library in use. Using LDAPTimeout value as search "
4be9c459920a7c1cfe62d654327dae5c4bb6b284sf "timeout only." );
4be9c459920a7c1cfe62d654327dae5c4bb6b284sf#endif
4be9c459920a7c1cfe62d654327dae5c4bb6b284sf
4be9c459920a7c1cfe62d654327dae5c4bb6b284sf return NULL;
4be9c459920a7c1cfe62d654327dae5c4bb6b284sf}
4be9c459920a7c1cfe62d654327dae5c4bb6b284sf
4be9c459920a7c1cfe62d654327dae5c4bb6b284sf
9ad7b260be233be7d7b5576979825cac72e15498rederpj
8113dac419143273351446c3ad653f3fe5ba5cfdwrowestatic void *util_ldap_create_config(apr_pool_t *p, server_rec *s)
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes{
e8f95a682820a599fe41b22977010636be5c2717jim util_ldap_state_t *st =
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes (util_ldap_state_t *)apr_pcalloc(p, sizeof(util_ldap_state_t));
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
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.
a0b44ec81b32ffb946537d4e43e1c3a3f7594137gregames */
490046d2a164ad86cc63bd789f32eaed663d239abnicholes apr_pool_create(&st->pool, p);
490046d2a164ad86cc63bd789f32eaed663d239abnicholes#if APR_HAS_THREADS
490046d2a164ad86cc63bd789f32eaed663d239abnicholes apr_thread_mutex_create(&st->mutex, APR_THREAD_MUTEX_DEFAULT, st->pool);
490046d2a164ad86cc63bd789f32eaed663d239abnicholes#endif
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
ecc6e723b804fb4b8f858910eff3f88242ec56fasf st->cache_bytes = 500000;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes st->search_cache_ttl = 600000000;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes st->search_cache_size = 1024;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes st->compare_cache_ttl = 600000000;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes st->compare_cache_size = 1024;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes st->connections = NULL;
54d22ed1c429b903b029bbd62621f11a9e286137minfrin st->ssl_supported = 0;
54d22ed1c429b903b029bbd62621f11a9e286137minfrin st->global_certs = apr_array_make(p, 10, sizeof(apr_ldap_opt_tls_cert_t));
54d22ed1c429b903b029bbd62621f11a9e286137minfrin st->secure = APR_LDAP_NONE;
54d22ed1c429b903b029bbd62621f11a9e286137minfrin st->secure_set = 0;
0894cd17fe3f614bf01dbf84f1414756bd5a34c3bnicholes st->connectionTimeout = 10;
4be9c459920a7c1cfe62d654327dae5c4bb6b284sf st->opTimeout = apr_pcalloc(p, sizeof(struct timeval));
4be9c459920a7c1cfe62d654327dae5c4bb6b284sf st->opTimeout->tv_sec = 60;
141e1368614dc7564e1627671361b01b4869b491bnicholes st->verify_svr_cert = 1;
54d22ed1c429b903b029bbd62621f11a9e286137minfrin
54d22ed1c429b903b029bbd62621f11a9e286137minfrin return st;
54d22ed1c429b903b029bbd62621f11a9e286137minfrin}
54d22ed1c429b903b029bbd62621f11a9e286137minfrin
f2386b627177c7a80d38fed6ec0aed3c086909c1covener/* cache-related settings are not merged here, but in the post_config hook,
f2386b627177c7a80d38fed6ec0aed3c086909c1covener * since the cache has not yet sprung to life
f2386b627177c7a80d38fed6ec0aed3c086909c1covener */
e8f95a682820a599fe41b22977010636be5c2717jimstatic void *util_ldap_merge_config(apr_pool_t *p, void *basev,
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe void *overridesv)
54d22ed1c429b903b029bbd62621f11a9e286137minfrin{
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;
54d22ed1c429b903b029bbd62621f11a9e286137minfrin
9c247afacdbb56fa794715f2ac218eb1cae39fe8bnicholes st->pool = overrides->pool;
490046d2a164ad86cc63bd789f32eaed663d239abnicholes#if APR_HAS_THREADS
9c247afacdbb56fa794715f2ac218eb1cae39fe8bnicholes st->mutex = overrides->mutex;
490046d2a164ad86cc63bd789f32eaed663d239abnicholes#endif
54d22ed1c429b903b029bbd62621f11a9e286137minfrin
9c247afacdbb56fa794715f2ac218eb1cae39fe8bnicholes /* The cache settings can not be modified in a
9c247afacdbb56fa794715f2ac218eb1cae39fe8bnicholes virtual host since all server use the same
9c247afacdbb56fa794715f2ac218eb1cae39fe8bnicholes shared memory cache. */
54d22ed1c429b903b029bbd62621f11a9e286137minfrin st->cache_bytes = base->cache_bytes;
54d22ed1c429b903b029bbd62621f11a9e286137minfrin st->search_cache_ttl = base->search_cache_ttl;
54d22ed1c429b903b029bbd62621f11a9e286137minfrin st->search_cache_size = base->search_cache_size;
54d22ed1c429b903b029bbd62621f11a9e286137minfrin st->compare_cache_ttl = base->compare_cache_ttl;
54d22ed1c429b903b029bbd62621f11a9e286137minfrin st->compare_cache_size = base->compare_cache_size;
9ab5933c174cb21de69e8305f80544cbe7ed2a7ccovener st->util_ldap_cache_lock = base->util_ldap_cache_lock;
9c247afacdbb56fa794715f2ac218eb1cae39fe8bnicholes
9c247afacdbb56fa794715f2ac218eb1cae39fe8bnicholes st->connections = NULL;
9c247afacdbb56fa794715f2ac218eb1cae39fe8bnicholes st->ssl_supported = 0;
e8f95a682820a599fe41b22977010636be5c2717jim st->global_certs = apr_array_append(p, base->global_certs,
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe overrides->global_certs);
e8f95a682820a599fe41b22977010636be5c2717jim st->secure = (overrides->secure_set == 0) ? base->secure
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe : overrides->secure;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
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. */
cbbfa8f4222ecc7b2e0f16db3032d0118d6a0accbnicholes st->connectionTimeout = base->connectionTimeout;
4be9c459920a7c1cfe62d654327dae5c4bb6b284sf st->opTimeout = base->opTimeout;
cbbfa8f4222ecc7b2e0f16db3032d0118d6a0accbnicholes st->verify_svr_cert = base->verify_svr_cert;
0f60998368b493f90120180a93fc2e1e74490872covener st->debug_level = base->debug_level;
9c247afacdbb56fa794715f2ac218eb1cae39fe8bnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes return st;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes}
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholesstatic apr_status_t util_ldap_cleanup_module(void *data)
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes{
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes server_rec *s = data;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes util_ldap_state_t *st = (util_ldap_state_t *)ap_get_module_config(
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes s->module_config, &ldap_module);
e8f95a682820a599fe41b22977010636be5c2717jim
54d22ed1c429b903b029bbd62621f11a9e286137minfrin if (st->ssl_supported) {
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes apr_ldap_ssl_deinit();
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes return APR_SUCCESS;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes}
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
11f2c481e1d57bedb3f758565307501e9a2730ddtrawickstatic int util_ldap_pre_config(apr_pool_t *pconf, apr_pool_t *plog,
11f2c481e1d57bedb3f758565307501e9a2730ddtrawick apr_pool_t *ptemp)
11f2c481e1d57bedb3f758565307501e9a2730ddtrawick{
11f2c481e1d57bedb3f758565307501e9a2730ddtrawick apr_status_t result;
11f2c481e1d57bedb3f758565307501e9a2730ddtrawick
43997561b2302d13dee973998e77743a3ddd2374trawick result = ap_mutex_register(pconf, ldap_cache_mutex_type, NULL,
11f2c481e1d57bedb3f758565307501e9a2730ddtrawick APR_LOCK_DEFAULT, 0);
11f2c481e1d57bedb3f758565307501e9a2730ddtrawick if (result != APR_SUCCESS) {
11f2c481e1d57bedb3f758565307501e9a2730ddtrawick return result;
11f2c481e1d57bedb3f758565307501e9a2730ddtrawick }
11f2c481e1d57bedb3f758565307501e9a2730ddtrawick
11f2c481e1d57bedb3f758565307501e9a2730ddtrawick return OK;
11f2c481e1d57bedb3f758565307501e9a2730ddtrawick}
11f2c481e1d57bedb3f758565307501e9a2730ddtrawick
e8f95a682820a599fe41b22977010636be5c2717jimstatic int util_ldap_post_config(apr_pool_t *p, apr_pool_t *plog,
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes apr_pool_t *ptemp, server_rec *s)
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes{
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes apr_status_t result;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes server_rec *s_vhost;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes util_ldap_state_t *st_vhost;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe util_ldap_state_t *st = (util_ldap_state_t *)
e8f95a682820a599fe41b22977010636be5c2717jim ap_get_module_config(s->module_config,
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe &ldap_module);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes void *data;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes const char *userdata_key = "util_ldap_init";
d5cff0d8e871bf2528aadd8736fb50dc044b1e6dbnicholes apr_ldap_err_t *result_err = NULL;
d5cff0d8e871bf2528aadd8736fb50dc044b1e6dbnicholes int rc;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
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 if (!data) {
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes apr_pool_userdata_set((const void *)1, userdata_key,
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes apr_pool_cleanup_null, s->process->pool);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes#if APR_HAS_SHARED_MEMORY
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes /* If the cache file already exists then delete it. Otherwise we are
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * going to run into problems creating the shared memory. */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes if (st->cache_file) {
490046d2a164ad86cc63bd789f32eaed663d239abnicholes char *lck_file = apr_pstrcat(ptemp, st->cache_file, ".lck",
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe NULL);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes apr_file_remove(lck_file, ptemp);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes#endif
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes return OK;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes#if APR_HAS_SHARED_MEMORY
e8f95a682820a599fe41b22977010636be5c2717jim /* initializing cache if shared memory size is not zero and we already
e8f95a682820a599fe41b22977010636be5c2717jim * don't have shm address
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes if (!st->cache_shm && st->cache_bytes > 0) {
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes#endif
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes result = util_ldap_cache_init(p, st);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes if (result != APR_SUCCESS) {
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes ap_log_error(APLOG_MARK, APLOG_ERR, result, s,
e70cf415769ad0b3704e98b3f6da38e916ff7228jorton "LDAP cache: could not create shared memory segment");
e70cf415769ad0b3704e98b3f6da38e916ff7228jorton return DONE;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
024e70e05386a6367eb45d0d1cc406764520ff4cwrowe result = ap_global_mutex_create(&st->util_ldap_cache_lock, NULL,
43997561b2302d13dee973998e77743a3ddd2374trawick ldap_cache_mutex_type, NULL, s, p, 0);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes if (result != APR_SUCCESS) {
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes return result;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes /* merge config in all vhost */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes s_vhost = s->next;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes while (s_vhost) {
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe st_vhost = (util_ldap_state_t *)
e8f95a682820a599fe41b22977010636be5c2717jim ap_get_module_config(s_vhost->module_config,
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe &ldap_module);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes#if APR_HAS_SHARED_MEMORY
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes st_vhost->cache_shm = st->cache_shm;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes st_vhost->cache_rmm = st->cache_rmm;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes st_vhost->cache_file = st->cache_file;
b26e0fd306aeae8a51efc1a57d1e9f42dc37a3f1covener st_vhost->util_ldap_cache = st->util_ldap_cache;
e8f95a682820a599fe41b22977010636be5c2717jim ap_log_error(APLOG_MARK, APLOG_DEBUG, result, s,
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe "LDAP merging Shared Cache conf: shm=0x%pp rmm=0x%pp "
e8f95a682820a599fe41b22977010636be5c2717jim "for VHOST: %s", st->cache_shm, st->cache_rmm,
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe s_vhost->server_hostname);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes#endif
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes s_vhost = s_vhost->next;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes#if APR_HAS_SHARED_MEMORY
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes else {
e8f95a682820a599fe41b22977010636be5c2717jim ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe "LDAP cache: LDAPSharedCacheSize is zero, disabling "
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe "shared memory cache");
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes#endif
e8f95a682820a599fe41b22977010636be5c2717jim
e8f95a682820a599fe41b22977010636be5c2717jim /* log the LDAP SDK used
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes {
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes apr_ldap_err_t *result = NULL;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes apr_ldap_info(p, &(result));
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes if (result != NULL) {
e70cf415769ad0b3704e98b3f6da38e916ff7228jorton ap_log_error(APLOG_MARK, APLOG_INFO, 0, s, "%s", result->reason);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes apr_pool_cleanup_register(p, s, util_ldap_cleanup_module,
e8f95a682820a599fe41b22977010636be5c2717jim util_ldap_cleanup_module);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
54d22ed1c429b903b029bbd62621f11a9e286137minfrin /*
54d22ed1c429b903b029bbd62621f11a9e286137minfrin * Initialize SSL support, and log the result for the benefit of the admin.
54d22ed1c429b903b029bbd62621f11a9e286137minfrin *
54d22ed1c429b903b029bbd62621f11a9e286137minfrin * If SSL is not supported it is not necessarily an error, as the
54d22ed1c429b903b029bbd62621f11a9e286137minfrin * application may not want to use it.
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes */
e8f95a682820a599fe41b22977010636be5c2717jim rc = apr_ldap_ssl_init(p,
e8f95a682820a599fe41b22977010636be5c2717jim NULL,
e8f95a682820a599fe41b22977010636be5c2717jim 0,
d5cff0d8e871bf2528aadd8736fb50dc044b1e6dbnicholes &(result_err));
54d22ed1c429b903b029bbd62621f11a9e286137minfrin if (APR_SUCCESS == rc) {
ebe5305f8b22507374358f32b74d12fb50c05a25covener rc = apr_ldap_set_option(ptemp, NULL, APR_LDAP_OPT_TLS_CERT,
54d22ed1c429b903b029bbd62621f11a9e286137minfrin (void *)st->global_certs, &(result_err));
54d22ed1c429b903b029bbd62621f11a9e286137minfrin }
54d22ed1c429b903b029bbd62621f11a9e286137minfrin
54d22ed1c429b903b029bbd62621f11a9e286137minfrin if (APR_SUCCESS == rc) {
54d22ed1c429b903b029bbd62621f11a9e286137minfrin st->ssl_supported = 1;
e70cf415769ad0b3704e98b3f6da38e916ff7228jorton ap_log_error(APLOG_MARK, APLOG_INFO, 0, s,
e70cf415769ad0b3704e98b3f6da38e916ff7228jorton "LDAP: SSL support available" );
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes else {
54d22ed1c429b903b029bbd62621f11a9e286137minfrin st->ssl_supported = 0;
e8f95a682820a599fe41b22977010636be5c2717jim ap_log_error(APLOG_MARK, APLOG_INFO, 0, s,
e70cf415769ad0b3704e98b3f6da38e916ff7228jorton "LDAP: SSL support unavailable%s%s",
e70cf415769ad0b3704e98b3f6da38e916ff7228jorton result_err ? ": " : "",
e70cf415769ad0b3704e98b3f6da38e916ff7228jorton result_err ? result_err->reason : "");
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
0894cd17fe3f614bf01dbf84f1414756bd5a34c3bnicholes
f7edd56768a46a01ae8b43c712c9eeef40e37f59bnicholes /* Initialize the rebind callback's cross reference list. */
f7edd56768a46a01ae8b43c712c9eeef40e37f59bnicholes apr_ldap_rebind_init (p);
f7edd56768a46a01ae8b43c712c9eeef40e37f59bnicholes
57e892abdf632bb9224c6ae6a715d863242a00f3fuankg#ifdef AP_LDAP_OPT_DEBUG
0f60998368b493f90120180a93fc2e1e74490872covener if (st->debug_level > 0) {
0f60998368b493f90120180a93fc2e1e74490872covener result = ldap_set_option(NULL, AP_LDAP_OPT_DEBUG, &st->debug_level);
0f60998368b493f90120180a93fc2e1e74490872covener if (result != LDAP_SUCCESS) {
0f60998368b493f90120180a93fc2e1e74490872covener ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
0f60998368b493f90120180a93fc2e1e74490872covener "LDAP: Could not set the LDAP library debug level to %d:(%d) %s",
0f60998368b493f90120180a93fc2e1e74490872covener st->debug_level, result, ldap_err2string(result));
0f60998368b493f90120180a93fc2e1e74490872covener }
0f60998368b493f90120180a93fc2e1e74490872covener }
57e892abdf632bb9224c6ae6a715d863242a00f3fuankg#endif
0f60998368b493f90120180a93fc2e1e74490872covener
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes return(OK);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes}
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholesstatic void util_ldap_child_init(apr_pool_t *p, server_rec *s)
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes{
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes apr_status_t sts;
e8f95a682820a599fe41b22977010636be5c2717jim util_ldap_state_t *st = ap_get_module_config(s->module_config,
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe &ldap_module);
d266c3777146d36a4c23c17aad6f153aebea1bf4jorton
d266c3777146d36a4c23c17aad6f153aebea1bf4jorton if (!st->util_ldap_cache_lock) return;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
e8f95a682820a599fe41b22977010636be5c2717jim sts = apr_global_mutex_child_init(&st->util_ldap_cache_lock,
11f2c481e1d57bedb3f758565307501e9a2730ddtrawick apr_global_mutex_lockfile(st->util_ldap_cache_lock), p);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes if (sts != APR_SUCCESS) {
af6d8b02b2fd4ea9a0f6bfb95940d6075030e9a7minfrin ap_log_error(APLOG_MARK, APLOG_CRIT, sts, s,
9efd5708f6f0ab1992f6a5233eb622ad5e4eae18sf "Failed to initialise global mutex %s in child process",
9efd5708f6f0ab1992f6a5233eb622ad5e4eae18sf ldap_cache_mutex_type);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes}
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
e025b9c2dbc3e2873142a775c37336a75ead222bjortonstatic const command_rec util_ldap_cmds[] = {
e8f95a682820a599fe41b22977010636be5c2717jim AP_INIT_TAKE1("LDAPSharedCacheSize", util_ldap_set_cache_bytes,
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe NULL, RSRC_CONF,
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe "Set the size of the shared memory cache (in bytes). Use "
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe "0 to disable the shared memory cache. (default: 100000)"),
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe
e8f95a682820a599fe41b22977010636be5c2717jim AP_INIT_TAKE1("LDAPSharedCacheFile", util_ldap_set_cache_file,
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe NULL, RSRC_CONF,
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe "Set the file name for the shared memory cache."),
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe
e8f95a682820a599fe41b22977010636be5c2717jim AP_INIT_TAKE1("LDAPCacheEntries", util_ldap_set_cache_entries,
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe NULL, RSRC_CONF,
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)"),
023ab66b169a239c82d6c36410ab43fe63561d11covener
e8f95a682820a599fe41b22977010636be5c2717jim AP_INIT_TAKE1("LDAPCacheTTL", util_ldap_set_cache_ttl,
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe NULL, RSRC_CONF,
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)"),
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe
e8f95a682820a599fe41b22977010636be5c2717jim AP_INIT_TAKE1("LDAPOpCacheEntries", util_ldap_set_opcache_entries,
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe NULL, RSRC_CONF,
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)"),
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe
e8f95a682820a599fe41b22977010636be5c2717jim AP_INIT_TAKE1("LDAPOpCacheTTL", util_ldap_set_opcache_ttl,
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe NULL, RSRC_CONF,
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
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe AP_INIT_TAKE23("LDAPTrustedGlobalCert", util_ldap_set_trusted_global_cert,
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe NULL, RSRC_CONF,
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
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe AP_INIT_TAKE23("LDAPTrustedClientCert", util_ldap_set_trusted_client_cert,
ae1981fc94adf2b231e2d0e15d2f895b2138c969covener NULL, OR_AUTHCFG,
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."),
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe
e8f95a682820a599fe41b22977010636be5c2717jim AP_INIT_TAKE1("LDAPTrustedMode", util_ldap_set_trusted_mode,
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe NULL, RSRC_CONF,
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe "Specify the type of security that should be applied to "
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe "an LDAP connection. One of; NONE, SSL or STARTTLS."),
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe
e8f95a682820a599fe41b22977010636be5c2717jim AP_INIT_FLAG("LDAPVerifyServerCert", util_ldap_set_verify_srv_cert,
141e1368614dc7564e1627671361b01b4869b491bnicholes NULL, RSRC_CONF,
8445dae5cc606ba8ba04efc341cc1e081d95920drpluem "Set to 'ON' requires that the server certificate be verified"
8445dae5cc606ba8ba04efc341cc1e081d95920drpluem " before a secure LDAP connection can be establish. Default"
8445dae5cc606ba8ba04efc341cc1e081d95920drpluem " 'ON'"),
141e1368614dc7564e1627671361b01b4869b491bnicholes
e8f95a682820a599fe41b22977010636be5c2717jim AP_INIT_TAKE1("LDAPConnectionTimeout", util_ldap_set_connection_timeout,
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe NULL, RSRC_CONF,
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe "Specify the LDAP socket connection timeout in seconds "
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe "(default: 10)"),
0894cd17fe3f614bf01dbf84f1414756bd5a34c3bnicholes
9ad7b260be233be7d7b5576979825cac72e15498rederpj AP_INIT_FLAG("LDAPReferrals", util_ldap_set_chase_referrals,
9ad7b260be233be7d7b5576979825cac72e15498rederpj NULL, OR_AUTHCFG,
9ad7b260be233be7d7b5576979825cac72e15498rederpj "Choose whether referrals are chased ['ON'|'OFF']. Default 'ON'"),
9ad7b260be233be7d7b5576979825cac72e15498rederpj
9ad7b260be233be7d7b5576979825cac72e15498rederpj AP_INIT_TAKE1("LDAPReferralHopLimit", util_ldap_set_referral_hop_limit,
9ad7b260be233be7d7b5576979825cac72e15498rederpj NULL, OR_AUTHCFG,
9ad7b260be233be7d7b5576979825cac72e15498rederpj "Limit the number of referral hops that LDAP can follow. "
87587593f1a53030e840acc0dec6cc881022ea40covener "(Integer value, Consult LDAP SDK documentation for applicability and defaults"),
9ad7b260be233be7d7b5576979825cac72e15498rederpj
0f60998368b493f90120180a93fc2e1e74490872covener AP_INIT_TAKE1("LDAPLibraryDebug", util_ldap_set_debug_level,
0f60998368b493f90120180a93fc2e1e74490872covener NULL, RSRC_CONF,
0f60998368b493f90120180a93fc2e1e74490872covener "Enable debugging in LDAP SDK (Default: off, values: SDK specific"),
0f60998368b493f90120180a93fc2e1e74490872covener
4be9c459920a7c1cfe62d654327dae5c4bb6b284sf AP_INIT_TAKE1("LDAPTimeout", util_ldap_set_op_timeout,
4be9c459920a7c1cfe62d654327dae5c4bb6b284sf NULL, RSRC_CONF,
4be9c459920a7c1cfe62d654327dae5c4bb6b284sf "Specify the LDAP bind/search timeout in seconds "
4be9c459920a7c1cfe62d654327dae5c4bb6b284sf "(0 = no limit). Default: 60"),
4be9c459920a7c1cfe62d654327dae5c4bb6b284sf
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes {NULL}
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes};
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholesstatic void util_ldap_register_hooks(apr_pool_t *p)
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes{
f43b67c5a9d29b572eac916f8335cedc80c908bebnicholes APR_REGISTER_OPTIONAL_FN(uldap_connection_open);
f43b67c5a9d29b572eac916f8335cedc80c908bebnicholes APR_REGISTER_OPTIONAL_FN(uldap_connection_close);
f43b67c5a9d29b572eac916f8335cedc80c908bebnicholes APR_REGISTER_OPTIONAL_FN(uldap_connection_unbind);
f43b67c5a9d29b572eac916f8335cedc80c908bebnicholes APR_REGISTER_OPTIONAL_FN(uldap_connection_cleanup);
f43b67c5a9d29b572eac916f8335cedc80c908bebnicholes APR_REGISTER_OPTIONAL_FN(uldap_connection_find);
f43b67c5a9d29b572eac916f8335cedc80c908bebnicholes APR_REGISTER_OPTIONAL_FN(uldap_cache_comparedn);
f43b67c5a9d29b572eac916f8335cedc80c908bebnicholes APR_REGISTER_OPTIONAL_FN(uldap_cache_compare);
f43b67c5a9d29b572eac916f8335cedc80c908bebnicholes APR_REGISTER_OPTIONAL_FN(uldap_cache_checkuserid);
f43b67c5a9d29b572eac916f8335cedc80c908bebnicholes APR_REGISTER_OPTIONAL_FN(uldap_cache_getuserdn);
f43b67c5a9d29b572eac916f8335cedc80c908bebnicholes APR_REGISTER_OPTIONAL_FN(uldap_ssl_supported);
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj APR_REGISTER_OPTIONAL_FN(uldap_cache_check_subgroups);
f43b67c5a9d29b572eac916f8335cedc80c908bebnicholes
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);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes}
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
36ef8f77bffe75d1aa327882be1b5bdbe2ff567asfAP_DECLARE_MODULE(ldap) = {
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes STANDARD20_MODULE_STUFF,
9ad7b260be233be7d7b5576979825cac72e15498rederpj util_ldap_create_dir_config, /* create dir config */
f05787953018140838ad51456c86c965d6a86267jim NULL, /* merge dir config */
f05787953018140838ad51456c86c965d6a86267jim util_ldap_create_config, /* create server config */
f05787953018140838ad51456c86c965d6a86267jim util_ldap_merge_config, /* merge server config */
f05787953018140838ad51456c86c965d6a86267jim util_ldap_cmds, /* command table */
f05787953018140838ad51456c86c965d6a86267jim util_ldap_register_hooks, /* set up request processing hooks */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes};