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
ab86c68ce36c715e93f403dde41d0b9c1522c8b0sf#if !APR_HAS_LDAP
ab86c68ce36c715e93f403dde41d0b9c1522c8b0sf#error mod_ldap requires APR-util to have LDAP support built in
cd3bbd6d2df78d6c75e5d159a81ef8bdd5f70df9trawick#endif
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
ab86c68ce36c715e93f403dde41d0b9c1522c8b0sf/* Default define for ldap functions that need a SIZELIMIT but
ab86c68ce36c715e93f403dde41d0b9c1522c8b0sf * do not have the define
5bfaaf573bacb45c1cf290ce85ecc676587e8a64jim * XXX This should be removed once a supporting #define is
ab86c68ce36c715e93f403dde41d0b9c1522c8b0sf * released through APR-Util.
ab86c68ce36c715e93f403dde41d0b9c1522c8b0sf */
ab86c68ce36c715e93f403dde41d0b9c1522c8b0sf#ifndef APR_LDAP_SIZELIMIT
ab86c68ce36c715e93f403dde41d0b9c1522c8b0sf#define APR_LDAP_SIZELIMIT -1
ab86c68ce36c715e93f403dde41d0b9c1522c8b0sf#endif
bede2929837dfd23863ad4b39199c63126566d61jorton
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
5bfaaf573bacb45c1cf290ce85ecc676587e8a64jim#define AP_LDAP_HOPLIMIT_UNSET -1
60284a9f9158baa60cc8ab4a69066404b1dcae7acovener#define AP_LDAP_CHASEREFERRALS_SDKDEFAULT -1
87587593f1a53030e840acc0dec6cc881022ea40covener#define AP_LDAP_CHASEREFERRALS_OFF 0
87587593f1a53030e840acc0dec6cc881022ea40covener#define AP_LDAP_CHASEREFERRALS_ON 1
87587593f1a53030e840acc0dec6cc881022ea40covener
a81c0c1ae464b2063a21b45f80c9da8d89bb840ecovener#define AP_LDAP_CONNPOOL_DEFAULT -1
a81c0c1ae464b2063a21b45f80c9da8d89bb840ecovener#define AP_LDAP_CONNPOOL_INFINITE -2
a81c0c1ae464b2063a21b45f80c9da8d89bb840ecovener
97cd2f98ad4abe68aaaba96b5bfc9ebf7109a2c1covener#if !defined(LDAP_OPT_NETWORK_TIMEOUT) && defined(LDAP_OPT_CONNECT_TIMEOUT)
97cd2f98ad4abe68aaaba96b5bfc9ebf7109a2c1covener#define LDAP_OPT_NETWORK_TIMEOUT LDAP_OPT_CONNECT_TIMEOUT
97cd2f98ad4abe68aaaba96b5bfc9ebf7109a2c1covener#endif
97cd2f98ad4abe68aaaba96b5bfc9ebf7109a2c1covener
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholesmodule AP_MODULE_DECLARE_DATA ldap_module;
43997561b2302d13dee973998e77743a3ddd2374trawickstatic const char *ldap_cache_mutex_type = "ldap-cache";
fa123db15501821e36e513afa78e839775ad2800covenerstatic apr_status_t uldap_connection_unbind(void *param);
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
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{
95b6fe1346805e1731e6e97c15d569c73be22cf7minfrin util_ldap_state_t *st;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes r->allowed |= (1 << M_GET);
95b6fe1346805e1731e6e97c15d569c73be22cf7minfrin if (r->method_number != M_GET) {
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes return DECLINED;
95b6fe1346805e1731e6e97c15d569c73be22cf7minfrin }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes if (strcmp(r->handler, "ldap-status")) {
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes return DECLINED;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
95b6fe1346805e1731e6e97c15d569c73be22cf7minfrin st = (util_ldap_state_t *) ap_get_module_config(r->server->module_config,
95b6fe1346805e1731e6e97c15d569c73be22cf7minfrin &ldap_module);
95b6fe1346805e1731e6e97c15d569c73be22cf7minfrin
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
fa123db15501821e36e513afa78e839775ad2800covener /* We leave bound LDAP connections floating around in our pool,
fa123db15501821e36e513afa78e839775ad2800covener * but always check/fix the binddn/bindpw when we take them out
fa123db15501821e36e513afa78e839775ad2800covener * of the pool
fa123db15501821e36e513afa78e839775ad2800covener */
5bfaaf573bacb45c1cf290ce85ecc676587e8a64jim if (!ldc->keep) {
fa123db15501821e36e513afa78e839775ad2800covener uldap_connection_unbind(ldc);
307219eca940aa30b873bfd68a44484dd3d3fa88covener ldc->r = NULL;
4e9c24785b525d2956e6e381015c0f2bd0a72f4bcovener }
5bfaaf573bacb45c1cf290ce85ecc676587e8a64jim else {
4e9c24785b525d2956e6e381015c0f2bd0a72f4bcovener /* mark our connection as available for reuse */
a81c0c1ae464b2063a21b45f80c9da8d89bb840ecovener ldc->freed = apr_time_now();
307219eca940aa30b873bfd68a44484dd3d3fa88covener ldc->r = NULL;
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) {
307219eca940aa30b873bfd68a44484dd3d3fa88covener if (ldc->r) {
307219eca940aa30b873bfd68a44484dd3d3fa88covener ap_log_rerror(APLOG_MARK, APLOG_TRACE5, 0, ldc->r, "LDC %pp unbind", ldc);
307219eca940aa30b873bfd68a44484dd3d3fa88covener }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes ldap_unbind_s(ldc->ldap);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes ldc->ldap = NULL;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes ldc->bound = 0;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
fa123db15501821e36e513afa78e839775ad2800covener /* forget the rebind info for this conn */
cceddc0b6c0fdaed0c73abda39975bb1d388243acovener if (ldc->ChaseReferrals == AP_LDAP_CHASEREFERRALS_ON) {
ab86c68ce36c715e93f403dde41d0b9c1522c8b0sf apr_ldap_rebind_remove(ldc->ldap);
fa123db15501821e36e513afa78e839775ad2800covener apr_pool_clear(ldc->rebind_pool);
cceddc0b6c0fdaed0c73abda39975bb1d388243acovener }
f2be127030aa4190033084f0a6add531c9bc41desf }
4e9c24785b525d2956e6e381015c0f2bd0a72f4bcovener
4e9c24785b525d2956e6e381015c0f2bd0a72f4bcovener return APR_SUCCESS;
4e9c24785b525d2956e6e381015c0f2bd0a72f4bcovener}
4e9c24785b525d2956e6e381015c0f2bd0a72f4bcovener
60215f303c7e1ce8b6d272acb5bfa5b3d99dfd34covener/* not presently used, not part of the API */
60215f303c7e1ce8b6d272acb5bfa5b3d99dfd34covener#if 0
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 */
5bfaaf573bacb45c1cf290ce85ecc676587e8a64jimstatic 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) {
5bfaaf573bacb45c1cf290ce85ecc676587e8a64jim prev->next = l->next;
4e9c24785b525d2956e6e381015c0f2bd0a72f4bcovener }
5bfaaf573bacb45c1cf290ce85ecc676587e8a64jim else {
4e9c24785b525d2956e6e381015c0f2bd0a72f4bcovener st->connections = l->next;
4e9c24785b525d2956e6e381015c0f2bd0a72f4bcovener }
4e9c24785b525d2956e6e381015c0f2bd0a72f4bcovener break;
4e9c24785b525d2956e6e381015c0f2bd0a72f4bcovener }
4e9c24785b525d2956e6e381015c0f2bd0a72f4bcovener prev = l;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
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
5bfaaf573bacb45c1cf290ce85ecc676587e8a64jim apr_pool_destroy(ldc->pool);
5bfaaf573bacb45c1cf290ce85ecc676587e8a64jim
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes return APR_SUCCESS;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes}
60215f303c7e1ce8b6d272acb5bfa5b3d99dfd34covener#endif
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;
ab86c68ce36c715e93f403dde41d0b9c1522c8b0sf apr_ldap_err_t *result = NULL;
465bb68501690d7a47bfd2a6129580047d76d8f1rederpj#ifdef LDAP_OPT_NETWORK_TIMEOUT
5bfaaf573bacb45c1cf290ce85ecc676587e8a64jim struct timeval connectionTimeout = {0};
465bb68501690d7a47bfd2a6129580047d76d8f1rederpj#endif
e8f95a682820a599fe41b22977010636be5c2717jim util_ldap_state_t *st =
3dfeb02cfb853d8717ca0cc259b59fea610173f5bnicholes (util_ldap_state_t *)ap_get_module_config(r->server->module_config,
3dfeb02cfb853d8717ca0cc259b59fea610173f5bnicholes &ldap_module);
55e2e59e5910072e51c870afc68b0907f41a28e0sf int have_client_certs = !apr_is_empty_array(ldc->client_certs);
55e2e59e5910072e51c870afc68b0907f41a28e0sf#if !APR_HAS_SOLARIS_LDAPSDK
55e2e59e5910072e51c870afc68b0907f41a28e0sf /*
55e2e59e5910072e51c870afc68b0907f41a28e0sf * Normally we enable SSL/TLS with apr_ldap_set_option(), except
55e2e59e5910072e51c870afc68b0907f41a28e0sf * with Solaris LDAP, where this is broken.
55e2e59e5910072e51c870afc68b0907f41a28e0sf */
55e2e59e5910072e51c870afc68b0907f41a28e0sf int secure = APR_LDAP_NONE;
55e2e59e5910072e51c870afc68b0907f41a28e0sf#else
55e2e59e5910072e51c870afc68b0907f41a28e0sf /*
55e2e59e5910072e51c870afc68b0907f41a28e0sf * With Solaris LDAP, we enable TSL via the secure argument
55e2e59e5910072e51c870afc68b0907f41a28e0sf * to apr_ldap_init(). This requires a fix from apr-util >= 1.4.0.
55e2e59e5910072e51c870afc68b0907f41a28e0sf *
55e2e59e5910072e51c870afc68b0907f41a28e0sf * Just in case client certificates ever get supported, we
55e2e59e5910072e51c870afc68b0907f41a28e0sf * handle those as with the other LDAP SDKs.
55e2e59e5910072e51c870afc68b0907f41a28e0sf */
55e2e59e5910072e51c870afc68b0907f41a28e0sf int secure = have_client_certs ? APR_LDAP_NONE : ldc->secure;
55e2e59e5910072e51c870afc68b0907f41a28e0sf#endif
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 */
ab86c68ce36c715e93f403dde41d0b9c1522c8b0sf apr_ldap_init(r->pool, &(ldc->ldap),
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes ldc->host,
ab86c68ce36c715e93f403dde41d0b9c1522c8b0sf APR_LDAP_SSL == ldc->secure ? LDAPS_PORT : LDAP_PORT,
55e2e59e5910072e51c870afc68b0907f41a28e0sf secure, &(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;
02fd88c85a9850109753b87612955ad372de1575sf ldc->bound = 0;
02fd88c85a9850109753b87612955ad372de1575sf return result->rc;
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
307219eca940aa30b873bfd68a44484dd3d3fa88covener ap_log_rerror(APLOG_MARK, APLOG_TRACE5, 0, r, "LDC %pp init", ldc);
307219eca940aa30b873bfd68a44484dd3d3fa88covener
707f6d077f73cc948deead8df5b40ea42c1eaa78covener if (ldc->ChaseReferrals == AP_LDAP_CHASEREFERRALS_ON) {
707f6d077f73cc948deead8df5b40ea42c1eaa78covener /* Now that we have an ldap struct, add it to the referral list for rebinds. */
ab86c68ce36c715e93f403dde41d0b9c1522c8b0sf rc = apr_ldap_rebind_add(ldc->rebind_pool, ldc->ldap, ldc->binddn, ldc->bindpw);
707f6d077f73cc948deead8df5b40ea42c1eaa78covener if (rc != APR_SUCCESS) {
185aa71728867671e105178b4c66fbc22b65ae26sf ap_log_error(APLOG_MARK, APLOG_ERR, rc, r->server, APLOGNO(01277)
707f6d077f73cc948deead8df5b40ea42c1eaa78covener "LDAP: Unable to add rebind cross reference entry. Out of memory?");
707f6d077f73cc948deead8df5b40ea42c1eaa78covener uldap_connection_unbind(ldc);
707f6d077f73cc948deead8df5b40ea42c1eaa78covener ldc->reason = "LDAP: Unable to add rebind cross reference entry.";
707f6d077f73cc948deead8df5b40ea42c1eaa78covener return(rc);
707f6d077f73cc948deead8df5b40ea42c1eaa78covener }
9ad7b260be233be7d7b5576979825cac72e15498rederpj }
9ad7b260be233be7d7b5576979825cac72e15498rederpj
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes /* always default to LDAP V3 */
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes ldap_set_option(ldc->ldap, LDAP_OPT_PROTOCOL_VERSION, &version);
54d22ed1c429b903b029bbd62621f11a9e286137minfrin
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes /* set client certificates */
55e2e59e5910072e51c870afc68b0907f41a28e0sf if (have_client_certs) {
ab86c68ce36c715e93f403dde41d0b9c1522c8b0sf 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 */
55e2e59e5910072e51c870afc68b0907f41a28e0sf if (APR_LDAP_NONE != ldc->secure
55e2e59e5910072e51c870afc68b0907f41a28e0sf#if APR_HAS_SOLARIS_LDAPSDK
55e2e59e5910072e51c870afc68b0907f41a28e0sf /* See comments near apr_ldap_init() above */
55e2e59e5910072e51c870afc68b0907f41a28e0sf && have_client_certs
55e2e59e5910072e51c870afc68b0907f41a28e0sf#endif
55e2e59e5910072e51c870afc68b0907f41a28e0sf ) {
ab86c68ce36c715e93f403dde41d0b9c1522c8b0sf apr_ldap_set_option(r->pool, ldc->ldap,
ab86c68ce36c715e93f403dde41d0b9c1522c8b0sf 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
60284a9f9158baa60cc8ab4a69066404b1dcae7acovener if (ldc->ChaseReferrals != AP_LDAP_CHASEREFERRALS_SDKDEFAULT) {
707f6d077f73cc948deead8df5b40ea42c1eaa78covener /* Set options for rebind and referrals. */
5f3e4e06f8e23597d2f95e2c2cff1116c522488fcovener ap_log_error(APLOG_MARK, APLOG_TRACE4, 0, r->server, APLOGNO(01278)
707f6d077f73cc948deead8df5b40ea42c1eaa78covener "LDAP: Setting referrals to %s.",
707f6d077f73cc948deead8df5b40ea42c1eaa78covener ((ldc->ChaseReferrals == AP_LDAP_CHASEREFERRALS_ON) ? "On" : "Off"));
ab86c68ce36c715e93f403dde41d0b9c1522c8b0sf apr_ldap_set_option(r->pool, ldc->ldap,
ab86c68ce36c715e93f403dde41d0b9c1522c8b0sf APR_LDAP_OPT_REFERRALS,
707f6d077f73cc948deead8df5b40ea42c1eaa78covener (void *)((ldc->ChaseReferrals == AP_LDAP_CHASEREFERRALS_ON) ?
707f6d077f73cc948deead8df5b40ea42c1eaa78covener LDAP_OPT_ON : LDAP_OPT_OFF),
707f6d077f73cc948deead8df5b40ea42c1eaa78covener &(result));
9ad7b260be233be7d7b5576979825cac72e15498rederpj if (result->rc != LDAP_SUCCESS) {
185aa71728867671e105178b4c66fbc22b65ae26sf ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, APLOGNO(01279)
707f6d077f73cc948deead8df5b40ea42c1eaa78covener "Unable to set LDAP_OPT_REFERRALS option to %s: %d.",
707f6d077f73cc948deead8df5b40ea42c1eaa78covener ((ldc->ChaseReferrals == AP_LDAP_CHASEREFERRALS_ON) ? "On" : "Off"),
707f6d077f73cc948deead8df5b40ea42c1eaa78covener result->rc);
707f6d077f73cc948deead8df5b40ea42c1eaa78covener result->reason = "Unable to set LDAP_OPT_REFERRALS.";
707f6d077f73cc948deead8df5b40ea42c1eaa78covener ldc->reason = result->reason;
707f6d077f73cc948deead8df5b40ea42c1eaa78covener uldap_connection_unbind(ldc);
707f6d077f73cc948deead8df5b40ea42c1eaa78covener return(result->rc);
707f6d077f73cc948deead8df5b40ea42c1eaa78covener }
60284a9f9158baa60cc8ab4a69066404b1dcae7acovener }
707f6d077f73cc948deead8df5b40ea42c1eaa78covener
60284a9f9158baa60cc8ab4a69066404b1dcae7acovener if (ldc->ChaseReferrals == AP_LDAP_CHASEREFERRALS_ON) {
707f6d077f73cc948deead8df5b40ea42c1eaa78covener if ((ldc->ReferralHopLimit != AP_LDAP_HOPLIMIT_UNSET) && ldc->ChaseReferrals == AP_LDAP_CHASEREFERRALS_ON) {
707f6d077f73cc948deead8df5b40ea42c1eaa78covener /* Referral hop limit - only if referrals are enabled and a hop limit is explicitly requested */
185aa71728867671e105178b4c66fbc22b65ae26sf ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, APLOGNO(01280)
707f6d077f73cc948deead8df5b40ea42c1eaa78covener "Setting referral hop limit to %d.",
707f6d077f73cc948deead8df5b40ea42c1eaa78covener ldc->ReferralHopLimit);
ab86c68ce36c715e93f403dde41d0b9c1522c8b0sf apr_ldap_set_option(r->pool, ldc->ldap,
ab86c68ce36c715e93f403dde41d0b9c1522c8b0sf APR_LDAP_OPT_REFHOPLIMIT,
707f6d077f73cc948deead8df5b40ea42c1eaa78covener (void *)&ldc->ReferralHopLimit,
707f6d077f73cc948deead8df5b40ea42c1eaa78covener &(result));
707f6d077f73cc948deead8df5b40ea42c1eaa78covener if (result->rc != LDAP_SUCCESS) {
185aa71728867671e105178b4c66fbc22b65ae26sf ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, APLOGNO(01281)
707f6d077f73cc948deead8df5b40ea42c1eaa78covener "Unable to set LDAP_OPT_REFHOPLIMIT option to %d: %d.",
707f6d077f73cc948deead8df5b40ea42c1eaa78covener ldc->ReferralHopLimit,
707f6d077f73cc948deead8df5b40ea42c1eaa78covener result->rc);
707f6d077f73cc948deead8df5b40ea42c1eaa78covener result->reason = "Unable to set LDAP_OPT_REFHOPLIMIT.";
707f6d077f73cc948deead8df5b40ea42c1eaa78covener ldc->reason = result->reason;
707f6d077f73cc948deead8df5b40ea42c1eaa78covener uldap_connection_unbind(ldc);
707f6d077f73cc948deead8df5b40ea42c1eaa78covener return(result->rc);
707f6d077f73cc948deead8df5b40ea42c1eaa78covener }
9ad7b260be233be7d7b5576979825cac72e15498rederpj }
9ad7b260be233be7d7b5576979825cac72e15498rederpj }
9ad7b260be233be7d7b5576979825cac72e15498rederpj
ab86c68ce36c715e93f403dde41d0b9c1522c8b0sf/*XXX All of the #ifdef's need to be removed once apr-util 1.2 is released */
ab86c68ce36c715e93f403dde41d0b9c1522c8b0sf#ifdef APR_LDAP_OPT_VERIFY_CERT
ab86c68ce36c715e93f403dde41d0b9c1522c8b0sf apr_ldap_set_option(r->pool, ldc->ldap, APR_LDAP_OPT_VERIFY_CERT,
8445dae5cc606ba8ba04efc341cc1e081d95920drpluem &(st->verify_svr_cert), &(result));
ab86c68ce36c715e93f403dde41d0b9c1522c8b0sf#else
ab86c68ce36c715e93f403dde41d0b9c1522c8b0sf#if defined(LDAPSSL_VERIFY_SERVER)
ab86c68ce36c715e93f403dde41d0b9c1522c8b0sf if (st->verify_svr_cert) {
ab86c68ce36c715e93f403dde41d0b9c1522c8b0sf result->rc = ldapssl_set_verify_mode(LDAPSSL_VERIFY_SERVER);
ab86c68ce36c715e93f403dde41d0b9c1522c8b0sf }
ab86c68ce36c715e93f403dde41d0b9c1522c8b0sf else {
ab86c68ce36c715e93f403dde41d0b9c1522c8b0sf result->rc = ldapssl_set_verify_mode(LDAPSSL_VERIFY_NONE);
ab86c68ce36c715e93f403dde41d0b9c1522c8b0sf }
ab86c68ce36c715e93f403dde41d0b9c1522c8b0sf#elif defined(LDAP_OPT_X_TLS_REQUIRE_CERT)
ab86c68ce36c715e93f403dde41d0b9c1522c8b0sf /* This is not a per-connection setting so just pass NULL for the
ab86c68ce36c715e93f403dde41d0b9c1522c8b0sf Ldap connection handle */
ab86c68ce36c715e93f403dde41d0b9c1522c8b0sf if (st->verify_svr_cert) {
ab86c68ce36c715e93f403dde41d0b9c1522c8b0sf int i = LDAP_OPT_X_TLS_DEMAND;
ab86c68ce36c715e93f403dde41d0b9c1522c8b0sf result->rc = ldap_set_option(NULL, LDAP_OPT_X_TLS_REQUIRE_CERT, &i);
ab86c68ce36c715e93f403dde41d0b9c1522c8b0sf }
ab86c68ce36c715e93f403dde41d0b9c1522c8b0sf else {
ab86c68ce36c715e93f403dde41d0b9c1522c8b0sf int i = LDAP_OPT_X_TLS_NEVER;
ab86c68ce36c715e93f403dde41d0b9c1522c8b0sf result->rc = ldap_set_option(NULL, LDAP_OPT_X_TLS_REQUIRE_CERT, &i);
ab86c68ce36c715e93f403dde41d0b9c1522c8b0sf }
ab86c68ce36c715e93f403dde41d0b9c1522c8b0sf#endif
ab86c68ce36c715e93f403dde41d0b9c1522c8b0sf#endif
141e1368614dc7564e1627671361b01b4869b491bnicholes
3dfeb02cfb853d8717ca0cc259b59fea610173f5bnicholes#ifdef LDAP_OPT_NETWORK_TIMEOUT
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes if (st->connectionTimeout > 0) {
4be9c459920a7c1cfe62d654327dae5c4bb6b284sf connectionTimeout.tv_sec = st->connectionTimeout;
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes }
e8f95a682820a599fe41b22977010636be5c2717jim
1ae7a5fbce5d4f65f3da355792258fe5dbc4ef55covener if (connectionTimeout.tv_sec > 0) {
ab86c68ce36c715e93f403dde41d0b9c1522c8b0sf rc = apr_ldap_set_option(r->pool, ldc->ldap, LDAP_OPT_NETWORK_TIMEOUT,
4be9c459920a7c1cfe62d654327dae5c4bb6b284sf (void *)&connectionTimeout, &(result));
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes if (APR_SUCCESS != rc) {
185aa71728867671e105178b4c66fbc22b65ae26sf ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server, APLOGNO(01282)
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) {
ab86c68ce36c715e93f403dde41d0b9c1522c8b0sf rc = apr_ldap_set_option(r->pool, ldc->ldap, LDAP_OPT_TIMEOUT,
4be9c459920a7c1cfe62d654327dae5c4bb6b284sf st->opTimeout, &(result));
4be9c459920a7c1cfe62d654327dae5c4bb6b284sf if (APR_SUCCESS != rc) {
185aa71728867671e105178b4c66fbc22b65ae26sf ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server, APLOGNO(01283)
4be9c459920a7c1cfe62d654327dae5c4bb6b284sf "LDAP: Could not set LDAP_OPT_TIMEOUT");
4be9c459920a7c1cfe62d654327dae5c4bb6b284sf }
4be9c459920a7c1cfe62d654327dae5c4bb6b284sf }
4be9c459920a7c1cfe62d654327dae5c4bb6b284sf#endif
4be9c459920a7c1cfe62d654327dae5c4bb6b284sf
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes return(rc);
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes}
e8f95a682820a599fe41b22977010636be5c2717jim
5bfaaf573bacb45c1cf290ce85ecc676587e8a64jimstatic int uldap_ld_errno(util_ldap_connection_t *ldc)
5bfaaf573bacb45c1cf290ce85ecc676587e8a64jim{
96ebb616bbf4ac2a422cc5d9770c9ad07ccecdc0covener int ldaprc;
96ebb616bbf4ac2a422cc5d9770c9ad07ccecdc0covener#ifdef LDAP_OPT_ERROR_NUMBER
96ebb616bbf4ac2a422cc5d9770c9ad07ccecdc0covener if (LDAP_SUCCESS == ldap_get_option(ldc->ldap, LDAP_OPT_ERROR_NUMBER, &ldaprc)) return ldaprc;
96ebb616bbf4ac2a422cc5d9770c9ad07ccecdc0covener#endif
96ebb616bbf4ac2a422cc5d9770c9ad07ccecdc0covener#ifdef LDAP_OPT_RESULT_CODE
96ebb616bbf4ac2a422cc5d9770c9ad07ccecdc0covener if (LDAP_SUCCESS == ldap_get_option(ldc->ldap, LDAP_OPT_RESULT_CODE, &ldaprc)) return ldaprc;
96ebb616bbf4ac2a422cc5d9770c9ad07ccecdc0covener#endif
96ebb616bbf4ac2a422cc5d9770c9ad07ccecdc0covener return LDAP_OTHER;
96ebb616bbf4ac2a422cc5d9770c9ad07ccecdc0covener}
783874b86bfe13d7a4fe0922f344a3779cdccea3covener
7dbf29be626018bc389ef94c1846aeac4b72633bsf/*
7dbf29be626018bc389ef94c1846aeac4b72633bsf * Replacement function for ldap_simple_bind_s() with a timeout.
5bfaaf573bacb45c1cf290ce85ecc676587e8a64jim * 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";
783874b86bfe13d7a4fe0922f344a3779cdccea3covener return uldap_ld_errno(ldc);
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 */
783874b86bfe13d7a4fe0922f344a3779cdccea3covener return uldap_ld_errno(ldc);
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";
783874b86bfe13d7a4fe0922f344a3779cdccea3covener return uldap_ld_errno(ldc);
7dbf29be626018bc389ef94c1846aeac4b72633bsf }
307219eca940aa30b873bfd68a44484dd3d3fa88covener else {
87a26948305eab2bab8a4fb3f2a21f6725055790covener ldc->last_backend_conn = ldc->r->request_time;
307219eca940aa30b873bfd68a44484dd3d3fa88covener ap_log_rerror(APLOG_MARK, APLOG_TRACE5, 0, ldc->r, "LDC %pp bind", ldc);
307219eca940aa30b873bfd68a44484dd3d3fa88covener }
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 */
307219eca940aa30b873bfd68a44484dd3d3fa88covener if (ldc->bound && !ldc->must_rebind)
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
60d81cab99dccfbb0c8d378cf6aa7338be0fdb74covener /* loop trying to bind up to st->retries times if LDAP_SERVER_DOWN or LDAP_TIMEOUT
60d81cab99dccfbb0c8d378cf6aa7338be0fdb74covener * are returned. Close the connection before the first retry, and then on every
60d81cab99dccfbb0c8d378cf6aa7338be0fdb74covener * other retry.
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 */
60d81cab99dccfbb0c8d378cf6aa7338be0fdb74covener
60d81cab99dccfbb0c8d378cf6aa7338be0fdb74covener while (failures <= st->retries) {
5bfaaf573bacb45c1cf290ce85ecc676587e8a64jim if (failures > 0 && st->retry_delay > 0) {
60d81cab99dccfbb0c8d378cf6aa7338be0fdb74covener apr_sleep(st->retry_delay);
60d81cab99dccfbb0c8d378cf6aa7338be0fdb74covener }
7dbf29be626018bc389ef94c1846aeac4b72633bsf rc = uldap_simple_bind(ldc, (char *)ldc->binddn, (char *)ldc->bindpw,
7dbf29be626018bc389ef94c1846aeac4b72633bsf st->opTimeout);
60d81cab99dccfbb0c8d378cf6aa7338be0fdb74covener
60d81cab99dccfbb0c8d378cf6aa7338be0fdb74covener if (rc == LDAP_SUCCESS) break;
60d81cab99dccfbb0c8d378cf6aa7338be0fdb74covener
60d81cab99dccfbb0c8d378cf6aa7338be0fdb74covener failures++;
60d81cab99dccfbb0c8d378cf6aa7338be0fdb74covener
5bfaaf573bacb45c1cf290ce85ecc676587e8a64jim if (AP_LDAP_IS_SERVER_DOWN(rc)) {
60d81cab99dccfbb0c8d378cf6aa7338be0fdb74covener ap_log_rerror(APLOG_MARK, APLOG_TRACE2, 0, r,
60d81cab99dccfbb0c8d378cf6aa7338be0fdb74covener "ldap_simple_bind() failed with server down "
60d81cab99dccfbb0c8d378cf6aa7338be0fdb74covener "(try %d)", failures);
60d81cab99dccfbb0c8d378cf6aa7338be0fdb74covener }
60d81cab99dccfbb0c8d378cf6aa7338be0fdb74covener else if (rc == LDAP_TIMEOUT) {
185aa71728867671e105178b4c66fbc22b65ae26sf ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, APLOGNO(01284)
60d81cab99dccfbb0c8d378cf6aa7338be0fdb74covener "ldap_simple_bind() timed out on %s "
5bfaaf573bacb45c1cf290ce85ecc676587e8a64jim "connection, dropped by firewall?",
60d81cab99dccfbb0c8d378cf6aa7338be0fdb74covener new_connection ? "new" : "reused");
1f50dc34ae069adeed20b2986e5ffdefa5c410e0covener if (new_connection) break;
60d81cab99dccfbb0c8d378cf6aa7338be0fdb74covener }
5bfaaf573bacb45c1cf290ce85ecc676587e8a64jim else {
60d81cab99dccfbb0c8d378cf6aa7338be0fdb74covener /* Other errors not retryable */
60d81cab99dccfbb0c8d378cf6aa7338be0fdb74covener break;
60d81cab99dccfbb0c8d378cf6aa7338be0fdb74covener }
60d81cab99dccfbb0c8d378cf6aa7338be0fdb74covener
60d81cab99dccfbb0c8d378cf6aa7338be0fdb74covener if (!(failures % 2)) {
5bfaaf573bacb45c1cf290ce85ecc676587e8a64jim ap_log_rerror(APLOG_MARK, APLOG_TRACE2, 0, r,
9c63a05713cb83a44a1590b4af33edeebf39f118sf "attempt to re-init the connection");
60d81cab99dccfbb0c8d378cf6aa7338be0fdb74covener uldap_connection_unbind(ldc);
5bfaaf573bacb45c1cf290ce85ecc676587e8a64jim if (LDAP_SUCCESS != uldap_connection_init(r, ldc)) {
60d81cab99dccfbb0c8d378cf6aa7338be0fdb74covener /* leave rc as the initial bind return code */
9c63a05713cb83a44a1590b4af33edeebf39f118sf break;
9c63a05713cb83a44a1590b4af33edeebf39f118sf }
4be9c459920a7c1cfe62d654327dae5c4bb6b284sf }
5bfaaf573bacb45c1cf290ce85ecc676587e8a64jim }
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;
307219eca940aa30b873bfd68a44484dd3d3fa88covener ldc->must_rebind = 0;
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;
ab86c68ce36c715e93f403dde41d0b9c1522c8b0sf 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 */
ab86c68ce36c715e93f403dde41d0b9c1522c8b0sf src = (struct apr_ldap_opt_tls_cert_t *)srcs->elts;
ab86c68ce36c715e93f403dde41d0b9c1522c8b0sf 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;
a81c0c1ae464b2063a21b45f80c9da8d89bb840ecovener apr_time_t now = apr_time_now();
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
ab86c68ce36c715e93f403dde41d0b9c1522c8b0sf 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 {
5bfaaf573bacb45c1cf290ce85ecc676587e8a64jim if (st->connection_pool_ttl > 0) {
87a26948305eab2bab8a4fb3f2a21f6725055790covener if (l->bound && (now - l->last_backend_conn) > st->connection_pool_ttl) {
5bfaaf573bacb45c1cf290ce85ecc676587e8a64jim ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r,
5bfaaf573bacb45c1cf290ce85ecc676587e8a64jim "Removing LDAP connection last used %" APR_TIME_T_FMT " seconds ago",
87a26948305eab2bab8a4fb3f2a21f6725055790covener (now - l->last_backend_conn) / APR_USEC_PER_SEC);
307219eca940aa30b873bfd68a44484dd3d3fa88covener l->r = r;
a81c0c1ae464b2063a21b45f80c9da8d89bb840ecovener uldap_connection_unbind(l);
54091ac5c596337658fc568231ca1a900abdc5fecovener /* Go ahead (by falling through) and use it, so we don't create more just to unbind some other old ones */
a81c0c1ae464b2063a21b45f80c9da8d89bb840ecovener }
307219eca940aa30b873bfd68a44484dd3d3fa88covener ap_log_rerror(APLOG_MARK, APLOG_TRACE5, 0, r,
307219eca940aa30b873bfd68a44484dd3d3fa88covener "Reuse %s LDC %pp",
307219eca940aa30b873bfd68a44484dd3d3fa88covener l->bound ? "bound" : "unbound", l);
a81c0c1ae464b2063a21b45f80c9da8d89bb840ecovener }
54091ac5c596337658fc568231ca1a900abdc5fecovener 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 {
307219eca940aa30b873bfd68a44484dd3d3fa88covener if (st->connection_pool_ttl > 0) {
87a26948305eab2bab8a4fb3f2a21f6725055790covener if (l->bound && (now - l->last_backend_conn) > st->connection_pool_ttl) {
307219eca940aa30b873bfd68a44484dd3d3fa88covener ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r,
307219eca940aa30b873bfd68a44484dd3d3fa88covener "Removing LDAP connection last used %" APR_TIME_T_FMT " seconds ago",
87a26948305eab2bab8a4fb3f2a21f6725055790covener (now - l->last_backend_conn) / APR_USEC_PER_SEC);
307219eca940aa30b873bfd68a44484dd3d3fa88covener l->r = r;
307219eca940aa30b873bfd68a44484dd3d3fa88covener uldap_connection_unbind(l);
307219eca940aa30b873bfd68a44484dd3d3fa88covener /* Go ahead (by falling through) and use it, so we don't create more just to unbind some other old ones */
307219eca940aa30b873bfd68a44484dd3d3fa88covener }
307219eca940aa30b873bfd68a44484dd3d3fa88covener ap_log_rerror(APLOG_MARK, APLOG_TRACE5, 0, r,
307219eca940aa30b873bfd68a44484dd3d3fa88covener "Reuse %s LDC %pp (will rebind)",
307219eca940aa30b873bfd68a44484dd3d3fa88covener l->bound ? "bound" : "unbound", l);
307219eca940aa30b873bfd68a44484dd3d3fa88covener }
5bfaaf573bacb45c1cf290ce85ecc676587e8a64jim
307219eca940aa30b873bfd68a44484dd3d3fa88covener /* the bind credentials have changed */
307219eca940aa30b873bfd68a44484dd3d3fa88covener l->must_rebind = 1;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes util_ldap_strdup((char**)&(l->binddn), binddn);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes util_ldap_strdup((char**)&(l->bindpw), bindpw);
307219eca940aa30b873bfd68a44484dd3d3fa88covener
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) {
185aa71728867671e105178b4c66fbc22b65ae26sf ap_log_rerror(APLOG_MARK, APLOG_CRIT, 0, r, APLOGNO(01285)
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 }
5bfaaf573bacb45c1cf290ce85ecc676587e8a64jim
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
ab86c68ce36c715e93f403dde41d0b9c1522c8b0sf * 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
a81c0c1ae464b2063a21b45f80c9da8d89bb840ecovener /* whether or not to keep this connection in the pool when it's returned */
7a55c294da84865fe13262ed66ffd0c5841a9da5covener l->keep = (st->connection_pool_ttl == 0) ? 0 : 1;
4e9c24785b525d2956e6e381015c0f2bd0a72f4bcovener
5bfaaf573bacb45c1cf290ce85ecc676587e8a64jim if (l->ChaseReferrals == AP_LDAP_CHASEREFERRALS_ON) {
fa123db15501821e36e513afa78e839775ad2800covener if (apr_pool_create(&(l->rebind_pool), l->pool) != APR_SUCCESS) {
185aa71728867671e105178b4c66fbc22b65ae26sf ap_log_rerror(APLOG_MARK, APLOG_CRIT, 0, r, APLOGNO(01286)
fa123db15501821e36e513afa78e839775ad2800covener "util_ldap: Failed to create memory pool");
fa123db15501821e36e513afa78e839775ad2800covener#if APR_HAS_THREADS
fa123db15501821e36e513afa78e839775ad2800covener apr_thread_mutex_unlock(st->mutex);
fa123db15501821e36e513afa78e839775ad2800covener#endif
fa123db15501821e36e513afa78e839775ad2800covener return NULL;
fa123db15501821e36e513afa78e839775ad2800covener }
fa123db15501821e36e513afa78e839775ad2800covener }
fa123db15501821e36e513afa78e839775ad2800covener
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
307219eca940aa30b873bfd68a44484dd3d3fa88covener l->r = r;
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:
60d81cab99dccfbb0c8d378cf6aa7338be0fdb74covener if (failures > st->retries) {
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes return result;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
60d81cab99dccfbb0c8d378cf6aa7338be0fdb74covener if (failures > 0 && st->retry_delay > 0) {
60d81cab99dccfbb0c8d378cf6aa7338be0fdb74covener apr_sleep(st->retry_delay);
60d81cab99dccfbb0c8d378cf6aa7338be0fdb74covener }
60d81cab99dccfbb0c8d378cf6aa7338be0fdb74covener
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,
ab86c68ce36c715e93f403dde41d0b9c1522c8b0sf 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);
60d81cab99dccfbb0c8d378cf6aa7338be0fdb74covener failures++;
a930613ffb7a8b9f4101e9dddb76235c718053c8covener ap_log_rerror(APLOG_MARK, APLOG_TRACE5, 0, r, "%s (attempt %d)", ldc->reason, failures);
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);
60d81cab99dccfbb0c8d378cf6aa7338be0fdb74covener failures++;
a930613ffb7a8b9f4101e9dddb76235c718053c8covener ap_log_rerror(APLOG_MARK, APLOG_TRACE5, 0, r, "%s (attempt %d)", ldc->reason, failures);
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
87a26948305eab2bab8a4fb3f2a21f6725055790covener ldc->last_backend_conn = r->request_time;
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:
60d81cab99dccfbb0c8d378cf6aa7338be0fdb74covener if (failures > st->retries) {
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes return result;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj
60d81cab99dccfbb0c8d378cf6aa7338be0fdb74covener if (failures > 0 && st->retry_delay > 0) {
60d81cab99dccfbb0c8d378cf6aa7338be0fdb74covener apr_sleep(st->retry_delay);
60d81cab99dccfbb0c8d378cf6aa7338be0fdb74covener }
60d81cab99dccfbb0c8d378cf6aa7338be0fdb74covener
f43b67c5a9d29b572eac916f8335cedc80c908bebnicholes if (LDAP_SUCCESS != (result = uldap_connection_open(r, ldc))) {
93f973142a3d6db34052694c0d2d5869f527fdc5covener /* uldap_connection_open() retried already */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes return result;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
37af4b0cf648275b68ff41c866c665b4ccf4667dcovener result = ldap_compare_s(ldc->ldap,
37af4b0cf648275b68ff41c866c665b4ccf4667dcovener (char *)dn,
37af4b0cf648275b68ff41c866c665b4ccf4667dcovener (char *)attrib,
37af4b0cf648275b68ff41c866c665b4ccf4667dcovener (char *)value);
5bfaaf573bacb45c1cf290ce85ecc676587e8a64jim 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);
60d81cab99dccfbb0c8d378cf6aa7338be0fdb74covener failures++;
a930613ffb7a8b9f4101e9dddb76235c718053c8covener ap_log_rerror(APLOG_MARK, APLOG_TRACE5, 0, r, "%s (attempt %d)", ldc->reason, failures);
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);
60d81cab99dccfbb0c8d378cf6aa7338be0fdb74covener failures++;
a930613ffb7a8b9f4101e9dddb76235c718053c8covener ap_log_rerror(APLOG_MARK, APLOG_TRACE5, 0, r, "%s (attempt %d)", ldc->reason, failures);
4be9c459920a7c1cfe62d654327dae5c4bb6b284sf goto start_over;
4be9c459920a7c1cfe62d654327dae5c4bb6b284sf }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
87a26948305eab2bab8a4fb3f2a21f6725055790covener ldc->last_backend_conn = r->request_time;
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) {
185aa71728867671e105178b4c66fbc22b65ae26sf ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01287)
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 *));
60d81cab99dccfbb0c8d378cf6aa7338be0fdb74covener util_ldap_state_t *st = (util_ldap_state_t *)
60d81cab99dccfbb0c8d378cf6aa7338be0fdb74covener ap_get_module_config(r->server->module_config,
60d81cab99dccfbb0c8d378cf6aa7338be0fdb74covener &ldap_module);
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 */
60d81cab99dccfbb0c8d378cf6aa7338be0fdb74covener if (failures > st->retries) {
8869662bb1a4078297020e94ae5e928626d877c6rederpj return res;
8869662bb1a4078297020e94ae5e928626d877c6rederpj }
8869662bb1a4078297020e94ae5e928626d877c6rederpj
60d81cab99dccfbb0c8d378cf6aa7338be0fdb74covener if (failures > 0 && st->retry_delay > 0) {
60d81cab99dccfbb0c8d378cf6aa7338be0fdb74covener apr_sleep(st->retry_delay);
60d81cab99dccfbb0c8d378cf6aa7338be0fdb74covener }
60d81cab99dccfbb0c8d378cf6aa7338be0fdb74covener
60d81cab99dccfbb0c8d378cf6aa7338be0fdb74covener
8869662bb1a4078297020e94ae5e928626d877c6rederpj if (LDAP_SUCCESS != (result = uldap_connection_open(r, ldc))) {
cbe04df5690511fd1e97f9efc9ed51ceb823cbedcovener /* uldap_connection_open() retried already */
8869662bb1a4078297020e94ae5e928626d877c6rederpj return res;
8869662bb1a4078297020e94ae5e928626d877c6rederpj }
8869662bb1a4078297020e94ae5e928626d877c6rederpj
8869662bb1a4078297020e94ae5e928626d877c6rederpj /* try to do the search */
8869662bb1a4078297020e94ae5e928626d877c6rederpj result = ldap_search_ext_s(ldc->ldap, (char *)dn, LDAP_SCOPE_BASE,
c56dba16be3b59e76160410e3291851287475705covener NULL, subgroupAttrs, 0,
ab86c68ce36c715e93f403dde41d0b9c1522c8b0sf 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);
60d81cab99dccfbb0c8d378cf6aa7338be0fdb74covener failures++;
a930613ffb7a8b9f4101e9dddb76235c718053c8covener ap_log_rerror(APLOG_MARK, APLOG_TRACE5, 0, r, "%s (attempt %d)", ldc->reason, failures);
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);
60d81cab99dccfbb0c8d378cf6aa7338be0fdb74covener failures++;
a930613ffb7a8b9f4101e9dddb76235c718053c8covener ap_log_rerror(APLOG_MARK, APLOG_TRACE5, 0, r, "%s (attempt %d)", ldc->reason, failures);
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
87a26948305eab2bab8a4fb3f2a21f6725055790covener ldc->last_backend_conn = r->request_time;
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,
5394490a3a12f43bc2364fd97b2d5792aeef81ddcovener 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));
342377e75b69a70c16175cce7f694472f9f8a6adjailletc res->subgroupDNs = apr_palloc(r->pool,
342377e75b69a70c16175cce7f694472f9f8a6adjailletc 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;
185aa71728867671e105178b4c66fbc22b65ae26sf ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01288)
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 =
342377e75b69a70c16175cce7f694472f9f8a6adjailletc apr_palloc(r->pool,
342377e75b69a70c16175cce7f694472f9f8a6adjailletc 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 */
185aa71728867671e105178b4c66fbc22b65ae26sf ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01289)
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 */
185aa71728867671e105178b4c66fbc22b65ae26sf ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01290) "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 */
185aa71728867671e105178b4c66fbc22b65ae26sf ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01291)
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) {
185aa71728867671e105178b4c66fbc22b65ae26sf ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01292)
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);
185aa71728867671e105178b4c66fbc22b65ae26sf ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, APLOGNO(01293)
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 {
185aa71728867671e105178b4c66fbc22b65ae26sf ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server, APLOGNO(01294)
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 */
185aa71728867671e105178b4c66fbc22b65ae26sf ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01295)
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 */
185aa71728867671e105178b4c66fbc22b65ae26sf ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01296)
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;
9597d9521d858a60fd123c9cf6e9d779a1dfa466jailletc *retvals = apr_palloc(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:
60d81cab99dccfbb0c8d378cf6aa7338be0fdb74covener if (failures > st->retries) {
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes return result;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
60d81cab99dccfbb0c8d378cf6aa7338be0fdb74covener
60d81cab99dccfbb0c8d378cf6aa7338be0fdb74covener if (failures > 0 && st->retry_delay > 0) {
60d81cab99dccfbb0c8d378cf6aa7338be0fdb74covener apr_sleep(st->retry_delay);
60d81cab99dccfbb0c8d378cf6aa7338be0fdb74covener }
60d81cab99dccfbb0c8d378cf6aa7338be0fdb74covener
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,
ab86c68ce36c715e93f403dde41d0b9c1522c8b0sf 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);
60d81cab99dccfbb0c8d378cf6aa7338be0fdb74covener failures++;
a930613ffb7a8b9f4101e9dddb76235c718053c8covener ap_log_rerror(APLOG_MARK, APLOG_TRACE5, 0, r, "%s (attempt %d)", ldc->reason, failures);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes goto start_over;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
4a0eca81f75e6151c9a21b7a941e9cc04a0ae9bacovener if (result == LDAP_TIMEOUT) {
4a0eca81f75e6151c9a21b7a941e9cc04a0ae9bacovener ldc->reason = "ldap_search_ext_s() for user failed with timeout";
4a0eca81f75e6151c9a21b7a941e9cc04a0ae9bacovener uldap_connection_unbind(ldc);
4a0eca81f75e6151c9a21b7a941e9cc04a0ae9bacovener failures++;
a930613ffb7a8b9f4101e9dddb76235c718053c8covener ap_log_rerror(APLOG_MARK, APLOG_TRACE5, 0, r, "%s (attempt %d)", ldc->reason, failures);
4a0eca81f75e6151c9a21b7a941e9cc04a0ae9bacovener goto start_over;
4a0eca81f75e6151c9a21b7a941e9cc04a0ae9bacovener }
4a0eca81f75e6151c9a21b7a941e9cc04a0ae9bacovener
4a0eca81f75e6151c9a21b7a941e9cc04a0ae9bacovener
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 */
87a26948305eab2bab8a4fb3f2a21f6725055790covener ldc->last_backend_conn = r->request_time;
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);
60d81cab99dccfbb0c8d378cf6aa7338be0fdb74covener failures++;
a930613ffb7a8b9f4101e9dddb76235c718053c8covener ap_log_rerror(APLOG_MARK, APLOG_TRACE5, 0, r, "%s (attempt %d)", ldc->reason, failures);
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
307219eca940aa30b873bfd68a44484dd3d3fa88covener * connection is used from the connection pool.
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes */
25d7c52391205ab26e3c8a314e8ba862c54b0041covener ldc->must_rebind = 1;
307219eca940aa30b873bfd68a44484dd3d3fa88covener ap_log_rerror(APLOG_MARK, APLOG_TRACE5, 0, r, "LDC %pp used for authn, must be rebound", ldc);
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;
342377e75b69a70c16175cce7f694472f9f8a6adjailletc *retvals = apr_palloc(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:
60d81cab99dccfbb0c8d378cf6aa7338be0fdb74covener if (failures > st->retries) {
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes return result;
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes }
60d81cab99dccfbb0c8d378cf6aa7338be0fdb74covener
60d81cab99dccfbb0c8d378cf6aa7338be0fdb74covener if (failures > 0 && st->retry_delay > 0) {
60d81cab99dccfbb0c8d378cf6aa7338be0fdb74covener apr_sleep(st->retry_delay);
60d81cab99dccfbb0c8d378cf6aa7338be0fdb74covener }
60d81cab99dccfbb0c8d378cf6aa7338be0fdb74covener
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,
ab86c68ce36c715e93f403dde41d0b9c1522c8b0sf 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);
60d81cab99dccfbb0c8d378cf6aa7338be0fdb74covener failures++;
a930613ffb7a8b9f4101e9dddb76235c718053c8covener ap_log_rerror(APLOG_MARK, APLOG_TRACE5, 0, r, "%s (attempt %d)", ldc->reason, failures);
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 */
87a26948305eab2bab8a4fb3f2a21f6725055790covener ldc->last_backend_conn = r->request_time;
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
185aa71728867671e105178b4c66fbc22b65ae26sf ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, cmd->server, APLOGNO(01297)
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) {
f474c7d8026377782a5cf4d95af6a3443759c0b0trawick st->cache_file = ap_runtime_dir_relative(st->pool, file);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes else {
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes st->cache_file = NULL;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
185aa71728867671e105178b4c66fbc22b65ae26sf ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, cmd->server, APLOGNO(01298)
851ee1e10feb6c88b7dad7572bd9b4f3d9e91fcftrawick "LDAP cache: Setting shared memory cache file to %s.",
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
185aa71728867671e105178b4c66fbc22b65ae26sf ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, cmd->server, APLOGNO(01299)
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
185aa71728867671e105178b4c66fbc22b65ae26sf ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, cmd->server, APLOGNO(01300)
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
185aa71728867671e105178b4c66fbc22b65ae26sf ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, cmd->server, APLOGNO(01301)
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
185aa71728867671e105178b4c66fbc22b65ae26sf ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, cmd->server, APLOGNO(01302)
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 *
ab86c68ce36c715e93f403dde41d0b9c1522c8b0sf * 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)) {
ab86c68ce36c715e93f403dde41d0b9c1522c8b0sf return APR_LDAP_CA_TYPE_DER;
54d22ed1c429b903b029bbd62621f11a9e286137minfrin }
54d22ed1c429b903b029bbd62621f11a9e286137minfrin
54d22ed1c429b903b029bbd62621f11a9e286137minfrin /* Authority file in Base64 format */
54d22ed1c429b903b029bbd62621f11a9e286137minfrin else if (0 == strcasecmp("CA_BASE64", type)) {
ab86c68ce36c715e93f403dde41d0b9c1522c8b0sf return APR_LDAP_CA_TYPE_BASE64;
54d22ed1c429b903b029bbd62621f11a9e286137minfrin }
54d22ed1c429b903b029bbd62621f11a9e286137minfrin
54d22ed1c429b903b029bbd62621f11a9e286137minfrin /* Netscape certificate database file/directory */
54d22ed1c429b903b029bbd62621f11a9e286137minfrin else if (0 == strcasecmp("CA_CERT7_DB", type)) {
ab86c68ce36c715e93f403dde41d0b9c1522c8b0sf return APR_LDAP_CA_TYPE_CERT7_DB;
54d22ed1c429b903b029bbd62621f11a9e286137minfrin }
54d22ed1c429b903b029bbd62621f11a9e286137minfrin
54d22ed1c429b903b029bbd62621f11a9e286137minfrin /* Netscape secmod file/directory */
54d22ed1c429b903b029bbd62621f11a9e286137minfrin else if (0 == strcasecmp("CA_SECMOD", type)) {
ab86c68ce36c715e93f403dde41d0b9c1522c8b0sf return APR_LDAP_CA_TYPE_SECMOD;
54d22ed1c429b903b029bbd62621f11a9e286137minfrin }
54d22ed1c429b903b029bbd62621f11a9e286137minfrin
54d22ed1c429b903b029bbd62621f11a9e286137minfrin /* Client cert file in DER format */
54d22ed1c429b903b029bbd62621f11a9e286137minfrin else if (0 == strcasecmp("CERT_DER", type)) {
ab86c68ce36c715e93f403dde41d0b9c1522c8b0sf return APR_LDAP_CERT_TYPE_DER;
54d22ed1c429b903b029bbd62621f11a9e286137minfrin }
54d22ed1c429b903b029bbd62621f11a9e286137minfrin
54d22ed1c429b903b029bbd62621f11a9e286137minfrin /* Client cert file in Base64 format */
54d22ed1c429b903b029bbd62621f11a9e286137minfrin else if (0 == strcasecmp("CERT_BASE64", type)) {
ab86c68ce36c715e93f403dde41d0b9c1522c8b0sf return APR_LDAP_CERT_TYPE_BASE64;
54d22ed1c429b903b029bbd62621f11a9e286137minfrin }
54d22ed1c429b903b029bbd62621f11a9e286137minfrin
09338db7fdcf82ecc189195347da3a3ed5d0287abnicholes /* Client cert file in PKCS#12 format */
09338db7fdcf82ecc189195347da3a3ed5d0287abnicholes else if (0 == strcasecmp("CERT_PFX", type)) {
ab86c68ce36c715e93f403dde41d0b9c1522c8b0sf return APR_LDAP_CERT_TYPE_PFX;
09338db7fdcf82ecc189195347da3a3ed5d0287abnicholes }
09338db7fdcf82ecc189195347da3a3ed5d0287abnicholes
54d22ed1c429b903b029bbd62621f11a9e286137minfrin /* Netscape client cert database file/directory */
54d22ed1c429b903b029bbd62621f11a9e286137minfrin else if (0 == strcasecmp("CERT_KEY3_DB", type)) {
ab86c68ce36c715e93f403dde41d0b9c1522c8b0sf return APR_LDAP_CERT_TYPE_KEY3_DB;
54d22ed1c429b903b029bbd62621f11a9e286137minfrin }
54d22ed1c429b903b029bbd62621f11a9e286137minfrin
54d22ed1c429b903b029bbd62621f11a9e286137minfrin /* Netscape client cert nickname */
54d22ed1c429b903b029bbd62621f11a9e286137minfrin else if (0 == strcasecmp("CERT_NICKNAME", type)) {
ab86c68ce36c715e93f403dde41d0b9c1522c8b0sf return APR_LDAP_CERT_TYPE_NICKNAME;
54d22ed1c429b903b029bbd62621f11a9e286137minfrin }
54d22ed1c429b903b029bbd62621f11a9e286137minfrin
54d22ed1c429b903b029bbd62621f11a9e286137minfrin /* Client cert key file in DER format */
54d22ed1c429b903b029bbd62621f11a9e286137minfrin else if (0 == strcasecmp("KEY_DER", type)) {
ab86c68ce36c715e93f403dde41d0b9c1522c8b0sf return APR_LDAP_KEY_TYPE_DER;
54d22ed1c429b903b029bbd62621f11a9e286137minfrin }
54d22ed1c429b903b029bbd62621f11a9e286137minfrin
54d22ed1c429b903b029bbd62621f11a9e286137minfrin /* Client cert key file in Base64 format */
54d22ed1c429b903b029bbd62621f11a9e286137minfrin else if (0 == strcasecmp("KEY_BASE64", type)) {
ab86c68ce36c715e93f403dde41d0b9c1522c8b0sf 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)) {
ab86c68ce36c715e93f403dde41d0b9c1522c8b0sf return APR_LDAP_KEY_TYPE_PFX;
09338db7fdcf82ecc189195347da3a3ed5d0287abnicholes }
09338db7fdcf82ecc189195347da3a3ed5d0287abnicholes
54d22ed1c429b903b029bbd62621f11a9e286137minfrin else {
ab86c68ce36c715e93f403dde41d0b9c1522c8b0sf 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{
793214f67dede32edfd9ee96c664ead04d175cbbjfclere#if APR_HAS_MICROSOFT_LDAPSDK
793214f67dede32edfd9ee96c664ead04d175cbbjfclere return "certificates cannot be set using this method.";
793214f67dede32edfd9ee96c664ead04d175cbbjfclere#else
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;
ab86c68ce36c715e93f403dde41d0b9c1522c8b0sf 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);
ab86c68ce36c715e93f403dde41d0b9c1522c8b0sf 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
185aa71728867671e105178b4c66fbc22b65ae26sf ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, cmd->server, APLOGNO(01303)
54d22ed1c429b903b029bbd62621f11a9e286137minfrin "LDAP: SSL trusted global cert - %s (type %s)",
54d22ed1c429b903b029bbd62621f11a9e286137minfrin file, type);
54d22ed1c429b903b029bbd62621f11a9e286137minfrin
54d22ed1c429b903b029bbd62621f11a9e286137minfrin /* add the certificate to the global array */
ab86c68ce36c715e93f403dde41d0b9c1522c8b0sf 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 */
ab86c68ce36c715e93f403dde41d0b9c1522c8b0sf if (cert_type != APR_LDAP_CA_TYPE_UNKNOWN &&
ab86c68ce36c715e93f403dde41d0b9c1522c8b0sf 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 {
185aa71728867671e105178b4c66fbc22b65ae26sf ap_log_error(APLOG_MARK, APLOG_ERR, rv, cmd->server, APLOGNO(01304)
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);
793214f67dede32edfd9ee96c664ead04d175cbbjfclere#endif
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{
d51494bc46ade92d9b033459e574b9b1088edcf7jfclere#if APR_HAS_MICROSOFT_LDAPSDK
d51494bc46ade92d9b033459e574b9b1088edcf7jfclere return "certificates cannot be set using this method.";
d51494bc46ade92d9b033459e574b9b1088edcf7jfclere#else
ae1981fc94adf2b231e2d0e15d2f895b2138c969covener util_ldap_config_t *dc = config;
54d22ed1c429b903b029bbd62621f11a9e286137minfrin apr_finfo_t finfo;
54d22ed1c429b903b029bbd62621f11a9e286137minfrin apr_status_t rv;
54d22ed1c429b903b029bbd62621f11a9e286137minfrin int cert_type = 0;
ab86c68ce36c715e93f403dde41d0b9c1522c8b0sf 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);
ab86c68ce36c715e93f403dde41d0b9c1522c8b0sf 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 }
ab86c68ce36c715e93f403dde41d0b9c1522c8b0sf else if ( APR_LDAP_CA_TYPE_CERT7_DB == cert_type ||
ab86c68ce36c715e93f403dde41d0b9c1522c8b0sf APR_LDAP_CA_TYPE_SECMOD == cert_type ||
ab86c68ce36c715e93f403dde41d0b9c1522c8b0sf APR_LDAP_CERT_TYPE_PFX == cert_type ||
ab86c68ce36c715e93f403dde41d0b9c1522c8b0sf 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
185aa71728867671e105178b4c66fbc22b65ae26sf ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, cmd->server, APLOGNO(01305)
54d22ed1c429b903b029bbd62621f11a9e286137minfrin "LDAP: SSL trusted client cert - %s (type %s)",
54d22ed1c429b903b029bbd62621f11a9e286137minfrin file, type);
54d22ed1c429b903b029bbd62621f11a9e286137minfrin
ae1981fc94adf2b231e2d0e15d2f895b2138c969covener /* add the certificate to the client array */
ab86c68ce36c715e93f403dde41d0b9c1522c8b0sf 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 */
ab86c68ce36c715e93f403dde41d0b9c1522c8b0sf if (cert_type != APR_LDAP_CA_TYPE_UNKNOWN &&
ab86c68ce36c715e93f403dde41d0b9c1522c8b0sf 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 {
185aa71728867671e105178b4c66fbc22b65ae26sf ap_log_error(APLOG_MARK, APLOG_ERR, rv, cmd->server, APLOGNO(01306)
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);
d51494bc46ade92d9b033459e574b9b1088edcf7jfclere#endif
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
185aa71728867671e105178b4c66fbc22b65ae26sf ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, cmd->server, APLOGNO(01307)
54d22ed1c429b903b029bbd62621f11a9e286137minfrin "LDAP: SSL trusted mode - %s",
54d22ed1c429b903b029bbd62621f11a9e286137minfrin mode);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
54d22ed1c429b903b029bbd62621f11a9e286137minfrin if (0 == strcasecmp("NONE", mode)) {
ab86c68ce36c715e93f403dde41d0b9c1522c8b0sf st->secure = APR_LDAP_NONE;
54d22ed1c429b903b029bbd62621f11a9e286137minfrin }
54d22ed1c429b903b029bbd62621f11a9e286137minfrin else if (0 == strcasecmp("SSL", mode)) {
ab86c68ce36c715e93f403dde41d0b9c1522c8b0sf st->secure = APR_LDAP_SSL;
54d22ed1c429b903b029bbd62621f11a9e286137minfrin }
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe else if ( (0 == strcasecmp("TLS", mode))
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe || (0 == strcasecmp("STARTTLS", mode))) {
ab86c68ce36c715e93f403dde41d0b9c1522c8b0sf 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
185aa71728867671e105178b4c66fbc22b65ae26sf ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, cmd->server, APLOGNO(01308)
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
185aa71728867671e105178b4c66fbc22b65ae26sf ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, cmd->server, APLOGNO(01309)
9efd5708f6f0ab1992f6a5233eb622ad5e4eae18sf "ldap connection: Setting connection timeout to %ld seconds.",
9efd5708f6f0ab1992f6a5233eb622ad5e4eae18sf st->connectionTimeout);
1c9fe70e77b36d36ae34997fe25fe47beacf8709bnicholes#else
185aa71728867671e105178b4c66fbc22b65ae26sf ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, cmd->server, APLOGNO(01310)
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,
60284a9f9158baa60cc8ab4a69066404b1dcae7acovener const char *arg)
9ad7b260be233be7d7b5576979825cac72e15498rederpj{
9ad7b260be233be7d7b5576979825cac72e15498rederpj util_ldap_config_t *dc = config;
9ad7b260be233be7d7b5576979825cac72e15498rederpj
185aa71728867671e105178b4c66fbc22b65ae26sf ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, cmd->server, APLOGNO(01311)
60284a9f9158baa60cc8ab4a69066404b1dcae7acovener "LDAP: Setting referral chasing %s", arg);
9ad7b260be233be7d7b5576979825cac72e15498rederpj
60284a9f9158baa60cc8ab4a69066404b1dcae7acovener if (0 == strcasecmp(arg, "on")) {
60284a9f9158baa60cc8ab4a69066404b1dcae7acovener dc->ChaseReferrals = AP_LDAP_CHASEREFERRALS_ON;
60284a9f9158baa60cc8ab4a69066404b1dcae7acovener }
60284a9f9158baa60cc8ab4a69066404b1dcae7acovener else if (0 == strcasecmp(arg, "off")) {
60284a9f9158baa60cc8ab4a69066404b1dcae7acovener dc->ChaseReferrals = AP_LDAP_CHASEREFERRALS_OFF;
60284a9f9158baa60cc8ab4a69066404b1dcae7acovener }
60284a9f9158baa60cc8ab4a69066404b1dcae7acovener else if (0 == strcasecmp(arg, "default")) {
60284a9f9158baa60cc8ab4a69066404b1dcae7acovener dc->ChaseReferrals = AP_LDAP_CHASEREFERRALS_SDKDEFAULT;
60284a9f9158baa60cc8ab4a69066404b1dcae7acovener }
60284a9f9158baa60cc8ab4a69066404b1dcae7acovener else {
60284a9f9158baa60cc8ab4a69066404b1dcae7acovener return "LDAPReferrals must be 'on', 'off', or 'default'";
60284a9f9158baa60cc8ab4a69066404b1dcae7acovener }
9ad7b260be233be7d7b5576979825cac72e15498rederpj
9ad7b260be233be7d7b5576979825cac72e15498rederpj return(NULL);
9ad7b260be233be7d7b5576979825cac72e15498rederpj}
9ad7b260be233be7d7b5576979825cac72e15498rederpj
0f60998368b493f90120180a93fc2e1e74490872covenerstatic const char *util_ldap_set_debug_level(cmd_parms *cmd,
0f60998368b493f90120180a93fc2e1e74490872covener void *config,
5bfaaf573bacb45c1cf290ce85ecc676587e8a64jim const char *arg) {
738d06536327e345daac9f4978b957262f48cfacrjung#ifdef AP_LDAP_OPT_DEBUG
0f60998368b493f90120180a93fc2e1e74490872covener util_ldap_state_t *st =
0f60998368b493f90120180a93fc2e1e74490872covener (util_ldap_state_t *)ap_get_module_config(cmd->server->module_config,
0f60998368b493f90120180a93fc2e1e74490872covener &ldap_module);
738d06536327e345daac9f4978b957262f48cfacrjung#endif
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";
37aeeeca6c5a3b2fcdb0b5256806e794fe47298bsf#else
0f60998368b493f90120180a93fc2e1e74490872covener st->debug_level = atoi(arg);
0f60998368b493f90120180a93fc2e1e74490872covener return NULL;
37aeeeca6c5a3b2fcdb0b5256806e794fe47298bsf#endif
5bfaaf573bacb45c1cf290ce85ecc676587e8a64jim}
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
5bfaaf573bacb45c1cf290ce85ecc676587e8a64jim if (dc->ReferralHopLimit <= 0) {
67c5e190a7b84528b8895d7ef7be81712d206805covener return "LDAPReferralHopLimit must be greater than zero (Use 'LDAPReferrals Off' to disable referral chasing)";
67c5e190a7b84528b8895d7ef7be81712d206805covener }
67c5e190a7b84528b8895d7ef7be81712d206805covener
185aa71728867671e105178b4c66fbc22b65ae26sf ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, cmd->server, APLOGNO(01312)
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 */
ab86c68ce36c715e93f403dde41d0b9c1522c8b0sf 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
185aa71728867671e105178b4c66fbc22b65ae26sf ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, cmd->server, APLOGNO(01313)
9efd5708f6f0ab1992f6a5233eb622ad5e4eae18sf "ldap connection: Setting op timeout to %ld seconds.",
9efd5708f6f0ab1992f6a5233eb622ad5e4eae18sf timeout);
4be9c459920a7c1cfe62d654327dae5c4bb6b284sf
4be9c459920a7c1cfe62d654327dae5c4bb6b284sf return NULL;
4be9c459920a7c1cfe62d654327dae5c4bb6b284sf}
4be9c459920a7c1cfe62d654327dae5c4bb6b284sf
a81c0c1ae464b2063a21b45f80c9da8d89bb840ecovenerstatic const char *util_ldap_set_conn_ttl(cmd_parms *cmd,
a81c0c1ae464b2063a21b45f80c9da8d89bb840ecovener void *dummy,
a81c0c1ae464b2063a21b45f80c9da8d89bb840ecovener const char *val)
a81c0c1ae464b2063a21b45f80c9da8d89bb840ecovener{
a81c0c1ae464b2063a21b45f80c9da8d89bb840ecovener apr_interval_time_t timeout;
a81c0c1ae464b2063a21b45f80c9da8d89bb840ecovener util_ldap_state_t *st =
a81c0c1ae464b2063a21b45f80c9da8d89bb840ecovener (util_ldap_state_t *)ap_get_module_config(cmd->server->module_config,
a81c0c1ae464b2063a21b45f80c9da8d89bb840ecovener &ldap_module);
a81c0c1ae464b2063a21b45f80c9da8d89bb840ecovener
5bfaaf573bacb45c1cf290ce85ecc676587e8a64jim if (ap_timeout_parameter_parse(val, &timeout, "s") != APR_SUCCESS) {
a81c0c1ae464b2063a21b45f80c9da8d89bb840ecovener return "LDAPConnPoolTTL has wrong format";
a81c0c1ae464b2063a21b45f80c9da8d89bb840ecovener }
4be9c459920a7c1cfe62d654327dae5c4bb6b284sf
5bfaaf573bacb45c1cf290ce85ecc676587e8a64jim if (timeout < 0) {
0972df03482b520989d4adbf12626755aef24907covener /* reserve -1 for default value */
0972df03482b520989d4adbf12626755aef24907covener timeout = AP_LDAP_CONNPOOL_INFINITE;
0972df03482b520989d4adbf12626755aef24907covener }
7a55c294da84865fe13262ed66ffd0c5841a9da5covener st->connection_pool_ttl = timeout;
a81c0c1ae464b2063a21b45f80c9da8d89bb840ecovener return NULL;
a81c0c1ae464b2063a21b45f80c9da8d89bb840ecovener}
60d81cab99dccfbb0c8d378cf6aa7338be0fdb74covenerstatic const char *util_ldap_set_retry_delay(cmd_parms *cmd,
60d81cab99dccfbb0c8d378cf6aa7338be0fdb74covener void *dummy,
60d81cab99dccfbb0c8d378cf6aa7338be0fdb74covener const char *val)
60d81cab99dccfbb0c8d378cf6aa7338be0fdb74covener{
60d81cab99dccfbb0c8d378cf6aa7338be0fdb74covener apr_interval_time_t timeout;
60d81cab99dccfbb0c8d378cf6aa7338be0fdb74covener util_ldap_state_t *st =
60d81cab99dccfbb0c8d378cf6aa7338be0fdb74covener (util_ldap_state_t *)ap_get_module_config(cmd->server->module_config,
60d81cab99dccfbb0c8d378cf6aa7338be0fdb74covener &ldap_module);
60d81cab99dccfbb0c8d378cf6aa7338be0fdb74covener const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
a81c0c1ae464b2063a21b45f80c9da8d89bb840ecovener
60d81cab99dccfbb0c8d378cf6aa7338be0fdb74covener if (err != NULL) {
60d81cab99dccfbb0c8d378cf6aa7338be0fdb74covener return err;
60d81cab99dccfbb0c8d378cf6aa7338be0fdb74covener }
60d81cab99dccfbb0c8d378cf6aa7338be0fdb74covener
5bfaaf573bacb45c1cf290ce85ecc676587e8a64jim if (ap_timeout_parameter_parse(val, &timeout, "s") != APR_SUCCESS) {
60d81cab99dccfbb0c8d378cf6aa7338be0fdb74covener return "LDAPRetryDelay has wrong format";
60d81cab99dccfbb0c8d378cf6aa7338be0fdb74covener }
60d81cab99dccfbb0c8d378cf6aa7338be0fdb74covener
5bfaaf573bacb45c1cf290ce85ecc676587e8a64jim if (timeout < 0) {
60d81cab99dccfbb0c8d378cf6aa7338be0fdb74covener return "LDAPRetryDelay must be >= 0";
60d81cab99dccfbb0c8d378cf6aa7338be0fdb74covener }
60d81cab99dccfbb0c8d378cf6aa7338be0fdb74covener
60d81cab99dccfbb0c8d378cf6aa7338be0fdb74covener st->retry_delay = timeout;
60d81cab99dccfbb0c8d378cf6aa7338be0fdb74covener return NULL;
60d81cab99dccfbb0c8d378cf6aa7338be0fdb74covener}
60d81cab99dccfbb0c8d378cf6aa7338be0fdb74covener
60d81cab99dccfbb0c8d378cf6aa7338be0fdb74covenerstatic const char *util_ldap_set_retries(cmd_parms *cmd,
60d81cab99dccfbb0c8d378cf6aa7338be0fdb74covener void *dummy,
60d81cab99dccfbb0c8d378cf6aa7338be0fdb74covener const char *val)
60d81cab99dccfbb0c8d378cf6aa7338be0fdb74covener{
60d81cab99dccfbb0c8d378cf6aa7338be0fdb74covener util_ldap_state_t *st =
60d81cab99dccfbb0c8d378cf6aa7338be0fdb74covener (util_ldap_state_t *)ap_get_module_config(cmd->server->module_config,
60d81cab99dccfbb0c8d378cf6aa7338be0fdb74covener &ldap_module);
60d81cab99dccfbb0c8d378cf6aa7338be0fdb74covener const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
60d81cab99dccfbb0c8d378cf6aa7338be0fdb74covener
60d81cab99dccfbb0c8d378cf6aa7338be0fdb74covener if (err != NULL) {
60d81cab99dccfbb0c8d378cf6aa7338be0fdb74covener return err;
60d81cab99dccfbb0c8d378cf6aa7338be0fdb74covener }
60d81cab99dccfbb0c8d378cf6aa7338be0fdb74covener
60d81cab99dccfbb0c8d378cf6aa7338be0fdb74covener st->retries = atoi(val);
5bfaaf573bacb45c1cf290ce85ecc676587e8a64jim if (st->retries < 0) {
60d81cab99dccfbb0c8d378cf6aa7338be0fdb74covener return "LDAPRetries must be >= 0";
60d81cab99dccfbb0c8d378cf6aa7338be0fdb74covener }
60d81cab99dccfbb0c8d378cf6aa7338be0fdb74covener
5bfaaf573bacb45c1cf290ce85ecc676587e8a64jim return NULL;
60d81cab99dccfbb0c8d378cf6aa7338be0fdb74covener}
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
5bfaaf573bacb45c1cf290ce85ecc676587e8a64jim /* 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;
ab86c68ce36c715e93f403dde41d0b9c1522c8b0sf st->global_certs = apr_array_make(p, 10, sizeof(apr_ldap_opt_tls_cert_t));
ab86c68ce36c715e93f403dde41d0b9c1522c8b0sf 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;
7a55c294da84865fe13262ed66ffd0c5841a9da5covener st->connection_pool_ttl = AP_LDAP_CONNPOOL_DEFAULT; /* no limit */
60d81cab99dccfbb0c8d378cf6aa7338be0fdb74covener st->retries = 3;
60d81cab99dccfbb0c8d378cf6aa7338be0fdb74covener st->retry_delay = 0; /* no delay */
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
5bfaaf573bacb45c1cf290ce85ecc676587e8a64jim /* 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;
5bfaaf573bacb45c1cf290ce85ecc676587e8a64jim st->util_ldap_cache_lock = base->util_ldap_cache_lock;
9c247afacdbb56fa794715f2ac218eb1cae39fe8bnicholes
9c247afacdbb56fa794715f2ac218eb1cae39fe8bnicholes st->connections = NULL;
03944c8577b204701c849fce01f3fcb423a615f1covener st->ssl_supported = 0; /* not known until post-config and re-merged */
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
5bfaaf573bacb45c1cf290ce85ecc676587e8a64jim /* These LDAP connection settings can not be overwritten in
5bfaaf573bacb45c1cf290ce85ecc676587e8a64jim a virtual host. Once set in the base server, they must
cbbfa8f4222ecc7b2e0f16db3032d0118d6a0accbnicholes remain the same. None of the LDAP SDKs seem to be able
5bfaaf573bacb45c1cf290ce85ecc676587e8a64jim 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
5bfaaf573bacb45c1cf290ce85ecc676587e8a64jim 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
5bfaaf573bacb45c1cf290ce85ecc676587e8a64jim st->connection_pool_ttl = (overrides->connection_pool_ttl == AP_LDAP_CONNPOOL_DEFAULT) ?
7a55c294da84865fe13262ed66ffd0c5841a9da5covener base->connection_pool_ttl : overrides->connection_pool_ttl;
a81c0c1ae464b2063a21b45f80c9da8d89bb840ecovener
60d81cab99dccfbb0c8d378cf6aa7338be0fdb74covener st->retries = base->retries;
60d81cab99dccfbb0c8d378cf6aa7338be0fdb74covener st->retry_delay = base->retry_delay;
60d81cab99dccfbb0c8d378cf6aa7338be0fdb74covener
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) {
ab86c68ce36c715e93f403dde41d0b9c1522c8b0sf 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
ab86c68ce36c715e93f403dde41d0b9c1522c8b0sf 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.*/
59d316b83d42d2a07e25c20d8c35a07b369618bdsf if (ap_state_query(AP_SQ_MAIN_STATE) == AP_SQ_MS_CREATE_PRE_CONFIG) {
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes#if APR_HAS_SHARED_MEMORY
e19d3a1e487aa73e0850658d3773f748aefba7f7sf /*
e19d3a1e487aa73e0850658d3773f748aefba7f7sf * If we are using shared memory caching and the cache file already
e19d3a1e487aa73e0850658d3773f748aefba7f7sf * exists then delete it. Otherwise we are going to run into problems
e19d3a1e487aa73e0850658d3773f748aefba7f7sf * creating the shared memory.
e19d3a1e487aa73e0850658d3773f748aefba7f7sf */
e19d3a1e487aa73e0850658d3773f748aefba7f7sf if (st->cache_file && st->cache_bytes > 0) {
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
e19d3a1e487aa73e0850658d3773f748aefba7f7sf /*
e19d3a1e487aa73e0850658d3773f748aefba7f7sf * initializing cache if we don't already have a shm address
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe */
e19d3a1e487aa73e0850658d3773f748aefba7f7sf if (!st->cache_shm) {
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes#endif
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes result = util_ldap_cache_init(p, st);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes if (result != APR_SUCCESS) {
185aa71728867671e105178b4c66fbc22b65ae26sf ap_log_error(APLOG_MARK, APLOG_ERR, result, s, APLOGNO(01315)
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;
185aa71728867671e105178b4c66fbc22b65ae26sf ap_log_error(APLOG_MARK, APLOG_DEBUG, result, s, APLOGNO(01316)
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 {
185aa71728867671e105178b4c66fbc22b65ae26sf ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(01317)
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe "LDAP cache: LDAPSharedCacheSize is zero, disabling "
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe "shared memory cache");
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes#endif
e8f95a682820a599fe41b22977010636be5c2717jim
e8f95a682820a599fe41b22977010636be5c2717jim /* log the LDAP SDK used
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes {
ab86c68ce36c715e93f403dde41d0b9c1522c8b0sf apr_ldap_err_t *result = NULL;
ab86c68ce36c715e93f403dde41d0b9c1522c8b0sf apr_ldap_info(p, &(result));
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes if (result != NULL) {
185aa71728867671e105178b4c66fbc22b65ae26sf ap_log_error(APLOG_MARK, APLOG_INFO, 0, s, APLOGNO(01318) "%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 */
ab86c68ce36c715e93f403dde41d0b9c1522c8b0sf rc = apr_ldap_ssl_init(p,
e8f95a682820a599fe41b22977010636be5c2717jim NULL,
e8f95a682820a599fe41b22977010636be5c2717jim 0,
d5cff0d8e871bf2528aadd8736fb50dc044b1e6dbnicholes &(result_err));
793214f67dede32edfd9ee96c664ead04d175cbbjfclere#if APR_HAS_MICROSOFT_LDAPSDK
793214f67dede32edfd9ee96c664ead04d175cbbjfclere /* MICROSOFT_LDAPSDK uses Microsoft Management Console (MMC) for that */
793214f67dede32edfd9ee96c664ead04d175cbbjfclere#else
54d22ed1c429b903b029bbd62621f11a9e286137minfrin if (APR_SUCCESS == rc) {
ab86c68ce36c715e93f403dde41d0b9c1522c8b0sf rc = apr_ldap_set_option(ptemp, NULL, APR_LDAP_OPT_TLS_CERT,
54d22ed1c429b903b029bbd62621f11a9e286137minfrin (void *)st->global_certs, &(result_err));
54d22ed1c429b903b029bbd62621f11a9e286137minfrin }
793214f67dede32edfd9ee96c664ead04d175cbbjfclere#endif
54d22ed1c429b903b029bbd62621f11a9e286137minfrin
54d22ed1c429b903b029bbd62621f11a9e286137minfrin if (APR_SUCCESS == rc) {
54d22ed1c429b903b029bbd62621f11a9e286137minfrin st->ssl_supported = 1;
185aa71728867671e105178b4c66fbc22b65ae26sf ap_log_error(APLOG_MARK, APLOG_INFO, 0, s, APLOGNO(01319)
e70cf415769ad0b3704e98b3f6da38e916ff7228jorton "LDAP: SSL support available" );
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes else {
54d22ed1c429b903b029bbd62621f11a9e286137minfrin st->ssl_supported = 0;
185aa71728867671e105178b4c66fbc22b65ae26sf ap_log_error(APLOG_MARK, APLOG_INFO, 0, s, APLOGNO(01320)
e70cf415769ad0b3704e98b3f6da38e916ff7228jorton "LDAP: SSL support unavailable%s%s",
e70cf415769ad0b3704e98b3f6da38e916ff7228jorton result_err ? ": " : "",
e70cf415769ad0b3704e98b3f6da38e916ff7228jorton result_err ? result_err->reason : "");
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
0894cd17fe3f614bf01dbf84f1414756bd5a34c3bnicholes
03944c8577b204701c849fce01f3fcb423a615f1covener /* ssl_supported is really a global setting */
03944c8577b204701c849fce01f3fcb423a615f1covener s_vhost = s->next;
03944c8577b204701c849fce01f3fcb423a615f1covener while (s_vhost) {
03944c8577b204701c849fce01f3fcb423a615f1covener st_vhost = (util_ldap_state_t *)
03944c8577b204701c849fce01f3fcb423a615f1covener ap_get_module_config(s_vhost->module_config,
03944c8577b204701c849fce01f3fcb423a615f1covener &ldap_module);
03944c8577b204701c849fce01f3fcb423a615f1covener
03944c8577b204701c849fce01f3fcb423a615f1covener st_vhost->ssl_supported = st->ssl_supported;
51e4795860b719286063728288bf0d8f49077185covener s_vhost = s_vhost->next;
03944c8577b204701c849fce01f3fcb423a615f1covener }
03944c8577b204701c849fce01f3fcb423a615f1covener
f7edd56768a46a01ae8b43c712c9eeef40e37f59bnicholes /* Initialize the rebind callback's cross reference list. */
ab86c68ce36c715e93f403dde41d0b9c1522c8b0sf apr_ldap_rebind_init (p);
f7edd56768a46a01ae8b43c712c9eeef40e37f59bnicholes
57e892abdf632bb9224c6ae6a715d863242a00f3fuankg#ifdef AP_LDAP_OPT_DEBUG
5bfaaf573bacb45c1cf290ce85ecc676587e8a64jim if (st->debug_level > 0) {
0f60998368b493f90120180a93fc2e1e74490872covener result = ldap_set_option(NULL, AP_LDAP_OPT_DEBUG, &st->debug_level);
0f60998368b493f90120180a93fc2e1e74490872covener if (result != LDAP_SUCCESS) {
185aa71728867671e105178b4c66fbc22b65ae26sf ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO(01321)
5bfaaf573bacb45c1cf290ce85ecc676587e8a64jim "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) {
185aa71728867671e105178b4c66fbc22b65ae26sf ap_log_error(APLOG_MARK, APLOG_CRIT, sts, s, APLOGNO(01322)
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 "
e19d3a1e487aa73e0850658d3773f748aefba7f7sf "0 to disable the shared memory cache. (default: 500000)"),
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 "
5bfaaf573bacb45c1cf290ce85ecc676587e8a64jim "LDAP search cache. Use 0 or -1 to disable the search cache "
023ab66b169a239c82d6c36410ab43fe63561d11covener "(default: 1024)"),
5bfaaf573bacb45c1cf290ce85ecc676587e8a64jim
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 "
5bfaaf573bacb45c1cf290ce85ecc676587e8a64jim "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
60284a9f9158baa60cc8ab4a69066404b1dcae7acovener AP_INIT_TAKE1("LDAPReferrals", util_ldap_set_chase_referrals,
9ad7b260be233be7d7b5576979825cac72e15498rederpj NULL, OR_AUTHCFG,
60284a9f9158baa60cc8ab4a69066404b1dcae7acovener "Choose whether referrals are chased ['ON'|'OFF'|'DEFAULT']. 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"),
a81c0c1ae464b2063a21b45f80c9da8d89bb840ecovener AP_INIT_TAKE1("LDAPConnectionPoolTTL", util_ldap_set_conn_ttl,
a81c0c1ae464b2063a21b45f80c9da8d89bb840ecovener NULL, RSRC_CONF,
a81c0c1ae464b2063a21b45f80c9da8d89bb840ecovener "Specify the maximum amount of time a bound connection can sit "
a81c0c1ae464b2063a21b45f80c9da8d89bb840ecovener "idle and still be considered valid for reuse"
a81c0c1ae464b2063a21b45f80c9da8d89bb840ecovener "(0 = no pool, -1 = no limit, n = time in seconds). Default: -1"),
60d81cab99dccfbb0c8d378cf6aa7338be0fdb74covener AP_INIT_TAKE1("LDAPRetries", util_ldap_set_retries,
60d81cab99dccfbb0c8d378cf6aa7338be0fdb74covener NULL, RSRC_CONF,
60d81cab99dccfbb0c8d378cf6aa7338be0fdb74covener "Specify the number of times a failed LDAP operation should be retried "
60d81cab99dccfbb0c8d378cf6aa7338be0fdb74covener "(0 = no retries). Default: 3"),
60d81cab99dccfbb0c8d378cf6aa7338be0fdb74covener AP_INIT_TAKE1("LDAPRetryDelay", util_ldap_set_retry_delay,
60d81cab99dccfbb0c8d378cf6aa7338be0fdb74covener NULL, RSRC_CONF,
60d81cab99dccfbb0c8d378cf6aa7338be0fdb74covener "Specify the delay between retries of a failed LDAP operation "
60d81cab99dccfbb0c8d378cf6aa7338be0fdb74covener "(0 = no delay). Default: 0"),
60d81cab99dccfbb0c8d378cf6aa7338be0fdb74covener
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_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};