util_ldap.c revision 11ca38a20ab9b2d00258f745620e2724838e7e21
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"
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes#include "util_ldap.h"
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes#include "util_ldap_cache.h"
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
5c0419d51818eb02045cf923a9fe456127a44c60wrowe#include <apr_strings.h>
5c0419d51818eb02045cf923a9fe456127a44c60wrowe
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes#if APR_HAVE_UNISTD_H
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes#include <unistd.h>
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes#endif
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes#if !APR_HAS_LDAP
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes#error mod_ldap requires APR-util to have LDAP support built in
d266c3777146d36a4c23c17aad6f153aebea1bf4jorton#endif
d266c3777146d36a4c23c17aad6f153aebea1bf4jorton
d266c3777146d36a4c23c17aad6f153aebea1bf4jorton#ifdef AP_NEED_SET_MUTEX_PERMS
d266c3777146d36a4c23c17aad6f153aebea1bf4jorton#include "unixd.h"
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes#endif
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
22f8da8087791fcb95b836c8a81937c5a9bba202bnicholes/* Default define for ldap functions that need a SIZELIMIT but
22f8da8087791fcb95b836c8a81937c5a9bba202bnicholes * do not have the define
22f8da8087791fcb95b836c8a81937c5a9bba202bnicholes * XXX This should be removed once a supporting #define is
22f8da8087791fcb95b836c8a81937c5a9bba202bnicholes * released through APR-Util.
22f8da8087791fcb95b836c8a81937c5a9bba202bnicholes */
22f8da8087791fcb95b836c8a81937c5a9bba202bnicholes#ifndef APR_LDAP_SIZELIMIT
22f8da8087791fcb95b836c8a81937c5a9bba202bnicholes#define APR_LDAP_SIZELIMIT -1
cd3bbd6d2df78d6c75e5d159a81ef8bdd5f70df9trawick#endif
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholesmodule AP_MODULE_DECLARE_DATA ldap_module;
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{
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe util_ldap_state_t *st = (util_ldap_state_t *)
e8f95a682820a599fe41b22977010636be5c2717jim ap_get_module_config(r->server->module_config,
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe &ldap_module);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes r->allowed |= (1 << M_GET);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes if (r->method_number != M_GET)
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes return DECLINED;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes if (strcmp(r->handler, "ldap-status")) {
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes return DECLINED;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
713a2b68bac4aeb1e9c48785006c0732451039depquerna ap_set_content_type(r, "text/html");
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
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes/*
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * Closes an LDAP connection by unlocking it. The next time
f43b67c5a9d29b572eac916f8335cedc80c908bebnicholes * uldap_connection_find() is called this connection will be
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * available for reuse.
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes */
8113dac419143273351446c3ad653f3fe5ba5cfdwrowestatic void uldap_connection_close(util_ldap_connection_t *ldc)
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes{
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes /*
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * QUESTION:
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes *
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * Is it safe leaving bound connections floating around between the
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * different modules? Keeping the user bound is a performance boost,
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * but it is also a potential security problem - maybe.
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes *
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * For now we unbind the user when we finish with a connection, but
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * we don't have to...
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes /* mark our connection as available for reuse */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes#if APR_HAS_THREADS
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes apr_thread_mutex_unlock(ldc->lock);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes#endif
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
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * state after an error, and during pool cleanup.
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes */
8113dac419143273351446c3ad653f3fe5ba5cfdwrowestatic apr_status_t uldap_connection_unbind(void *param)
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes{
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes util_ldap_connection_t *ldc = param;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes if (ldc) {
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes if (ldc->ldap) {
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes ldap_unbind_s(ldc->ldap);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes ldc->ldap = NULL;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes ldc->bound = 0;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes return APR_SUCCESS;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes}
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes/*
1f299703465bd9975d94e9f229f76af807442de2covener * Clean up an LDAP connection by unbinding and unlocking the connection.
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes */
8113dac419143273351446c3ad653f3fe5ba5cfdwrowestatic apr_status_t uldap_connection_cleanup(void *param)
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes{
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes util_ldap_connection_t *ldc = param;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes if (ldc) {
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes /* unbind and disconnect from the LDAP server */
f43b67c5a9d29b572eac916f8335cedc80c908bebnicholes uldap_connection_unbind(ldc);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes /* free the username and password */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes if (ldc->bindpw) {
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes free((void*)ldc->bindpw);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes if (ldc->binddn) {
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes free((void*)ldc->binddn);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes /* unlock this entry */
f43b67c5a9d29b572eac916f8335cedc80c908bebnicholes uldap_connection_close(ldc);
e8f95a682820a599fe41b22977010636be5c2717jim
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes return APR_SUCCESS;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes}
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholesstatic int uldap_connection_init(request_rec *r,
68d5e906a21c3abe1ebd0da30d2f0e8e4c2ad28cjim util_ldap_connection_t *ldc )
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes{
b08925593f214f621161742925dcf074a8047e0acovener int rc = 0, ldap_option = 0;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes int version = LDAP_VERSION3;
54d22ed1c429b903b029bbd62621f11a9e286137minfrin apr_ldap_err_t *result = NULL;
3dfeb02cfb853d8717ca0cc259b59fea610173f5bnicholes struct timeval timeOut = {10,0}; /* 10 second connection timeout */
e8f95a682820a599fe41b22977010636be5c2717jim util_ldap_state_t *st =
3dfeb02cfb853d8717ca0cc259b59fea610173f5bnicholes (util_ldap_state_t *)ap_get_module_config(r->server->module_config,
3dfeb02cfb853d8717ca0cc259b59fea610173f5bnicholes &ldap_module);
54d22ed1c429b903b029bbd62621f11a9e286137minfrin
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes /* Since the host will include a port if the default port is not used,
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes * always specify the default ports for the port parameter. This will
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes * allow a host string that contains multiple hosts the ability to mix
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes * some hosts with ports and some without. All hosts which do not
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes * specify a port will use the default port.
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes */
ebe5305f8b22507374358f32b74d12fb50c05a25covener apr_ldap_init(r->pool, &(ldc->ldap),
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes ldc->host,
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes APR_LDAP_SSL == ldc->secure ? LDAPS_PORT : LDAP_PORT,
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes APR_LDAP_NONE,
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes &(result));
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes if (result != NULL && result->rc) {
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes ldc->reason = result->reason;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes if (NULL == ldc->ldap)
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes {
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes ldc->bound = 0;
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes if (NULL == ldc->reason) {
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes ldc->reason = "LDAP: ldap initialization failed";
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes }
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes else {
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes ldc->reason = result->reason;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes return(result->rc);
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes /* always default to LDAP V3 */
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes ldap_set_option(ldc->ldap, LDAP_OPT_PROTOCOL_VERSION, &version);
54d22ed1c429b903b029bbd62621f11a9e286137minfrin
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes /* set client certificates */
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes if (!apr_is_empty_array(ldc->client_certs)) {
ebe5305f8b22507374358f32b74d12fb50c05a25covener apr_ldap_set_option(r->pool, ldc->ldap, APR_LDAP_OPT_TLS_CERT,
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes ldc->client_certs, &(result));
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes if (LDAP_SUCCESS != result->rc) {
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes uldap_connection_unbind( ldc );
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes ldc->reason = result->reason;
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes return(result->rc);
54d22ed1c429b903b029bbd62621f11a9e286137minfrin }
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes }
54d22ed1c429b903b029bbd62621f11a9e286137minfrin
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes /* switch on SSL/TLS */
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes if (APR_LDAP_NONE != ldc->secure) {
ebe5305f8b22507374358f32b74d12fb50c05a25covener apr_ldap_set_option(r->pool, ldc->ldap,
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes APR_LDAP_OPT_TLS, &ldc->secure, &(result));
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes if (LDAP_SUCCESS != result->rc) {
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes uldap_connection_unbind( ldc );
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes ldc->reason = result->reason;
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes return(result->rc);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes /* Set the alias dereferencing option */
b08925593f214f621161742925dcf074a8047e0acovener ldap_option = ldc->deref;
b08925593f214f621161742925dcf074a8047e0acovener ldap_set_option(ldc->ldap, LDAP_OPT_DEREF, &ldap_option);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
7add8f7fb048534390571801b7794f71cd9e127abnicholes/*XXX All of the #ifdef's need to be removed once apr-util 1.2 is released */
7add8f7fb048534390571801b7794f71cd9e127abnicholes#ifdef APR_LDAP_OPT_VERIFY_CERT
ebe5305f8b22507374358f32b74d12fb50c05a25covener apr_ldap_set_option(r->pool, ldc->ldap,
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes APR_LDAP_OPT_VERIFY_CERT, &(st->verify_svr_cert), &(result));
7add8f7fb048534390571801b7794f71cd9e127abnicholes#else
7add8f7fb048534390571801b7794f71cd9e127abnicholes#if defined(LDAPSSL_VERIFY_SERVER)
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes if (st->verify_svr_cert) {
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes result->rc = ldapssl_set_verify_mode(LDAPSSL_VERIFY_SERVER);
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes }
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes else {
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes result->rc = ldapssl_set_verify_mode(LDAPSSL_VERIFY_NONE);
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes }
7add8f7fb048534390571801b7794f71cd9e127abnicholes#elif defined(LDAP_OPT_X_TLS_REQUIRE_CERT)
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes /* This is not a per-connection setting so just pass NULL for the
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes Ldap connection handle */
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes if (st->verify_svr_cert) {
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes int i = LDAP_OPT_X_TLS_DEMAND;
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes result->rc = ldap_set_option(NULL, LDAP_OPT_X_TLS_REQUIRE_CERT, &i);
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes }
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes else {
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes int i = LDAP_OPT_X_TLS_NEVER;
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes result->rc = ldap_set_option(NULL, LDAP_OPT_X_TLS_REQUIRE_CERT, &i);
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes }
7add8f7fb048534390571801b7794f71cd9e127abnicholes#endif
7add8f7fb048534390571801b7794f71cd9e127abnicholes#endif
141e1368614dc7564e1627671361b01b4869b491bnicholes
3dfeb02cfb853d8717ca0cc259b59fea610173f5bnicholes#ifdef LDAP_OPT_NETWORK_TIMEOUT
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes if (st->connectionTimeout > 0) {
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes timeOut.tv_sec = st->connectionTimeout;
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes }
e8f95a682820a599fe41b22977010636be5c2717jim
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes if (st->connectionTimeout >= 0) {
ebe5305f8b22507374358f32b74d12fb50c05a25covener rc = apr_ldap_set_option(r->pool, ldc->ldap, LDAP_OPT_NETWORK_TIMEOUT,
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes (void *)&timeOut, &(result));
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes if (APR_SUCCESS != rc) {
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server,
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes "LDAP: Could not set the connection timeout");
3dfeb02cfb853d8717ca0cc259b59fea610173f5bnicholes }
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes }
3dfeb02cfb853d8717ca0cc259b59fea610173f5bnicholes#endif
3dfeb02cfb853d8717ca0cc259b59fea610173f5bnicholes
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes return(rc);
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes}
e8f95a682820a599fe41b22977010636be5c2717jim
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;
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes /* sanity check for NULL */
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes if (!ldc) {
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes return -1;
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes }
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes /* If the connection is already bound, return
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes */
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes if (ldc->bound)
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes {
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes ldc->reason = "LDAP: connection open successful (already bound)";
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes return LDAP_SUCCESS;
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes }
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes /* create the ldap session handle
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes */
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes if (NULL == ldc->ldap)
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes {
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes rc = uldap_connection_init( r, ldc );
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes if (LDAP_SUCCESS != rc)
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes {
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes return rc;
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes /* loop trying to bind up to 10 times if LDAP_SERVER_DOWN error is
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * returned. Break out of the loop on Success or any other error.
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.
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes for (failures=0; failures<10; failures++)
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes {
54d22ed1c429b903b029bbd62621f11a9e286137minfrin rc = ldap_simple_bind_s(ldc->ldap,
54d22ed1c429b903b029bbd62621f11a9e286137minfrin (char *)ldc->binddn,
54d22ed1c429b903b029bbd62621f11a9e286137minfrin (char *)ldc->bindpw);
54d22ed1c429b903b029bbd62621f11a9e286137minfrin if (LDAP_SERVER_DOWN != rc) {
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes break;
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes } else if (failures == 5) {
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes /* attempt to init the connection once again */
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes uldap_connection_unbind( ldc );
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes rc = uldap_connection_init( r, ldc );
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes if (LDAP_SUCCESS != rc)
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes {
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes break;
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes }
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes /* free the handle if there was an error
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes */
54d22ed1c429b903b029bbd62621f11a9e286137minfrin if (LDAP_SUCCESS != rc)
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes {
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes uldap_connection_unbind(ldc);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes ldc->reason = "LDAP: ldap_simple_bind_s() failed";
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes else {
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes ldc->bound = 1;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes ldc->reason = "LDAP: connection open successful";
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
54d22ed1c429b903b029bbd62621f11a9e286137minfrin return(rc);
54d22ed1c429b903b029bbd62621f11a9e286137minfrin}
54d22ed1c429b903b029bbd62621f11a9e286137minfrin
54d22ed1c429b903b029bbd62621f11a9e286137minfrin
54d22ed1c429b903b029bbd62621f11a9e286137minfrin/*
54d22ed1c429b903b029bbd62621f11a9e286137minfrin * Compare client certificate arrays.
54d22ed1c429b903b029bbd62621f11a9e286137minfrin *
54d22ed1c429b903b029bbd62621f11a9e286137minfrin * Returns 1 on compare failure, 0 otherwise.
54d22ed1c429b903b029bbd62621f11a9e286137minfrin */
e8f95a682820a599fe41b22977010636be5c2717jimstatic int compare_client_certs(apr_array_header_t *srcs,
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe apr_array_header_t *dests)
8a03cd420b800a2428f49f4617293de9b2387b20jorton{
54d22ed1c429b903b029bbd62621f11a9e286137minfrin int i = 0;
54d22ed1c429b903b029bbd62621f11a9e286137minfrin struct apr_ldap_opt_tls_cert_t *src, *dest;
54d22ed1c429b903b029bbd62621f11a9e286137minfrin
54d22ed1c429b903b029bbd62621f11a9e286137minfrin /* arrays both NULL? if so, then equal */
54d22ed1c429b903b029bbd62621f11a9e286137minfrin if (srcs == NULL && dests == NULL) {
54d22ed1c429b903b029bbd62621f11a9e286137minfrin return 0;
54d22ed1c429b903b029bbd62621f11a9e286137minfrin }
54d22ed1c429b903b029bbd62621f11a9e286137minfrin
54d22ed1c429b903b029bbd62621f11a9e286137minfrin /* arrays different length or either NULL? If so, then not equal */
54d22ed1c429b903b029bbd62621f11a9e286137minfrin if (srcs == NULL || dests == NULL || srcs->nelts != dests->nelts) {
54d22ed1c429b903b029bbd62621f11a9e286137minfrin return 1;
54d22ed1c429b903b029bbd62621f11a9e286137minfrin }
54d22ed1c429b903b029bbd62621f11a9e286137minfrin
54d22ed1c429b903b029bbd62621f11a9e286137minfrin /* run an actual comparison */
54d22ed1c429b903b029bbd62621f11a9e286137minfrin src = (struct apr_ldap_opt_tls_cert_t *)srcs->elts;
54d22ed1c429b903b029bbd62621f11a9e286137minfrin dest = (struct apr_ldap_opt_tls_cert_t *)dests->elts;
54d22ed1c429b903b029bbd62621f11a9e286137minfrin for (i = 0; i < srcs->nelts; i++) {
edc346c3223efd41e6a2057c37cea69744b73dccwrowe if (strcmp(src[i].path, dest[i].path) ||
edc346c3223efd41e6a2057c37cea69744b73dccwrowe strcmp(src[i].password, dest[i].password) ||
54d22ed1c429b903b029bbd62621f11a9e286137minfrin src[i].type != dest[i].type) {
54d22ed1c429b903b029bbd62621f11a9e286137minfrin return 1;
54d22ed1c429b903b029bbd62621f11a9e286137minfrin }
54d22ed1c429b903b029bbd62621f11a9e286137minfrin }
54d22ed1c429b903b029bbd62621f11a9e286137minfrin
54d22ed1c429b903b029bbd62621f11a9e286137minfrin /* if we got here, the cert arrays were identical */
54d22ed1c429b903b029bbd62621f11a9e286137minfrin return 0;
54d22ed1c429b903b029bbd62621f11a9e286137minfrin
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes}
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes/*
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * Find an existing ldap connection struct that matches the
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * provided ldap connection parameters.
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes *
e8f95a682820a599fe41b22977010636be5c2717jim * If not found in the cache, a new ldc structure will be allocated
e8f95a682820a599fe41b22977010636be5c2717jim * from st->pool and returned to the caller. If found in the cache,
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe * a pointer to the existing ldc structure will be returned.
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes */
e8f95a682820a599fe41b22977010636be5c2717jimstatic util_ldap_connection_t *
8113dac419143273351446c3ad653f3fe5ba5cfdwrowe uldap_connection_find(request_rec *r,
8113dac419143273351446c3ad653f3fe5ba5cfdwrowe const char *host, int port,
8113dac419143273351446c3ad653f3fe5ba5cfdwrowe const char *binddn, const char *bindpw,
f0f6f1b90ab582896f8a7d56d85bd62a55e57d90covener deref_options deref, int secure)
8113dac419143273351446c3ad653f3fe5ba5cfdwrowe{
54d22ed1c429b903b029bbd62621f11a9e286137minfrin struct util_ldap_connection_t *l, *p; /* To traverse the linked list */
560fd0658902ab57754616c172d8953e69fc4722bnicholes int secureflag = secure;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
e8f95a682820a599fe41b22977010636be5c2717jim util_ldap_state_t *st =
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes (util_ldap_state_t *)ap_get_module_config(r->server->module_config,
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes &ldap_module);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes#if APR_HAS_THREADS
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes /* mutex lock this function */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes apr_thread_mutex_lock(st->mutex);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes#endif
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
560fd0658902ab57754616c172d8953e69fc4722bnicholes if (secure < APR_LDAP_NONE) {
560fd0658902ab57754616c172d8953e69fc4722bnicholes secureflag = st->secure;
560fd0658902ab57754616c172d8953e69fc4722bnicholes }
560fd0658902ab57754616c172d8953e69fc4722bnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes /* Search for an exact connection match in the list that is not
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * being used.
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes for (l=st->connections,p=NULL; l; l=l->next) {
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes#if APR_HAS_THREADS
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes if (APR_SUCCESS == apr_thread_mutex_trylock(l->lock)) {
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes#endif
e8f95a682820a599fe41b22977010636be5c2717jim if ( (l->port == port) && (strcmp(l->host, host) == 0)
e8f95a682820a599fe41b22977010636be5c2717jim && ((!l->binddn && !binddn) || (l->binddn && binddn
e8f95a682820a599fe41b22977010636be5c2717jim && !strcmp(l->binddn, binddn)))
e8f95a682820a599fe41b22977010636be5c2717jim && ((!l->bindpw && !bindpw) || (l->bindpw && bindpw
e8f95a682820a599fe41b22977010636be5c2717jim && !strcmp(l->bindpw, bindpw)))
e8f95a682820a599fe41b22977010636be5c2717jim && (l->deref == deref) && (l->secure == secureflag)
e8f95a682820a599fe41b22977010636be5c2717jim && !compare_client_certs(st->client_certs, l->client_certs))
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe {
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes break;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes#if APR_HAS_THREADS
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes /* If this connection didn't match the criteria, then we
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * need to unlock the mutex so it is available to be reused.
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes apr_thread_mutex_unlock(l->lock);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes#endif
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes p = l;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes /* If nothing found, search again, but we don't care about the
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * binddn and bindpw this time.
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes if (!l) {
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes for (l=st->connections,p=NULL; l; l=l->next) {
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes#if APR_HAS_THREADS
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes if (APR_SUCCESS == apr_thread_mutex_trylock(l->lock)) {
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes#endif
e8f95a682820a599fe41b22977010636be5c2717jim if ((l->port == port) && (strcmp(l->host, host) == 0) &&
560fd0658902ab57754616c172d8953e69fc4722bnicholes (l->deref == deref) && (l->secure == secureflag) &&
e8f95a682820a599fe41b22977010636be5c2717jim !compare_client_certs(st->client_certs, l->client_certs))
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe {
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes /* the bind credentials have changed */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes l->bound = 0;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes util_ldap_strdup((char**)&(l->binddn), binddn);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes util_ldap_strdup((char**)&(l->bindpw), bindpw);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes break;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes#if APR_HAS_THREADS
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes /* If this connection didn't match the criteria, then we
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * need to unlock the mutex so it is available to be reused.
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes apr_thread_mutex_unlock(l->lock);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes#endif
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes p = l;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes/* artificially disable cache */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes/* l = NULL; */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes /* If no connection what found after the second search, we
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * must create one.
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes if (!l) {
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
e8f95a682820a599fe41b22977010636be5c2717jim /*
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * Add the new connection entry to the linked list. Note that we
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * don't actually establish an LDAP connection yet; that happens
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * the first time authentication is requested.
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes /* create the details to the pool in st */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes l = apr_pcalloc(st->pool, sizeof(util_ldap_connection_t));
ebe5305f8b22507374358f32b74d12fb50c05a25covener if (apr_pool_create(&l->pool, st->pool) != APR_SUCCESS) {
ebe5305f8b22507374358f32b74d12fb50c05a25covener ap_log_rerror(APLOG_MARK, APLOG_CRIT, 0, r,
ebe5305f8b22507374358f32b74d12fb50c05a25covener "util_ldap: Failed to create memory pool");
ebe5305f8b22507374358f32b74d12fb50c05a25covener#if APR_HAS_THREADS
ebe5305f8b22507374358f32b74d12fb50c05a25covener apr_thread_mutex_unlock(st->mutex);
ebe5305f8b22507374358f32b74d12fb50c05a25covener#endif
ebe5305f8b22507374358f32b74d12fb50c05a25covener return NULL;
ebe5305f8b22507374358f32b74d12fb50c05a25covener
ebe5305f8b22507374358f32b74d12fb50c05a25covener }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes#if APR_HAS_THREADS
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes apr_thread_mutex_create(&l->lock, APR_THREAD_MUTEX_DEFAULT, st->pool);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes apr_thread_mutex_lock(l->lock);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes#endif
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes l->bound = 0;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes l->host = apr_pstrdup(st->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);
54d22ed1c429b903b029bbd62621f11a9e286137minfrin
54d22ed1c429b903b029bbd62621f11a9e286137minfrin /* The security mode after parsing the URL will always be either
54d22ed1c429b903b029bbd62621f11a9e286137minfrin * APR_LDAP_NONE (ldap://) or APR_LDAP_SSL (ldaps://).
54d22ed1c429b903b029bbd62621f11a9e286137minfrin * If the security setting is NONE, override it to the security
54d22ed1c429b903b029bbd62621f11a9e286137minfrin * setting optionally supplied by the admin using LDAPTrustedMode
54d22ed1c429b903b029bbd62621f11a9e286137minfrin */
560fd0658902ab57754616c172d8953e69fc4722bnicholes l->secure = secureflag;
54d22ed1c429b903b029bbd62621f11a9e286137minfrin
54d22ed1c429b903b029bbd62621f11a9e286137minfrin /* save away a copy of the client cert list that is presently valid */
54d22ed1c429b903b029bbd62621f11a9e286137minfrin l->client_certs = apr_array_copy_hdr(l->pool, st->client_certs);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes if (p) {
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes p->next = l;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes else {
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes st->connections = l;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes#if APR_HAS_THREADS
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes apr_thread_mutex_unlock(st->mutex);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes#endif
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes return l;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes}
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes/* ------------------------------------------------------------------ */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes/*
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe * Compares two DNs to see if they're equal. The only way to do this correctly
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe * is to search for the dn and then do ldap_get_dn() on the result. This should
e8f95a682820a599fe41b22977010636be5c2717jim * match the initial dn, since it would have been also retrieved with
e8f95a682820a599fe41b22977010636be5c2717jim * ldap_get_dn(). This is expensive, so if the configuration value
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe * compare_dn_on_server is false, just does an ordinary strcmp.
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes *
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * The lock for the ldap cache should already be acquired.
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes */
e8f95a682820a599fe41b22977010636be5c2717jimstatic int uldap_cache_comparedn(request_rec *r, util_ldap_connection_t *ldc,
e8f95a682820a599fe41b22977010636be5c2717jim const char *url, const char *dn,
8113dac419143273351446c3ad653f3fe5ba5cfdwrowe const char *reqdn, int compare_dn_on_server)
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes{
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes int result = 0;
e8f95a682820a599fe41b22977010636be5c2717jim util_url_node_t *curl;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes util_url_node_t curnode;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes util_dn_compare_node_t *node;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes util_dn_compare_node_t newnode;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes int failures = 0;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes LDAPMessage *res, *entry;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes char *searchdn;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe util_ldap_state_t *st = (util_ldap_state_t *)
e8f95a682820a599fe41b22977010636be5c2717jim ap_get_module_config(r->server->module_config,
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe &ldap_module);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes /* get cache entry (or create one) */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes LDAP_CACHE_LOCK();
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes curnode.url = url;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes curl = util_ald_cache_fetch(st->util_ldap_cache, &curnode);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes if (curl == NULL) {
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes curl = util_ald_create_caches(st, url);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes LDAP_CACHE_UNLOCK();
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes /* a simple compare? */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes if (!compare_dn_on_server) {
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes /* unlock this read lock */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes if (strcmp(dn, reqdn)) {
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes ldc->reason = "DN Comparison FALSE (direct strcmp())";
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes return LDAP_COMPARE_FALSE;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes else {
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes ldc->reason = "DN Comparison TRUE (direct strcmp())";
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes return LDAP_COMPARE_TRUE;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes if (curl) {
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes /* no - it's a server side compare */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes LDAP_CACHE_LOCK();
e8f95a682820a599fe41b22977010636be5c2717jim
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes /* is it in the compare cache? */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes newnode.reqdn = (char *)reqdn;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes node = util_ald_cache_fetch(curl->dn_compare_cache, &newnode);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes if (node != NULL) {
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes /* If it's in the cache, it's good */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes /* unlock this read lock */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes LDAP_CACHE_UNLOCK();
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes ldc->reason = "DN Comparison TRUE (cached)";
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes return LDAP_COMPARE_TRUE;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
e8f95a682820a599fe41b22977010636be5c2717jim
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes /* unlock this read lock */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes LDAP_CACHE_UNLOCK();
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholesstart_over:
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes if (failures++ > 10) {
43c3e6a4b559b76b750c245ee95e2782c15b4296jim /* too many failures */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes return result;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes /* make a server connection */
f43b67c5a9d29b572eac916f8335cedc80c908bebnicholes if (LDAP_SUCCESS != (result = uldap_connection_open(r, ldc))) {
43c3e6a4b559b76b750c245ee95e2782c15b4296jim /* connect to server failed */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes return result;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes /* search for reqdn */
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe if ((result = ldap_search_ext_s(ldc->ldap, (char *)reqdn, LDAP_SCOPE_BASE,
e8f95a682820a599fe41b22977010636be5c2717jim "(objectclass=*)", NULL, 1,
22f8da8087791fcb95b836c8a81937c5a9bba202bnicholes NULL, NULL, NULL, APR_LDAP_SIZELIMIT, &res))
e8f95a682820a599fe41b22977010636be5c2717jim == LDAP_SERVER_DOWN)
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe {
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe ldc->reason = "DN Comparison ldap_search_ext_s() "
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe "failed with server down";
f43b67c5a9d29b572eac916f8335cedc80c908bebnicholes uldap_connection_unbind(ldc);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes goto start_over;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes if (result != LDAP_SUCCESS) {
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes /* search for reqdn failed - no match */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes ldc->reason = "DN Comparison ldap_search_ext_s() failed";
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes return result;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes entry = ldap_first_entry(ldc->ldap, res);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes searchdn = ldap_get_dn(ldc->ldap, entry);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes ldap_msgfree(res);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes if (strcmp(dn, searchdn) != 0) {
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes /* compare unsuccessful */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes ldc->reason = "DN Comparison FALSE (checked on server)";
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes result = LDAP_COMPARE_FALSE;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes else {
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes if (curl) {
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes /* compare successful - add to the compare cache */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes LDAP_CACHE_LOCK();
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes newnode.reqdn = (char *)reqdn;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes newnode.dn = (char *)dn;
e8f95a682820a599fe41b22977010636be5c2717jim
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes node = util_ald_cache_fetch(curl->dn_compare_cache, &newnode);
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe if ( (node == NULL)
e8f95a682820a599fe41b22977010636be5c2717jim || (strcmp(reqdn, node->reqdn) != 0)
e8f95a682820a599fe41b22977010636be5c2717jim || (strcmp(dn, node->dn) != 0))
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe {
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes util_ald_cache_insert(curl->dn_compare_cache, &newnode);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes LDAP_CACHE_UNLOCK();
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes ldc->reason = "DN Comparison TRUE (checked on server)";
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes result = LDAP_COMPARE_TRUE;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes ldap_memfree(searchdn);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes return result;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes}
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes/*
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * Does an generic ldap_compare operation. It accepts a cache that it will use
e8f95a682820a599fe41b22977010636be5c2717jim * to lookup the compare in the cache. We cache two kinds of compares
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * (require group compares) and (require user compares). Each compare has a different
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * cache node: require group includes the DN; require user does not because the
e8f95a682820a599fe41b22977010636be5c2717jim * require user cache is owned by the
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes *
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes */
8113dac419143273351446c3ad653f3fe5ba5cfdwrowestatic int uldap_cache_compare(request_rec *r, util_ldap_connection_t *ldc,
8113dac419143273351446c3ad653f3fe5ba5cfdwrowe const char *url, const char *dn,
8113dac419143273351446c3ad653f3fe5ba5cfdwrowe const char *attrib, const char *value)
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes{
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes int result = 0;
e8f95a682820a599fe41b22977010636be5c2717jim util_url_node_t *curl;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes util_url_node_t curnode;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes util_compare_node_t *compare_nodep;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes util_compare_node_t the_compare_node;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes apr_time_t curtime = 0; /* silence gcc -Wall */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes int failures = 0;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe util_ldap_state_t *st = (util_ldap_state_t *)
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe ap_get_module_config(r->server->module_config,
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe &ldap_module);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes /* get cache entry (or create one) */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes LDAP_CACHE_LOCK();
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes curnode.url = url;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes curl = util_ald_cache_fetch(st->util_ldap_cache, &curnode);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes if (curl == NULL) {
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes curl = util_ald_create_caches(st, url);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes LDAP_CACHE_UNLOCK();
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes if (curl) {
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes /* make a comparison to the cache */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes LDAP_CACHE_LOCK();
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes curtime = apr_time_now();
e8f95a682820a599fe41b22977010636be5c2717jim
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes the_compare_node.dn = (char *)dn;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes the_compare_node.attrib = (char *)attrib;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes the_compare_node.value = (char *)value;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes the_compare_node.result = 0;
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj the_compare_node.sgl_processed = 0;
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj the_compare_node.subgroupList = NULL;
e8f95a682820a599fe41b22977010636be5c2717jim
e8f95a682820a599fe41b22977010636be5c2717jim compare_nodep = util_ald_cache_fetch(curl->compare_cache,
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe &the_compare_node);
e8f95a682820a599fe41b22977010636be5c2717jim
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes if (compare_nodep != NULL) {
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes /* found it... */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes if (curtime - compare_nodep->lastcompare > st->compare_cache_ttl) {
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes /* ...but it is too old */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes util_ald_cache_remove(curl->compare_cache, compare_nodep);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes else {
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes /* ...and it is good */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes if (LDAP_COMPARE_TRUE == compare_nodep->result) {
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes ldc->reason = "Comparison true (cached)";
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes else if (LDAP_COMPARE_FALSE == compare_nodep->result) {
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes ldc->reason = "Comparison false (cached)";
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes else if (LDAP_NO_SUCH_ATTRIBUTE == compare_nodep->result) {
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes ldc->reason = "Comparison no such attribute (cached)";
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes else {
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes ldc->reason = "Comparison undefined (cached)";
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj /* record the result code to return with the reason... */
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj result = compare_nodep->result;
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj /* and unlock this read lock */
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj LDAP_CACHE_UNLOCK();
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj return result;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes /* unlock this read lock */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes LDAP_CACHE_UNLOCK();
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholesstart_over:
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes if (failures++ > 10) {
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes /* too many failures */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes return result;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj
f43b67c5a9d29b572eac916f8335cedc80c908bebnicholes if (LDAP_SUCCESS != (result = uldap_connection_open(r, ldc))) {
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes /* connect failed */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes return result;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
bb07ee33bce1a448bcc60ca43720b1ab1c413f87minfrin if ((result = ldap_compare_s(ldc->ldap,
bb07ee33bce1a448bcc60ca43720b1ab1c413f87minfrin (char *)dn,
bb07ee33bce1a448bcc60ca43720b1ab1c413f87minfrin (char *)attrib,
bb07ee33bce1a448bcc60ca43720b1ab1c413f87minfrin (char *)value))
e8f95a682820a599fe41b22977010636be5c2717jim == LDAP_SERVER_DOWN) {
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes /* connection failed - try again */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes ldc->reason = "ldap_compare_s() failed with server down";
f43b67c5a9d29b572eac916f8335cedc80c908bebnicholes uldap_connection_unbind(ldc);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes goto start_over;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes ldc->reason = "Comparison complete";
e8f95a682820a599fe41b22977010636be5c2717jim if ((LDAP_COMPARE_TRUE == result) ||
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes (LDAP_COMPARE_FALSE == result) ||
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes (LDAP_NO_SUCH_ATTRIBUTE == result)) {
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes if (curl) {
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes /* compare completed; caching result */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes LDAP_CACHE_LOCK();
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes the_compare_node.lastcompare = curtime;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes the_compare_node.result = result;
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj the_compare_node.sgl_processed = 0;
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj the_compare_node.subgroupList = NULL;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe /* If the node doesn't exist then insert it, otherwise just update
e8f95a682820a599fe41b22977010636be5c2717jim * it with the last results
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe */
e8f95a682820a599fe41b22977010636be5c2717jim compare_nodep = util_ald_cache_fetch(curl->compare_cache,
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe &the_compare_node);
e8f95a682820a599fe41b22977010636be5c2717jim if ( (compare_nodep == NULL)
e8f95a682820a599fe41b22977010636be5c2717jim || (strcmp(the_compare_node.dn, compare_nodep->dn) != 0)
e8f95a682820a599fe41b22977010636be5c2717jim || (strcmp(the_compare_node.attrib,compare_nodep->attrib) != 0)
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe || (strcmp(the_compare_node.value, compare_nodep->value) != 0))
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe {
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj void *junk;
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj junk = util_ald_cache_insert(curl->compare_cache, &the_compare_node);
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj if(junk == NULL) {
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, "[%" APR_PID_T_FMT "] cache_compare: Cache insertion failure.", getpid());
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
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj/*
11ca38a20ab9b2d00258f745620e2724838e7e21rederpj * Does a recursive lookup operation to try to find a user within (cached) nested
11ca38a20ab9b2d00258f745620e2724838e7e21rederpj * groups. It accepts a cache that it will use to lookup previous compare attempts.
11ca38a20ab9b2d00258f745620e2724838e7e21rederpj * We cache two kinds of compares (require group compares) and (require user
11ca38a20ab9b2d00258f745620e2724838e7e21rederpj * compares). Each compare has a different cache node: require group includes the DN;
11ca38a20ab9b2d00258f745620e2724838e7e21rederpj * require user does not because the require user cache is owned by the
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj *
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj * DON'T CALL THIS UNLESS YOU CALLED uldap_cache_compare FIRST!!!!!
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj */
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj /*
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj * 1. Call uldap_cache_compare for each subgroupclass value to check the generic,
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj * user-agnostic, cached group entry. This will create a new generic cache entry if there
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj * wasn't one. If nothing returns LDAP_COMPARE_TRUE skip to step 5 since we have no groups.
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj * 2. Lock The cache and get the generic cache entry.
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj * 3. Check if there is already a subgrouplist in this generic group's cache entry.
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj * A. If there is, go to step 4.
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj * B. If there isn't:
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj * i) Use ldap_search to get the full list
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj * of subgroup "members" (which may include non-group "members").
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj * ii) Use uldap_cache_compare to strip the list down to just groups.
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj * iii) Lock and add this stripped down list to the cache of the generic group.
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj * 4. Loop through the sgl and call uldap_cache_compare (using the user info) for each
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj * subgroup to see if the subgroup contains the user and to get the subgroups added to the
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj * cache (with user-afinity, if they aren't already there).
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj * A. If the user is in the subgroup, then we'll be returning LDAP_COMPARE_TRUE.
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj * B. if the user isn't in the subgroup (LDAP_COMPARE_FALSE via uldap_cache_compare) then
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj * recursively call this function to get the sub-subgroups added...
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj * 5. Cleanup local allocations.
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj * 6. Return the final result.
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj */
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj
11ca38a20ab9b2d00258f745620e2724838e7e21rederpjstatic int uldap_cache_check_subgroups(request_rec *r, util_ldap_connection_t *ldc,
11ca38a20ab9b2d00258f745620e2724838e7e21rederpj const char *url, const char *dn,
11ca38a20ab9b2d00258f745620e2724838e7e21rederpj const char *attrib, const char *value,
11ca38a20ab9b2d00258f745620e2724838e7e21rederpj char **subgroupAttrs, apr_array_header_t *subgroupclasses,
11ca38a20ab9b2d00258f745620e2724838e7e21rederpj int cur_subgroup_depth, 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;
11ca38a20ab9b2d00258f745620e2724838e7e21rederpj int failures = 0;
11ca38a20ab9b2d00258f745620e2724838e7e21rederpj LDAPMessage *sga_res, *entry;
11ca38a20ab9b2d00258f745620e2724838e7e21rederpj apr_array_header_t *subgroups = apr_array_make(r->pool, 20, sizeof(char *));
11ca38a20ab9b2d00258f745620e2724838e7e21rederpj
11ca38a20ab9b2d00258f745620e2724838e7e21rederpj util_ldap_state_t *st = (util_ldap_state_t *)
11ca38a20ab9b2d00258f745620e2724838e7e21rederpj ap_get_module_config(r->server->module_config,
11ca38a20ab9b2d00258f745620e2724838e7e21rederpj &ldap_module);
11ca38a20ab9b2d00258f745620e2724838e7e21rederpj
11ca38a20ab9b2d00258f745620e2724838e7e21rederpj /* Stop looking at deeper levels of nested groups if we have reached the max.
11ca38a20ab9b2d00258f745620e2724838e7e21rederpj * Since we already checked the top-level group in uldap_cache_compare, we don't
11ca38a20ab9b2d00258f745620e2724838e7e21rederpj * need to check it again here - so if max_subgroup_depth is set to 0, we won't
11ca38a20ab9b2d00258f745620e2724838e7e21rederpj * check it (i.e. that is why we check < rather than <=).
11ca38a20ab9b2d00258f745620e2724838e7e21rederpj * We'll be calling uldap_cache_compare from here to check if the user is in the
11ca38a20ab9b2d00258f745620e2724838e7e21rederpj * next level before we recurse into that next level looking for more subgroups.
11ca38a20ab9b2d00258f745620e2724838e7e21rederpj */
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj if (cur_subgroup_depth < max_subgroup_depth) {
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj int base_sgcIndex = 0;
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj int lcl_sgl_processedFlag = 0;
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj struct mod_auth_ldap_groupattr_entry_t *sgc_ents = (struct mod_auth_ldap_groupattr_entry_t *) subgroupclasses->elts;
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj /* 1. Check the "groupiness" of the specified basedn. Stopping at the first TRUE return. */
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj while ((base_sgcIndex < subgroupclasses->nelts) && (result != LDAP_COMPARE_TRUE)) {
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj result = uldap_cache_compare(r, ldc, url, dn, "objectClass", sgc_ents[base_sgcIndex].name);
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj if (result != LDAP_COMPARE_TRUE) {
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj base_sgcIndex++;
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj }
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj }
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj if (result != LDAP_COMPARE_TRUE) {
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj ldc->reason = "DN failed group verification.";
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj return result;
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj }
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj /* 2. Find previously created cache entry and check if there is already a subgrouplist. */
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj LDAP_CACHE_LOCK();
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj curnode.url = url;
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj curl = util_ald_cache_fetch(st->util_ldap_cache, &curnode);
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj LDAP_CACHE_UNLOCK();
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj if (curl && curl->compare_cache) {
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj /* make a comparison to the cache */
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj LDAP_CACHE_LOCK();
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj the_compare_node.dn = (char *)dn;
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj the_compare_node.attrib = (char *)"objectClass";
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj the_compare_node.value = (char *)sgc_ents[base_sgcIndex].name;
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj the_compare_node.result = 0;
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj the_compare_node.sgl_processed = 0;
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj the_compare_node.subgroupList = NULL;
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj compare_nodep = util_ald_cache_fetch(curl->compare_cache, &the_compare_node);
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj if (compare_nodep == NULL) {
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj /* Didn't find it. This shouldn't happen since we just called uldap_cache_compare. */
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj LDAP_CACHE_UNLOCK();
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj ldc->reason = "check_subgroups failed to find cached element.";
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj return LDAP_COMPARE_FALSE;
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj }
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj else {
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj /* Found the generic group entry... but the user isn't in this group or we wouldn't be here. */
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj lcl_sgl_processedFlag = compare_nodep->sgl_processed;
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj if(compare_nodep->sgl_processed && compare_nodep->subgroupList) {
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj /* Make a local copy of the subgroup list */
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj int i;
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj tmp_local_sgl = apr_pcalloc(r->pool, sizeof(util_compare_subgroup_t));
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj tmp_local_sgl->len = compare_nodep->subgroupList->len;
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj tmp_local_sgl->subgroupDNs = apr_pcalloc(r->pool, sizeof(char *) * compare_nodep->subgroupList->len);
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj for (i = 0; i < compare_nodep->subgroupList->len; i++) {
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj tmp_local_sgl->subgroupDNs[i] = apr_pstrdup(r->pool, compare_nodep->subgroupList->subgroupDNs[i]);
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj }
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj }
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj }
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj LDAP_CACHE_UNLOCK();
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj }
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj else {
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj /* If we get here, something is wrong. Caches should have been created and
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj this group entry should be found in the cache. */
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj ldc->reason = "check_subgroups failed to find any caches.";
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj return LDAP_COMPARE_FALSE;
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj }
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj result = LDAP_COMPARE_FALSE;
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj if ((lcl_sgl_processedFlag == 0) && (!tmp_local_sgl)) {
11ca38a20ab9b2d00258f745620e2724838e7e21rederpj /* No Cached SGL, retrieve from LDAP */
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpjstart_over:
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj /* 3.B. The cache didn't have any subgrouplist yet. Go check for subgroups. */
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj if (failures++ > 10) {
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj /* too many failures */
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj return result;
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj }
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj if (LDAP_SUCCESS != (result = uldap_connection_open(r, ldc))) {
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj /* connect failed */
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj return result;
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj }
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj /* try to do the search */
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj result = ldap_search_ext_s(ldc->ldap, (char *)dn, LDAP_SCOPE_BASE,
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj (char *)"cn=*", subgroupAttrs, 0,
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj NULL, NULL, NULL, APR_LDAP_SIZELIMIT, &sga_res);
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj if (result == LDAP_SERVER_DOWN) {
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj ldc->reason = "ldap_search_ext_s() for subgroups failed with server down";
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj uldap_connection_unbind(ldc);
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj goto start_over;
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj }
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj /* if there is an error (including LDAP_NO_SUCH_OBJECT) return now */
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj if (result != LDAP_SUCCESS) {
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj ldc->reason = "ldap_search_ext_s() for subgroups failed";
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj return result;
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj }
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj entry = ldap_first_entry(ldc->ldap, sga_res);
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj /*
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj * Get values for the provided sub-group attributes.
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj */
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj if (subgroupAttrs) {
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj int indx = 0, tmp_sgcIndex;
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj while (subgroupAttrs[indx]) {
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj char **values;
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj int val_index = 0;
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj /* Get *all* matching "member" values from this group. */
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj values = ldap_get_values(ldc->ldap, entry, subgroupAttrs[indx]);
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj if (values) {
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj val_index = 0;
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj /*
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj * Now we are going to pare the subgroup members of this group to *just*
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj * the subgroups, add them to the compare_nodep, and then proceed to check
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj * the new level of subgroups.
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj */
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj while (values[val_index]) {
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj /* Check if this entry really is a group. */
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj tmp_sgcIndex = 0;
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj result = LDAP_COMPARE_FALSE;
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj while ((tmp_sgcIndex < subgroupclasses->nelts) && (result != LDAP_COMPARE_TRUE)) {
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj result = uldap_cache_compare(r, ldc, url, values[val_index], "objectClass",
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj sgc_ents[tmp_sgcIndex].name);
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj if (result != LDAP_COMPARE_TRUE) {
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj tmp_sgcIndex++;
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj }
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj }
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj /* It's a group, so add it to the array. */
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj if (result == LDAP_COMPARE_TRUE) {
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj char **newgrp = (char **) apr_array_push(subgroups);
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj *newgrp = apr_pstrdup(r->pool, values[val_index]);
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj }
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj val_index++;
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj }
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj ldap_value_free(values);
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj }
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj indx++;
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj }
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj }
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj ldap_msgfree(sga_res);
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj if (subgroups->nelts > 0) {
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj /* We need to fill in tmp_local_subgroups using the data from LDAP */
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj int sgindex;
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj char **group;
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj tmp_local_sgl = apr_pcalloc(r->pool, sizeof(util_compare_subgroup_t));
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj tmp_local_sgl->subgroupDNs = apr_pcalloc(r->pool, sizeof(char *) * (subgroups->nelts));
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj for (sgindex = 0; (group = apr_array_pop(subgroups)); sgindex++) {
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj tmp_local_sgl->subgroupDNs[sgindex] = apr_pstrdup(r->pool, *group);
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj }
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj tmp_local_sgl->len = sgindex;
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj }
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj
11ca38a20ab9b2d00258f745620e2724838e7e21rederpj /* Find the generic group cache entry and add the sgl we just retrieved. */
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj LDAP_CACHE_LOCK();
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj the_compare_node.dn = (char *)dn;
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj the_compare_node.attrib = (char *)"objectClass";
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj the_compare_node.value = (char *)sgc_ents[base_sgcIndex].name;
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj the_compare_node.result = 0;
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj the_compare_node.sgl_processed = 0;
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj the_compare_node.subgroupList = NULL;
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj compare_nodep = util_ald_cache_fetch(curl->compare_cache, &the_compare_node);
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj if (compare_nodep == NULL) {
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj /* Didn't find it. This shouldn't happen since we just called uldap_cache_compare. */
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj LDAP_CACHE_UNLOCK();
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj ldc->reason = "check_subgroups failed to find the cache entry to add sub-group list to.";
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj return LDAP_COMPARE_FALSE;
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj }
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj else {
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj /* overwrite SGL if it was previously updated between the last
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj ** two times we looked at the cache
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj */
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj compare_nodep->sgl_processed = 1;
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj if (tmp_local_sgl) {
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj compare_nodep->subgroupList = util_ald_sgl_dup(curl->compare_cache, tmp_local_sgl);
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj }
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj else {
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj /* We didn't find a single subgroup, next time save us from looking */
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj compare_nodep->subgroupList = NULL;
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj }
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj }
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj LDAP_CACHE_UNLOCK();
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj }
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj /* tmp_local_sgl has either been created, or copied out of the cache */
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj /* If tmp_local_sgl is NULL, there are no subgroups to process and we'll return false */
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj result = LDAP_COMPARE_FALSE;
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj if (tmp_local_sgl) {
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj int sgindex = 0;
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj const char *group = NULL;
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj while ((result != LDAP_COMPARE_TRUE) && (sgindex < tmp_local_sgl->len)) {
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj group = tmp_local_sgl->subgroupDNs[sgindex];
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj /* 4. Now loop through the subgroupList and call uldap_cache_compare to check for the user. */
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj result = uldap_cache_compare(r, ldc, url, group, attrib, value);
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj if (result == LDAP_COMPARE_TRUE) {
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj /* 4.A. We found the user in the subgroup. Return LDAP_COMPARE_TRUE. */
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, "[%" APR_PID_T_FMT "] util_ldap:"
11ca38a20ab9b2d00258f745620e2724838e7e21rederpj " Found user %s in a subgroup (%s) at level %d of %d.",
11ca38a20ab9b2d00258f745620e2724838e7e21rederpj getpid(), r->user, group, cur_subgroup_depth+1, max_subgroup_depth);
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj }
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj else {
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj /* 4.B. We didn't find the user in this subgroup, so recurse into it and keep looking. */
11ca38a20ab9b2d00258f745620e2724838e7e21rederpj ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, "[%" APR_PID_T_FMT "] util_ldap:"
11ca38a20ab9b2d00258f745620e2724838e7e21rederpj " user %s not found in subgroup (%s) at level %d of %d.",
11ca38a20ab9b2d00258f745620e2724838e7e21rederpj getpid(), r->user, group, cur_subgroup_depth+1, max_subgroup_depth);
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj result = uldap_cache_check_subgroups(r, ldc, url, group, attrib,
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj value, subgroupAttrs, subgroupclasses,
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj cur_subgroup_depth+1, max_subgroup_depth);
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj }
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj sgindex++;
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj }
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj }
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) {
c4f16f709c79bb7e2ddffb532bc7708eab9a9691covener int i = 0, k = 0;
c4f16f709c79bb7e2ddffb532bc7708eab9a9691covener while (attrs[k++]);
c4f16f709c79bb7e2ddffb532bc7708eab9a9691covener *retvals = apr_pcalloc(r->pool, sizeof(char *) * k);
c4f16f709c79bb7e2ddffb532bc7708eab9a9691covener while (search_nodep->vals[i]) {
b19bd761d15272888503eb9fce5071783c1eecd7covener (*retvals)[i] = apr_pstrdup(r->pool, search_nodep->vals[i]);
c4f16f709c79bb7e2ddffb532bc7708eab9a9691covener i++;
c4f16f709c79bb7e2ddffb532bc7708eab9a9691covener }
c4f16f709c79bb7e2ddffb532bc7708eab9a9691covener }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes LDAP_CACHE_UNLOCK();
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes ldc->reason = "Authentication successful (cached)";
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes return LDAP_SUCCESS;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes /* unlock this read lock */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes LDAP_CACHE_UNLOCK();
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
e8f95a682820a599fe41b22977010636be5c2717jim /*
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * At this point, there is no valid cached search, so lets do the search.
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes /*
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe * If LDAP operation fails due to LDAP_SERVER_DOWN, control returns here.
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholesstart_over:
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes if (failures++ > 10) {
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes return result;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
f43b67c5a9d29b572eac916f8335cedc80c908bebnicholes if (LDAP_SUCCESS != (result = uldap_connection_open(r, ldc))) {
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes return result;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes /* try do the search */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes if ((result = ldap_search_ext_s(ldc->ldap,
e8f95a682820a599fe41b22977010636be5c2717jim (char *)basedn, scope,
e8f95a682820a599fe41b22977010636be5c2717jim (char *)filter, attrs, 0,
22f8da8087791fcb95b836c8a81937c5a9bba202bnicholes NULL, NULL, NULL, APR_LDAP_SIZELIMIT, &res))
e8f95a682820a599fe41b22977010636be5c2717jim == LDAP_SERVER_DOWN)
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe {
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes ldc->reason = "ldap_search_ext_s() for user failed with server down";
f43b67c5a9d29b572eac916f8335cedc80c908bebnicholes uldap_connection_unbind(ldc);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes goto start_over;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes /* if there is an error (including LDAP_NO_SUCH_OBJECT) return now */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes if (result != LDAP_SUCCESS) {
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes ldc->reason = "ldap_search_ext_s() for user failed";
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes return result;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
e8f95a682820a599fe41b22977010636be5c2717jim /*
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * We should have found exactly one entry; to find a different
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * number is an error.
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes count = ldap_count_entries(ldc->ldap, res);
e8f95a682820a599fe41b22977010636be5c2717jim if (count != 1)
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes {
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes if (count == 0 )
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes ldc->reason = "User not found";
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes else
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe ldc->reason = "User is not unique (search found two "
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe "or more matches)";
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes ldap_msgfree(res);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes return LDAP_NO_SUCH_OBJECT;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes entry = ldap_first_entry(ldc->ldap, res);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes /* Grab the dn, copy it into the pool, and free it again */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes dn = ldap_get_dn(ldc->ldap, entry);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes *binddn = apr_pstrdup(r->pool, dn);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes ldap_memfree(dn);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
e8f95a682820a599fe41b22977010636be5c2717jim /*
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * A bind to the server with an empty password always succeeds, so
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * we check to ensure that the password is not empty. This implies
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * that users who actually do have empty passwords will never be
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * able to authenticate with this module. I don't see this as a big
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * problem.
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes */
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes if (!bindpw || strlen(bindpw) <= 0) {
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes ldap_msgfree(res);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes ldc->reason = "Empty password not allowed";
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes return LDAP_INVALID_CREDENTIALS;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
e8f95a682820a599fe41b22977010636be5c2717jim /*
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * Attempt to bind with the retrieved dn and the password. If the bind
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * fails, it means that the password is wrong (the dn obviously
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * exists, since we just retrieved it)
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes */
bb07ee33bce1a448bcc60ca43720b1ab1c413f87minfrin if ((result = ldap_simple_bind_s(ldc->ldap,
bb07ee33bce1a448bcc60ca43720b1ab1c413f87minfrin (char *)*binddn,
bb07ee33bce1a448bcc60ca43720b1ab1c413f87minfrin (char *)bindpw)) == LDAP_SERVER_DOWN) {
bb07ee33bce1a448bcc60ca43720b1ab1c413f87minfrin ldc->reason = "ldap_simple_bind_s() to check user credentials "
bb07ee33bce1a448bcc60ca43720b1ab1c413f87minfrin "failed with server down";
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes ldap_msgfree(res);
f43b67c5a9d29b572eac916f8335cedc80c908bebnicholes uldap_connection_unbind(ldc);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes goto start_over;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes /* failure? if so - return */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes if (result != LDAP_SUCCESS) {
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes ldc->reason = "ldap_simple_bind_s() to check user credentials failed";
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes ldap_msgfree(res);
f43b67c5a9d29b572eac916f8335cedc80c908bebnicholes uldap_connection_unbind(ldc);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes return result;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes else {
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes /*
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * We have just bound the connection to a different user and password
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * combination, which might be reused unintentionally next time this
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * connection is used from the connection pool. To ensure no confusion,
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * we mark the connection as unbound.
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes ldc->bound = 0;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes /*
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * Get values for the provided attributes.
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes if (attrs) {
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes int k = 0;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes int i = 0;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes while (attrs[k++]);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes vals = apr_pcalloc(r->pool, sizeof(char *) * (k+1));
8bdea88407c848c1c2693655e2f8b23abde12307bnicholes numvals = k;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes while (attrs[i]) {
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes char **values;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes int j = 0;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes char *str = NULL;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes /* get values */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes values = ldap_get_values(ldc->ldap, entry, attrs[i]);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes while (values && values[j]) {
e8f95a682820a599fe41b22977010636be5c2717jim str = str ? apr_pstrcat(r->pool, str, "; ", values[j], NULL)
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe : apr_pstrdup(r->pool, values[j]);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes j++;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes ldap_value_free(values);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes vals[i] = str;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes i++;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes *retvals = vals;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
e8f95a682820a599fe41b22977010636be5c2717jim /*
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * Add the new username to the search cache.
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes if (curl) {
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes LDAP_CACHE_LOCK();
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes the_search_node.username = filter;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes the_search_node.dn = *binddn;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes the_search_node.bindpw = bindpw;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes the_search_node.lastbind = apr_time_now();
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes the_search_node.vals = vals;
8bdea88407c848c1c2693655e2f8b23abde12307bnicholes the_search_node.numvals = numvals;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
e8f95a682820a599fe41b22977010636be5c2717jim /* Search again to make sure that another thread didn't ready insert
e8f95a682820a599fe41b22977010636be5c2717jim * this node into the cache before we got here. If it does exist then
e8f95a682820a599fe41b22977010636be5c2717jim * update the lastbind
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe */
e8f95a682820a599fe41b22977010636be5c2717jim search_nodep = util_ald_cache_fetch(curl->search_cache,
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe &the_search_node);
e8f95a682820a599fe41b22977010636be5c2717jim if ((search_nodep == NULL) ||
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes (strcmp(*binddn, search_nodep->dn) != 0)) {
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes /* Nothing in cache, insert new entry */
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes util_ald_cache_insert(curl->search_cache, &the_search_node);
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes }
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes else if ((!search_nodep->bindpw) ||
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes (strcmp(bindpw, search_nodep->bindpw) != 0)) {
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes /* Entry in cache is invalid, remove it and insert new one */
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes util_ald_cache_remove(curl->search_cache, search_nodep);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes util_ald_cache_insert(curl->search_cache, &the_search_node);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes else {
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes /* Cache entry is valid, update lastbind */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes search_nodep->lastbind = the_search_node.lastbind;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes LDAP_CACHE_UNLOCK();
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes ldap_msgfree(res);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes ldc->reason = "Authentication successful";
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes return LDAP_SUCCESS;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes}
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
8113dac419143273351446c3ad653f3fe5ba5cfdwrowe/*
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes * This function will return the DN of the entry matching userid.
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes * It is used to get the DN in case some other module than mod_auth_ldap
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes * has authenticated the user.
f43b67c5a9d29b572eac916f8335cedc80c908bebnicholes * The function is basically a copy of uldap_cache_checkuserid
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes * with password checking removed.
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes */
8113dac419143273351446c3ad653f3fe5ba5cfdwrowestatic int uldap_cache_getuserdn(request_rec *r, util_ldap_connection_t *ldc,
e8f95a682820a599fe41b22977010636be5c2717jim const char *url, const char *basedn,
e8f95a682820a599fe41b22977010636be5c2717jim int scope, char **attrs, const char *filter,
8113dac419143273351446c3ad653f3fe5ba5cfdwrowe const char **binddn, const char ***retvals)
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes{
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes const char **vals = NULL;
8bdea88407c848c1c2693655e2f8b23abde12307bnicholes int numvals = 0;
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes int result = 0;
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes LDAPMessage *res, *entry;
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes char *dn;
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes int count;
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes int failures = 0;
f05787953018140838ad51456c86c965d6a86267jim util_url_node_t *curl; /* Cached URL node */
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes util_url_node_t curnode;
f05787953018140838ad51456c86c965d6a86267jim util_search_node_t *search_nodep; /* Cached search node */
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes util_search_node_t the_search_node;
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes apr_time_t curtime;
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes
e8f95a682820a599fe41b22977010636be5c2717jim util_ldap_state_t *st =
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes (util_ldap_state_t *)ap_get_module_config(r->server->module_config,
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes &ldap_module);
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes /* Get the cache node for this url */
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes LDAP_CACHE_LOCK();
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes curnode.url = url;
e8f95a682820a599fe41b22977010636be5c2717jim curl = (util_url_node_t *)util_ald_cache_fetch(st->util_ldap_cache,
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe &curnode);
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes if (curl == NULL) {
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes curl = util_ald_create_caches(st, url);
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes }
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes LDAP_CACHE_UNLOCK();
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes if (curl) {
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes LDAP_CACHE_LOCK();
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes the_search_node.username = filter;
e8f95a682820a599fe41b22977010636be5c2717jim search_nodep = util_ald_cache_fetch(curl->search_cache,
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe &the_search_node);
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes if (search_nodep != NULL) {
e8f95a682820a599fe41b22977010636be5c2717jim
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes /* found entry in search cache... */
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes curtime = apr_time_now();
e8f95a682820a599fe41b22977010636be5c2717jim
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes /*
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes * Remove this item from the cache if its expired.
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes */
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes if ((curtime - search_nodep->lastbind) > st->search_cache_ttl) {
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes /* ...but entry is too old */
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes util_ald_cache_remove(curl->search_cache, search_nodep);
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes }
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes else {
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes /* ...and entry is valid */
c4f16f709c79bb7e2ddffb532bc7708eab9a9691covener *binddn = apr_pstrdup(r->pool, search_nodep->dn);
c4f16f709c79bb7e2ddffb532bc7708eab9a9691covener if (attrs) {
c4f16f709c79bb7e2ddffb532bc7708eab9a9691covener int i = 0, k = 0;
c4f16f709c79bb7e2ddffb532bc7708eab9a9691covener while (attrs[k++]);
c4f16f709c79bb7e2ddffb532bc7708eab9a9691covener *retvals = apr_pcalloc(r->pool, sizeof(char *) * k);
c4f16f709c79bb7e2ddffb532bc7708eab9a9691covener while (search_nodep->vals[i]) {
b19bd761d15272888503eb9fce5071783c1eecd7covener (*retvals)[i] = apr_pstrdup(r->pool, search_nodep->vals[i]);
c4f16f709c79bb7e2ddffb532bc7708eab9a9691covener i++;
c4f16f709c79bb7e2ddffb532bc7708eab9a9691covener }
c4f16f709c79bb7e2ddffb532bc7708eab9a9691covener }
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes LDAP_CACHE_UNLOCK();
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes ldc->reason = "Search successful (cached)";
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes return LDAP_SUCCESS;
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes }
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes }
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes /* unlock this read lock */
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes LDAP_CACHE_UNLOCK();
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes }
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes
e8f95a682820a599fe41b22977010636be5c2717jim /*
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes * At this point, there is no valid cached search, so lets do the search.
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes */
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes /*
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe * If LDAP operation fails due to LDAP_SERVER_DOWN, control returns here.
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes */
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholesstart_over:
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes if (failures++ > 10) {
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes return result;
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes }
f43b67c5a9d29b572eac916f8335cedc80c908bebnicholes if (LDAP_SUCCESS != (result = uldap_connection_open(r, ldc))) {
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes return result;
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes }
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes /* try do the search */
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes if ((result = ldap_search_ext_s(ldc->ldap,
43c3e6a4b559b76b750c245ee95e2782c15b4296jim (char *)basedn, scope,
e8f95a682820a599fe41b22977010636be5c2717jim (char *)filter, attrs, 0,
22f8da8087791fcb95b836c8a81937c5a9bba202bnicholes NULL, NULL, NULL, APR_LDAP_SIZELIMIT, &res))
e8f95a682820a599fe41b22977010636be5c2717jim == LDAP_SERVER_DOWN)
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe {
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes ldc->reason = "ldap_search_ext_s() for user failed with server down";
f43b67c5a9d29b572eac916f8335cedc80c908bebnicholes uldap_connection_unbind(ldc);
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes goto start_over;
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes }
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes /* if there is an error (including LDAP_NO_SUCH_OBJECT) return now */
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes if (result != LDAP_SUCCESS) {
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes ldc->reason = "ldap_search_ext_s() for user failed";
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes return result;
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes }
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes
e8f95a682820a599fe41b22977010636be5c2717jim /*
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes * We should have found exactly one entry; to find a different
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes * number is an error.
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes */
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes count = ldap_count_entries(ldc->ldap, res);
e8f95a682820a599fe41b22977010636be5c2717jim if (count != 1)
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes {
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes if (count == 0 )
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes ldc->reason = "User not found";
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes else
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe ldc->reason = "User is not unique (search found two "
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe "or more matches)";
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes ldap_msgfree(res);
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes return LDAP_NO_SUCH_OBJECT;
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes }
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes entry = ldap_first_entry(ldc->ldap, res);
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes /* Grab the dn, copy it into the pool, and free it again */
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes dn = ldap_get_dn(ldc->ldap, entry);
490046d2a164ad86cc63bd789f32eaed663d239abnicholes *binddn = apr_pstrdup(r->pool, dn);
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes ldap_memfree(dn);
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes /*
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes * Get values for the provided attributes.
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes */
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes if (attrs) {
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes int k = 0;
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes int i = 0;
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes while (attrs[k++]);
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes vals = apr_pcalloc(r->pool, sizeof(char *) * (k+1));
8bdea88407c848c1c2693655e2f8b23abde12307bnicholes numvals = k;
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes while (attrs[i]) {
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes char **values;
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes int j = 0;
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes char *str = NULL;
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes /* get values */
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes values = ldap_get_values(ldc->ldap, entry, attrs[i]);
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes while (values && values[j]) {
e8f95a682820a599fe41b22977010636be5c2717jim str = str ? apr_pstrcat(r->pool, str, "; ", values[j], NULL)
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe : apr_pstrdup(r->pool, values[j]);
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes j++;
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes }
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes ldap_value_free(values);
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes vals[i] = str;
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes i++;
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes }
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes *retvals = vals;
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes }
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes
e8f95a682820a599fe41b22977010636be5c2717jim /*
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes * Add the new username to the search cache.
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes */
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes if (curl) {
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes LDAP_CACHE_LOCK();
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes the_search_node.username = filter;
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes the_search_node.dn = *binddn;
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes the_search_node.bindpw = NULL;
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes the_search_node.lastbind = apr_time_now();
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes the_search_node.vals = vals;
8bdea88407c848c1c2693655e2f8b23abde12307bnicholes the_search_node.numvals = numvals;
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes
e8f95a682820a599fe41b22977010636be5c2717jim /* Search again to make sure that another thread didn't ready insert
e8f95a682820a599fe41b22977010636be5c2717jim * this node into the cache before we got here. If it does exist then
e8f95a682820a599fe41b22977010636be5c2717jim * update the lastbind
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe */
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe search_nodep = util_ald_cache_fetch(curl->search_cache,
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe &the_search_node);
e8f95a682820a599fe41b22977010636be5c2717jim if ((search_nodep == NULL) ||
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes (strcmp(*binddn, search_nodep->dn) != 0)) {
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes /* Nothing in cache, insert new entry */
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes util_ald_cache_insert(curl->search_cache, &the_search_node);
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes }
0c8aa496e9d7676ff8101783398f17c0da1900f7bnicholes /*
0c8aa496e9d7676ff8101783398f17c0da1900f7bnicholes * Don't update lastbind on entries with bindpw because
0c8aa496e9d7676ff8101783398f17c0da1900f7bnicholes * we haven't verified that password. It's OK to update
0c8aa496e9d7676ff8101783398f17c0da1900f7bnicholes * the entry if there is no password in it.
0c8aa496e9d7676ff8101783398f17c0da1900f7bnicholes */
0c8aa496e9d7676ff8101783398f17c0da1900f7bnicholes else if (!search_nodep->bindpw) {
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes /* Cache entry is valid, update lastbind */
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes search_nodep->lastbind = the_search_node.lastbind;
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes }
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes LDAP_CACHE_UNLOCK();
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes }
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes ldap_msgfree(res);
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes ldc->reason = "Search successful";
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes return LDAP_SUCCESS;
03f4448f864e31ade79856ac8c264a5e6dce3b10bnicholes}
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes/*
e8f95a682820a599fe41b22977010636be5c2717jim * Reports if ssl support is enabled
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes *
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * 1 = enabled, 0 = not enabled
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes */
8113dac419143273351446c3ad653f3fe5ba5cfdwrowestatic int uldap_ssl_supported(request_rec *r)
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes{
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes util_ldap_state_t *st = (util_ldap_state_t *)ap_get_module_config(
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes r->server->module_config, &ldap_module);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
54d22ed1c429b903b029bbd62621f11a9e286137minfrin return(st->ssl_supported);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes}
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes/* ---------------------------------------- */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes/* config directives */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
e8f95a682820a599fe41b22977010636be5c2717jimstatic const char *util_ldap_set_cache_bytes(cmd_parms *cmd, void *dummy,
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe const char *bytes)
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes{
e8f95a682820a599fe41b22977010636be5c2717jim util_ldap_state_t *st =
e8f95a682820a599fe41b22977010636be5c2717jim (util_ldap_state_t *)ap_get_module_config(cmd->server->module_config,
43c3e6a4b559b76b750c245ee95e2782c15b4296jim &ldap_module);
3effb85eb3124c6f02cd89e22ffed0fc9afaddb9bnicholes const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
3effb85eb3124c6f02cd89e22ffed0fc9afaddb9bnicholes
3effb85eb3124c6f02cd89e22ffed0fc9afaddb9bnicholes if (err != NULL) {
3effb85eb3124c6f02cd89e22ffed0fc9afaddb9bnicholes return err;
3effb85eb3124c6f02cd89e22ffed0fc9afaddb9bnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes st->cache_bytes = atol(bytes);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
e8f95a682820a599fe41b22977010636be5c2717jim ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, cmd->server,
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes "[%" APR_PID_T_FMT "] ldap cache: Setting shared memory "
e8f95a682820a599fe41b22977010636be5c2717jim " cache size to %" APR_SIZE_T_FMT " bytes.",
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes getpid(), st->cache_bytes);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes return NULL;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes}
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
e8f95a682820a599fe41b22977010636be5c2717jimstatic const char *util_ldap_set_cache_file(cmd_parms *cmd, void *dummy,
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe const char *file)
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes{
e8f95a682820a599fe41b22977010636be5c2717jim util_ldap_state_t *st =
e8f95a682820a599fe41b22977010636be5c2717jim (util_ldap_state_t *)ap_get_module_config(cmd->server->module_config,
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes &ldap_module);
3effb85eb3124c6f02cd89e22ffed0fc9afaddb9bnicholes const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
3effb85eb3124c6f02cd89e22ffed0fc9afaddb9bnicholes
3effb85eb3124c6f02cd89e22ffed0fc9afaddb9bnicholes if (err != NULL) {
3effb85eb3124c6f02cd89e22ffed0fc9afaddb9bnicholes return err;
3effb85eb3124c6f02cd89e22ffed0fc9afaddb9bnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes if (file) {
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes st->cache_file = ap_server_root_relative(st->pool, file);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes else {
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes st->cache_file = NULL;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
e8f95a682820a599fe41b22977010636be5c2717jim ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, cmd->server,
e8f95a682820a599fe41b22977010636be5c2717jim "LDAP cache: Setting shared memory cache file to %s bytes.",
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes st->cache_file);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes return NULL;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes}
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
e8f95a682820a599fe41b22977010636be5c2717jimstatic const char *util_ldap_set_cache_ttl(cmd_parms *cmd, void *dummy,
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe const char *ttl)
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes{
e8f95a682820a599fe41b22977010636be5c2717jim util_ldap_state_t *st =
e8f95a682820a599fe41b22977010636be5c2717jim (util_ldap_state_t *)ap_get_module_config(cmd->server->module_config,
43c3e6a4b559b76b750c245ee95e2782c15b4296jim &ldap_module);
3effb85eb3124c6f02cd89e22ffed0fc9afaddb9bnicholes const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
3effb85eb3124c6f02cd89e22ffed0fc9afaddb9bnicholes
3effb85eb3124c6f02cd89e22ffed0fc9afaddb9bnicholes if (err != NULL) {
3effb85eb3124c6f02cd89e22ffed0fc9afaddb9bnicholes return err;
3effb85eb3124c6f02cd89e22ffed0fc9afaddb9bnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes st->search_cache_ttl = atol(ttl) * 1000000;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
e8f95a682820a599fe41b22977010636be5c2717jim ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, cmd->server,
368a30e0cf9ddb3fda08e6b443dd01410277cfb6jim "[%" APR_PID_T_FMT "] ldap cache: Setting cache TTL to %ld microseconds.",
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe getpid(), st->search_cache_ttl);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes return NULL;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes}
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
e8f95a682820a599fe41b22977010636be5c2717jimstatic const char *util_ldap_set_cache_entries(cmd_parms *cmd, void *dummy,
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe const char *size)
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes{
e8f95a682820a599fe41b22977010636be5c2717jim util_ldap_state_t *st =
e8f95a682820a599fe41b22977010636be5c2717jim (util_ldap_state_t *)ap_get_module_config(cmd->server->module_config,
43c3e6a4b559b76b750c245ee95e2782c15b4296jim &ldap_module);
3effb85eb3124c6f02cd89e22ffed0fc9afaddb9bnicholes const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
3effb85eb3124c6f02cd89e22ffed0fc9afaddb9bnicholes if (err != NULL) {
3effb85eb3124c6f02cd89e22ffed0fc9afaddb9bnicholes return err;
3effb85eb3124c6f02cd89e22ffed0fc9afaddb9bnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes st->search_cache_size = atol(size);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes if (st->search_cache_size < 0) {
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes st->search_cache_size = 0;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
e8f95a682820a599fe41b22977010636be5c2717jim ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, cmd->server,
368a30e0cf9ddb3fda08e6b443dd01410277cfb6jim "[%" APR_PID_T_FMT "] ldap cache: Setting search cache size to %ld entries.",
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe getpid(), st->search_cache_size);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes return NULL;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes}
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
e8f95a682820a599fe41b22977010636be5c2717jimstatic const char *util_ldap_set_opcache_ttl(cmd_parms *cmd, void *dummy,
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe const char *ttl)
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes{
e8f95a682820a599fe41b22977010636be5c2717jim util_ldap_state_t *st =
e8f95a682820a599fe41b22977010636be5c2717jim (util_ldap_state_t *)ap_get_module_config(cmd->server->module_config,
43c3e6a4b559b76b750c245ee95e2782c15b4296jim &ldap_module);
3effb85eb3124c6f02cd89e22ffed0fc9afaddb9bnicholes const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
3effb85eb3124c6f02cd89e22ffed0fc9afaddb9bnicholes
3effb85eb3124c6f02cd89e22ffed0fc9afaddb9bnicholes if (err != NULL) {
3effb85eb3124c6f02cd89e22ffed0fc9afaddb9bnicholes return err;
3effb85eb3124c6f02cd89e22ffed0fc9afaddb9bnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes st->compare_cache_ttl = atol(ttl) * 1000000;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
e8f95a682820a599fe41b22977010636be5c2717jim ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, cmd->server,
e8f95a682820a599fe41b22977010636be5c2717jim "[%" APR_PID_T_FMT "] ldap cache: Setting operation cache TTL to %ld microseconds.",
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe getpid(), st->compare_cache_ttl);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes return NULL;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes}
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
e8f95a682820a599fe41b22977010636be5c2717jimstatic const char *util_ldap_set_opcache_entries(cmd_parms *cmd, void *dummy,
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe const char *size)
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes{
e8f95a682820a599fe41b22977010636be5c2717jim util_ldap_state_t *st =
e8f95a682820a599fe41b22977010636be5c2717jim (util_ldap_state_t *)ap_get_module_config(cmd->server->module_config,
43c3e6a4b559b76b750c245ee95e2782c15b4296jim &ldap_module);
3effb85eb3124c6f02cd89e22ffed0fc9afaddb9bnicholes const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
3effb85eb3124c6f02cd89e22ffed0fc9afaddb9bnicholes
3effb85eb3124c6f02cd89e22ffed0fc9afaddb9bnicholes if (err != NULL) {
3effb85eb3124c6f02cd89e22ffed0fc9afaddb9bnicholes return err;
3effb85eb3124c6f02cd89e22ffed0fc9afaddb9bnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes st->compare_cache_size = atol(size);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes if (st->compare_cache_size < 0) {
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes st->compare_cache_size = 0;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
e8f95a682820a599fe41b22977010636be5c2717jim ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, cmd->server,
368a30e0cf9ddb3fda08e6b443dd01410277cfb6jim "[%" APR_PID_T_FMT "] ldap cache: Setting operation cache size to %ld "
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe "entries.", getpid(), st->compare_cache_size);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes return NULL;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes}
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
54d22ed1c429b903b029bbd62621f11a9e286137minfrin
54d22ed1c429b903b029bbd62621f11a9e286137minfrin/**
54d22ed1c429b903b029bbd62621f11a9e286137minfrin * Parse the certificate type.
54d22ed1c429b903b029bbd62621f11a9e286137minfrin *
54d22ed1c429b903b029bbd62621f11a9e286137minfrin * The type can be one of the following:
54d22ed1c429b903b029bbd62621f11a9e286137minfrin * CA_DER, CA_BASE64, CA_CERT7_DB, CA_SECMOD, CERT_DER, CERT_BASE64,
54d22ed1c429b903b029bbd62621f11a9e286137minfrin * CERT_KEY3_DB, CERT_NICKNAME, KEY_DER, KEY_BASE64
54d22ed1c429b903b029bbd62621f11a9e286137minfrin *
54d22ed1c429b903b029bbd62621f11a9e286137minfrin * If no matches are found, APR_LDAP_CA_TYPE_UNKNOWN is returned.
54d22ed1c429b903b029bbd62621f11a9e286137minfrin */
88adce5ec0da39b41450ce1d5a77659168097e0cjortonstatic int util_ldap_parse_cert_type(const char *type)
88adce5ec0da39b41450ce1d5a77659168097e0cjorton{
54d22ed1c429b903b029bbd62621f11a9e286137minfrin /* Authority file in binary DER format */
54d22ed1c429b903b029bbd62621f11a9e286137minfrin if (0 == strcasecmp("CA_DER", type)) {
54d22ed1c429b903b029bbd62621f11a9e286137minfrin return APR_LDAP_CA_TYPE_DER;
54d22ed1c429b903b029bbd62621f11a9e286137minfrin }
54d22ed1c429b903b029bbd62621f11a9e286137minfrin
54d22ed1c429b903b029bbd62621f11a9e286137minfrin /* Authority file in Base64 format */
54d22ed1c429b903b029bbd62621f11a9e286137minfrin else if (0 == strcasecmp("CA_BASE64", type)) {
54d22ed1c429b903b029bbd62621f11a9e286137minfrin return APR_LDAP_CA_TYPE_BASE64;
54d22ed1c429b903b029bbd62621f11a9e286137minfrin }
54d22ed1c429b903b029bbd62621f11a9e286137minfrin
54d22ed1c429b903b029bbd62621f11a9e286137minfrin /* Netscape certificate database file/directory */
54d22ed1c429b903b029bbd62621f11a9e286137minfrin else if (0 == strcasecmp("CA_CERT7_DB", type)) {
54d22ed1c429b903b029bbd62621f11a9e286137minfrin return APR_LDAP_CA_TYPE_CERT7_DB;
54d22ed1c429b903b029bbd62621f11a9e286137minfrin }
54d22ed1c429b903b029bbd62621f11a9e286137minfrin
54d22ed1c429b903b029bbd62621f11a9e286137minfrin /* Netscape secmod file/directory */
54d22ed1c429b903b029bbd62621f11a9e286137minfrin else if (0 == strcasecmp("CA_SECMOD", type)) {
54d22ed1c429b903b029bbd62621f11a9e286137minfrin return APR_LDAP_CA_TYPE_SECMOD;
54d22ed1c429b903b029bbd62621f11a9e286137minfrin }
54d22ed1c429b903b029bbd62621f11a9e286137minfrin
54d22ed1c429b903b029bbd62621f11a9e286137minfrin /* Client cert file in DER format */
54d22ed1c429b903b029bbd62621f11a9e286137minfrin else if (0 == strcasecmp("CERT_DER", type)) {
54d22ed1c429b903b029bbd62621f11a9e286137minfrin return APR_LDAP_CERT_TYPE_DER;
54d22ed1c429b903b029bbd62621f11a9e286137minfrin }
54d22ed1c429b903b029bbd62621f11a9e286137minfrin
54d22ed1c429b903b029bbd62621f11a9e286137minfrin /* Client cert file in Base64 format */
54d22ed1c429b903b029bbd62621f11a9e286137minfrin else if (0 == strcasecmp("CERT_BASE64", type)) {
54d22ed1c429b903b029bbd62621f11a9e286137minfrin return APR_LDAP_CERT_TYPE_BASE64;
54d22ed1c429b903b029bbd62621f11a9e286137minfrin }
54d22ed1c429b903b029bbd62621f11a9e286137minfrin
09338db7fdcf82ecc189195347da3a3ed5d0287abnicholes /* Client cert file in PKCS#12 format */
09338db7fdcf82ecc189195347da3a3ed5d0287abnicholes else if (0 == strcasecmp("CERT_PFX", type)) {
09338db7fdcf82ecc189195347da3a3ed5d0287abnicholes return APR_LDAP_CERT_TYPE_PFX;
09338db7fdcf82ecc189195347da3a3ed5d0287abnicholes }
09338db7fdcf82ecc189195347da3a3ed5d0287abnicholes
54d22ed1c429b903b029bbd62621f11a9e286137minfrin /* Netscape client cert database file/directory */
54d22ed1c429b903b029bbd62621f11a9e286137minfrin else if (0 == strcasecmp("CERT_KEY3_DB", type)) {
54d22ed1c429b903b029bbd62621f11a9e286137minfrin return APR_LDAP_CERT_TYPE_KEY3_DB;
54d22ed1c429b903b029bbd62621f11a9e286137minfrin }
54d22ed1c429b903b029bbd62621f11a9e286137minfrin
54d22ed1c429b903b029bbd62621f11a9e286137minfrin /* Netscape client cert nickname */
54d22ed1c429b903b029bbd62621f11a9e286137minfrin else if (0 == strcasecmp("CERT_NICKNAME", type)) {
54d22ed1c429b903b029bbd62621f11a9e286137minfrin return APR_LDAP_CERT_TYPE_NICKNAME;
54d22ed1c429b903b029bbd62621f11a9e286137minfrin }
54d22ed1c429b903b029bbd62621f11a9e286137minfrin
54d22ed1c429b903b029bbd62621f11a9e286137minfrin /* Client cert key file in DER format */
54d22ed1c429b903b029bbd62621f11a9e286137minfrin else if (0 == strcasecmp("KEY_DER", type)) {
54d22ed1c429b903b029bbd62621f11a9e286137minfrin return APR_LDAP_KEY_TYPE_DER;
54d22ed1c429b903b029bbd62621f11a9e286137minfrin }
54d22ed1c429b903b029bbd62621f11a9e286137minfrin
54d22ed1c429b903b029bbd62621f11a9e286137minfrin /* Client cert key file in Base64 format */
54d22ed1c429b903b029bbd62621f11a9e286137minfrin else if (0 == strcasecmp("KEY_BASE64", type)) {
54d22ed1c429b903b029bbd62621f11a9e286137minfrin return APR_LDAP_KEY_TYPE_BASE64;
54d22ed1c429b903b029bbd62621f11a9e286137minfrin }
54d22ed1c429b903b029bbd62621f11a9e286137minfrin
09338db7fdcf82ecc189195347da3a3ed5d0287abnicholes /* Client cert key file in PKCS#12 format */
09338db7fdcf82ecc189195347da3a3ed5d0287abnicholes else if (0 == strcasecmp("KEY_PFX", type)) {
09338db7fdcf82ecc189195347da3a3ed5d0287abnicholes return APR_LDAP_KEY_TYPE_PFX;
09338db7fdcf82ecc189195347da3a3ed5d0287abnicholes }
09338db7fdcf82ecc189195347da3a3ed5d0287abnicholes
54d22ed1c429b903b029bbd62621f11a9e286137minfrin else {
54d22ed1c429b903b029bbd62621f11a9e286137minfrin return APR_LDAP_CA_TYPE_UNKNOWN;
54d22ed1c429b903b029bbd62621f11a9e286137minfrin }
54d22ed1c429b903b029bbd62621f11a9e286137minfrin
54d22ed1c429b903b029bbd62621f11a9e286137minfrin}
54d22ed1c429b903b029bbd62621f11a9e286137minfrin
54d22ed1c429b903b029bbd62621f11a9e286137minfrin
54d22ed1c429b903b029bbd62621f11a9e286137minfrin/**
54d22ed1c429b903b029bbd62621f11a9e286137minfrin * Set LDAPTrustedGlobalCert.
54d22ed1c429b903b029bbd62621f11a9e286137minfrin *
54d22ed1c429b903b029bbd62621f11a9e286137minfrin * This directive takes either two or three arguments:
54d22ed1c429b903b029bbd62621f11a9e286137minfrin * - certificate type
54d22ed1c429b903b029bbd62621f11a9e286137minfrin * - certificate file / directory / nickname
54d22ed1c429b903b029bbd62621f11a9e286137minfrin * - certificate password (optional)
54d22ed1c429b903b029bbd62621f11a9e286137minfrin *
54d22ed1c429b903b029bbd62621f11a9e286137minfrin * This directive may only be used globally.
54d22ed1c429b903b029bbd62621f11a9e286137minfrin */
e8f95a682820a599fe41b22977010636be5c2717jimstatic const char *util_ldap_set_trusted_global_cert(cmd_parms *cmd,
e8f95a682820a599fe41b22977010636be5c2717jim void *dummy,
e8f95a682820a599fe41b22977010636be5c2717jim const char *type,
e8f95a682820a599fe41b22977010636be5c2717jim const char *file,
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe const char *password)
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes{
54d22ed1c429b903b029bbd62621f11a9e286137minfrin util_ldap_state_t *st =
54d22ed1c429b903b029bbd62621f11a9e286137minfrin (util_ldap_state_t *)ap_get_module_config(cmd->server->module_config,
54d22ed1c429b903b029bbd62621f11a9e286137minfrin &ldap_module);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
5aa455d45abacfa675c88d4ff53fbe97c44ce545bnicholes apr_finfo_t finfo;
1223ef8a85a044b5e3a8df29391a66530153aefcbnicholes apr_status_t rv;
54d22ed1c429b903b029bbd62621f11a9e286137minfrin int cert_type = 0;
d5cff0d8e871bf2528aadd8736fb50dc044b1e6dbnicholes apr_ldap_opt_tls_cert_t *cert;
5aa455d45abacfa675c88d4ff53fbe97c44ce545bnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes if (err != NULL) {
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes return err;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
54d22ed1c429b903b029bbd62621f11a9e286137minfrin /* handle the certificate type */
54d22ed1c429b903b029bbd62621f11a9e286137minfrin if (type) {
54d22ed1c429b903b029bbd62621f11a9e286137minfrin cert_type = util_ldap_parse_cert_type(type);
54d22ed1c429b903b029bbd62621f11a9e286137minfrin if (APR_LDAP_CA_TYPE_UNKNOWN == cert_type) {
54d22ed1c429b903b029bbd62621f11a9e286137minfrin return apr_psprintf(cmd->pool, "The certificate type %s is "
54d22ed1c429b903b029bbd62621f11a9e286137minfrin "not recognised. It should be one "
54d22ed1c429b903b029bbd62621f11a9e286137minfrin "of CA_DER, CA_BASE64, CA_CERT7_DB, "
54d22ed1c429b903b029bbd62621f11a9e286137minfrin "CA_SECMOD, CERT_DER, CERT_BASE64, "
54d22ed1c429b903b029bbd62621f11a9e286137minfrin "CERT_KEY3_DB, CERT_NICKNAME, "
54d22ed1c429b903b029bbd62621f11a9e286137minfrin "KEY_DER, KEY_BASE64", type);
54d22ed1c429b903b029bbd62621f11a9e286137minfrin }
54d22ed1c429b903b029bbd62621f11a9e286137minfrin }
54d22ed1c429b903b029bbd62621f11a9e286137minfrin else {
54d22ed1c429b903b029bbd62621f11a9e286137minfrin return "Certificate type was not specified.";
54d22ed1c429b903b029bbd62621f11a9e286137minfrin }
54d22ed1c429b903b029bbd62621f11a9e286137minfrin
796e4a7141265d8ed7036e4628161c6eafb2a789jorton ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, cmd->server,
54d22ed1c429b903b029bbd62621f11a9e286137minfrin "LDAP: SSL trusted global cert - %s (type %s)",
54d22ed1c429b903b029bbd62621f11a9e286137minfrin file, type);
54d22ed1c429b903b029bbd62621f11a9e286137minfrin
54d22ed1c429b903b029bbd62621f11a9e286137minfrin /* add the certificate to the global array */
d5cff0d8e871bf2528aadd8736fb50dc044b1e6dbnicholes cert = (apr_ldap_opt_tls_cert_t *)apr_array_push(st->global_certs);
54d22ed1c429b903b029bbd62621f11a9e286137minfrin cert->type = cert_type;
54d22ed1c429b903b029bbd62621f11a9e286137minfrin cert->path = file;
54d22ed1c429b903b029bbd62621f11a9e286137minfrin cert->password = password;
54d22ed1c429b903b029bbd62621f11a9e286137minfrin
54d22ed1c429b903b029bbd62621f11a9e286137minfrin /* if file is a file or path, fix the path */
54d22ed1c429b903b029bbd62621f11a9e286137minfrin if (cert_type != APR_LDAP_CA_TYPE_UNKNOWN &&
54d22ed1c429b903b029bbd62621f11a9e286137minfrin cert_type != APR_LDAP_CERT_TYPE_NICKNAME) {
54d22ed1c429b903b029bbd62621f11a9e286137minfrin
54d22ed1c429b903b029bbd62621f11a9e286137minfrin cert->path = ap_server_root_relative(cmd->pool, file);
54d22ed1c429b903b029bbd62621f11a9e286137minfrin if (cert->path &&
e8f95a682820a599fe41b22977010636be5c2717jim ((rv = apr_stat (&finfo, cert->path, APR_FINFO_MIN, cmd->pool))
e8f95a682820a599fe41b22977010636be5c2717jim != APR_SUCCESS))
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe {
54d22ed1c429b903b029bbd62621f11a9e286137minfrin ap_log_error(APLOG_MARK, APLOG_ERR, rv, cmd->server,
54d22ed1c429b903b029bbd62621f11a9e286137minfrin "LDAP: Could not open SSL trusted certificate "
54d22ed1c429b903b029bbd62621f11a9e286137minfrin "authority file - %s",
54d22ed1c429b903b029bbd62621f11a9e286137minfrin cert->path == NULL ? file : cert->path);
54d22ed1c429b903b029bbd62621f11a9e286137minfrin return "Invalid global certificate file path";
54d22ed1c429b903b029bbd62621f11a9e286137minfrin }
5aa455d45abacfa675c88d4ff53fbe97c44ce545bnicholes }
5aa455d45abacfa675c88d4ff53fbe97c44ce545bnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes return(NULL);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes}
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
54d22ed1c429b903b029bbd62621f11a9e286137minfrin/**
54d22ed1c429b903b029bbd62621f11a9e286137minfrin * Set LDAPTrustedClientCert.
54d22ed1c429b903b029bbd62621f11a9e286137minfrin *
54d22ed1c429b903b029bbd62621f11a9e286137minfrin * This directive takes either two or three arguments:
54d22ed1c429b903b029bbd62621f11a9e286137minfrin * - certificate type
54d22ed1c429b903b029bbd62621f11a9e286137minfrin * - certificate file / directory / nickname
54d22ed1c429b903b029bbd62621f11a9e286137minfrin * - certificate password (optional)
54d22ed1c429b903b029bbd62621f11a9e286137minfrin */
e8f95a682820a599fe41b22977010636be5c2717jimstatic const char *util_ldap_set_trusted_client_cert(cmd_parms *cmd,
e8f95a682820a599fe41b22977010636be5c2717jim void *config,
e8f95a682820a599fe41b22977010636be5c2717jim const char *type,
e8f95a682820a599fe41b22977010636be5c2717jim const char *file,
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe const char *password)
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes{
54d22ed1c429b903b029bbd62621f11a9e286137minfrin util_ldap_state_t *st =
54d22ed1c429b903b029bbd62621f11a9e286137minfrin (util_ldap_state_t *)ap_get_module_config(cmd->server->module_config,
54d22ed1c429b903b029bbd62621f11a9e286137minfrin &ldap_module);
54d22ed1c429b903b029bbd62621f11a9e286137minfrin apr_finfo_t finfo;
54d22ed1c429b903b029bbd62621f11a9e286137minfrin apr_status_t rv;
54d22ed1c429b903b029bbd62621f11a9e286137minfrin int cert_type = 0;
d5cff0d8e871bf2528aadd8736fb50dc044b1e6dbnicholes apr_ldap_opt_tls_cert_t *cert;
54d22ed1c429b903b029bbd62621f11a9e286137minfrin
54d22ed1c429b903b029bbd62621f11a9e286137minfrin /* handle the certificate type */
54d22ed1c429b903b029bbd62621f11a9e286137minfrin if (type) {
54d22ed1c429b903b029bbd62621f11a9e286137minfrin cert_type = util_ldap_parse_cert_type(type);
54d22ed1c429b903b029bbd62621f11a9e286137minfrin if (APR_LDAP_CA_TYPE_UNKNOWN == cert_type) {
54d22ed1c429b903b029bbd62621f11a9e286137minfrin return apr_psprintf(cmd->pool, "The certificate type \"%s\" is "
54d22ed1c429b903b029bbd62621f11a9e286137minfrin "not recognised. It should be one "
54d22ed1c429b903b029bbd62621f11a9e286137minfrin "of CERT_DER, CERT_BASE64, "
09338db7fdcf82ecc189195347da3a3ed5d0287abnicholes "CERT_NICKNAME, CERT_PFX,"
e8f95a682820a599fe41b22977010636be5c2717jim "KEY_DER, KEY_BASE64, KEY_PFX",
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe type);
54d22ed1c429b903b029bbd62621f11a9e286137minfrin }
54d22ed1c429b903b029bbd62621f11a9e286137minfrin else if (APR_LDAP_CA_TYPE_DER == cert_type ||
54d22ed1c429b903b029bbd62621f11a9e286137minfrin APR_LDAP_CA_TYPE_BASE64 == cert_type ||
54d22ed1c429b903b029bbd62621f11a9e286137minfrin APR_LDAP_CA_TYPE_CERT7_DB == cert_type ||
54d22ed1c429b903b029bbd62621f11a9e286137minfrin APR_LDAP_CA_TYPE_SECMOD == cert_type ||
09338db7fdcf82ecc189195347da3a3ed5d0287abnicholes APR_LDAP_CERT_TYPE_PFX == cert_type ||
54d22ed1c429b903b029bbd62621f11a9e286137minfrin APR_LDAP_CERT_TYPE_KEY3_DB == cert_type) {
54d22ed1c429b903b029bbd62621f11a9e286137minfrin return apr_psprintf(cmd->pool, "The certificate type \"%s\" is "
54d22ed1c429b903b029bbd62621f11a9e286137minfrin "only valid within a "
54d22ed1c429b903b029bbd62621f11a9e286137minfrin "LDAPTrustedGlobalCert directive. "
54d22ed1c429b903b029bbd62621f11a9e286137minfrin "Only CERT_DER, CERT_BASE64, "
54d22ed1c429b903b029bbd62621f11a9e286137minfrin "CERT_NICKNAME, KEY_DER, and "
54d22ed1c429b903b029bbd62621f11a9e286137minfrin "KEY_BASE64 may be used.", type);
54d22ed1c429b903b029bbd62621f11a9e286137minfrin }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
54d22ed1c429b903b029bbd62621f11a9e286137minfrin else {
54d22ed1c429b903b029bbd62621f11a9e286137minfrin return "Certificate type was not specified.";
54d22ed1c429b903b029bbd62621f11a9e286137minfrin }
54d22ed1c429b903b029bbd62621f11a9e286137minfrin
796e4a7141265d8ed7036e4628161c6eafb2a789jorton ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, cmd->server,
54d22ed1c429b903b029bbd62621f11a9e286137minfrin "LDAP: SSL trusted client cert - %s (type %s)",
54d22ed1c429b903b029bbd62621f11a9e286137minfrin file, type);
54d22ed1c429b903b029bbd62621f11a9e286137minfrin
54d22ed1c429b903b029bbd62621f11a9e286137minfrin /* add the certificate to the global array */
d5cff0d8e871bf2528aadd8736fb50dc044b1e6dbnicholes cert = (apr_ldap_opt_tls_cert_t *)apr_array_push(st->global_certs);
e8f95a682820a599fe41b22977010636be5c2717jim cert->type = cert_type;
54d22ed1c429b903b029bbd62621f11a9e286137minfrin cert->path = file;
54d22ed1c429b903b029bbd62621f11a9e286137minfrin cert->password = password;
54d22ed1c429b903b029bbd62621f11a9e286137minfrin
54d22ed1c429b903b029bbd62621f11a9e286137minfrin /* if file is a file or path, fix the path */
54d22ed1c429b903b029bbd62621f11a9e286137minfrin if (cert_type != APR_LDAP_CA_TYPE_UNKNOWN &&
54d22ed1c429b903b029bbd62621f11a9e286137minfrin cert_type != APR_LDAP_CERT_TYPE_NICKNAME) {
54d22ed1c429b903b029bbd62621f11a9e286137minfrin
54d22ed1c429b903b029bbd62621f11a9e286137minfrin cert->path = ap_server_root_relative(cmd->pool, file);
54d22ed1c429b903b029bbd62621f11a9e286137minfrin if (cert->path &&
e8f95a682820a599fe41b22977010636be5c2717jim ((rv = apr_stat (&finfo, cert->path, APR_FINFO_MIN, cmd->pool))
e8f95a682820a599fe41b22977010636be5c2717jim != APR_SUCCESS))
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe {
54d22ed1c429b903b029bbd62621f11a9e286137minfrin ap_log_error(APLOG_MARK, APLOG_ERR, rv, cmd->server,
54d22ed1c429b903b029bbd62621f11a9e286137minfrin "LDAP: Could not open SSL client certificate "
54d22ed1c429b903b029bbd62621f11a9e286137minfrin "file - %s",
54d22ed1c429b903b029bbd62621f11a9e286137minfrin cert->path == NULL ? file : cert->path);
54d22ed1c429b903b029bbd62621f11a9e286137minfrin return "Invalid client certificate file path";
54d22ed1c429b903b029bbd62621f11a9e286137minfrin }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
54d22ed1c429b903b029bbd62621f11a9e286137minfrin }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
54d22ed1c429b903b029bbd62621f11a9e286137minfrin return(NULL);
54d22ed1c429b903b029bbd62621f11a9e286137minfrin}
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
54d22ed1c429b903b029bbd62621f11a9e286137minfrin/**
54d22ed1c429b903b029bbd62621f11a9e286137minfrin * Set LDAPTrustedMode.
e8f95a682820a599fe41b22977010636be5c2717jim *
54d22ed1c429b903b029bbd62621f11a9e286137minfrin * This directive sets what encryption mode to use on a connection:
54d22ed1c429b903b029bbd62621f11a9e286137minfrin * - None (No encryption)
54d22ed1c429b903b029bbd62621f11a9e286137minfrin * - SSL (SSL encryption)
54d22ed1c429b903b029bbd62621f11a9e286137minfrin * - STARTTLS (TLS encryption)
e8f95a682820a599fe41b22977010636be5c2717jim */
e8f95a682820a599fe41b22977010636be5c2717jimstatic const char *util_ldap_set_trusted_mode(cmd_parms *cmd, void *dummy,
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe const char *mode)
54d22ed1c429b903b029bbd62621f11a9e286137minfrin{
54d22ed1c429b903b029bbd62621f11a9e286137minfrin util_ldap_state_t *st =
54d22ed1c429b903b029bbd62621f11a9e286137minfrin (util_ldap_state_t *)ap_get_module_config(cmd->server->module_config,
54d22ed1c429b903b029bbd62621f11a9e286137minfrin &ldap_module);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
796e4a7141265d8ed7036e4628161c6eafb2a789jorton ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, cmd->server,
54d22ed1c429b903b029bbd62621f11a9e286137minfrin "LDAP: SSL trusted mode - %s",
54d22ed1c429b903b029bbd62621f11a9e286137minfrin mode);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
54d22ed1c429b903b029bbd62621f11a9e286137minfrin if (0 == strcasecmp("NONE", mode)) {
54d22ed1c429b903b029bbd62621f11a9e286137minfrin st->secure = APR_LDAP_NONE;
54d22ed1c429b903b029bbd62621f11a9e286137minfrin }
54d22ed1c429b903b029bbd62621f11a9e286137minfrin else if (0 == strcasecmp("SSL", mode)) {
54d22ed1c429b903b029bbd62621f11a9e286137minfrin st->secure = APR_LDAP_SSL;
54d22ed1c429b903b029bbd62621f11a9e286137minfrin }
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe else if ( (0 == strcasecmp("TLS", mode))
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe || (0 == strcasecmp("STARTTLS", mode))) {
54d22ed1c429b903b029bbd62621f11a9e286137minfrin st->secure = APR_LDAP_STARTTLS;
54d22ed1c429b903b029bbd62621f11a9e286137minfrin }
54d22ed1c429b903b029bbd62621f11a9e286137minfrin else {
54d22ed1c429b903b029bbd62621f11a9e286137minfrin return "Invalid LDAPTrustedMode setting: must be one of NONE, "
54d22ed1c429b903b029bbd62621f11a9e286137minfrin "SSL, or TLS/STARTTLS";
54d22ed1c429b903b029bbd62621f11a9e286137minfrin }
54d22ed1c429b903b029bbd62621f11a9e286137minfrin
54d22ed1c429b903b029bbd62621f11a9e286137minfrin st->secure_set = 1;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes return(NULL);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes}
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
e8f95a682820a599fe41b22977010636be5c2717jimstatic const char *util_ldap_set_verify_srv_cert(cmd_parms *cmd,
e8f95a682820a599fe41b22977010636be5c2717jim void *dummy,
141e1368614dc7564e1627671361b01b4869b491bnicholes int mode)
141e1368614dc7564e1627671361b01b4869b491bnicholes{
141e1368614dc7564e1627671361b01b4869b491bnicholes util_ldap_state_t *st =
141e1368614dc7564e1627671361b01b4869b491bnicholes (util_ldap_state_t *)ap_get_module_config(cmd->server->module_config,
141e1368614dc7564e1627671361b01b4869b491bnicholes &ldap_module);
cbbfa8f4222ecc7b2e0f16db3032d0118d6a0accbnicholes const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
cbbfa8f4222ecc7b2e0f16db3032d0118d6a0accbnicholes
cbbfa8f4222ecc7b2e0f16db3032d0118d6a0accbnicholes if (err != NULL) {
cbbfa8f4222ecc7b2e0f16db3032d0118d6a0accbnicholes return err;
cbbfa8f4222ecc7b2e0f16db3032d0118d6a0accbnicholes }
141e1368614dc7564e1627671361b01b4869b491bnicholes
796e4a7141265d8ed7036e4628161c6eafb2a789jorton ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, cmd->server,
e8f95a682820a599fe41b22977010636be5c2717jim "LDAP: SSL verify server certificate - %s",
141e1368614dc7564e1627671361b01b4869b491bnicholes mode?"TRUE":"FALSE");
141e1368614dc7564e1627671361b01b4869b491bnicholes
141e1368614dc7564e1627671361b01b4869b491bnicholes st->verify_svr_cert = mode;
141e1368614dc7564e1627671361b01b4869b491bnicholes
141e1368614dc7564e1627671361b01b4869b491bnicholes return(NULL);
141e1368614dc7564e1627671361b01b4869b491bnicholes}
141e1368614dc7564e1627671361b01b4869b491bnicholes
141e1368614dc7564e1627671361b01b4869b491bnicholes
e8f95a682820a599fe41b22977010636be5c2717jimstatic const char *util_ldap_set_connection_timeout(cmd_parms *cmd,
e8f95a682820a599fe41b22977010636be5c2717jim void *dummy,
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe const char *ttl)
0894cd17fe3f614bf01dbf84f1414756bd5a34c3bnicholes{
e8f95a682820a599fe41b22977010636be5c2717jim util_ldap_state_t *st =
e8f95a682820a599fe41b22977010636be5c2717jim (util_ldap_state_t *)ap_get_module_config(cmd->server->module_config,
43c3e6a4b559b76b750c245ee95e2782c15b4296jim &ldap_module);
cbbfa8f4222ecc7b2e0f16db3032d0118d6a0accbnicholes const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
cbbfa8f4222ecc7b2e0f16db3032d0118d6a0accbnicholes
cbbfa8f4222ecc7b2e0f16db3032d0118d6a0accbnicholes if (err != NULL) {
cbbfa8f4222ecc7b2e0f16db3032d0118d6a0accbnicholes return err;
cbbfa8f4222ecc7b2e0f16db3032d0118d6a0accbnicholes }
0894cd17fe3f614bf01dbf84f1414756bd5a34c3bnicholes
1c9fe70e77b36d36ae34997fe25fe47beacf8709bnicholes#ifdef LDAP_OPT_NETWORK_TIMEOUT
0894cd17fe3f614bf01dbf84f1414756bd5a34c3bnicholes st->connectionTimeout = atol(ttl);
0894cd17fe3f614bf01dbf84f1414756bd5a34c3bnicholes
e8f95a682820a599fe41b22977010636be5c2717jim ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, cmd->server,
368a30e0cf9ddb3fda08e6b443dd01410277cfb6jim "[%" APR_PID_T_FMT "] ldap connection: Setting connection timeout to "
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe "%ld seconds.", getpid(), st->connectionTimeout);
1c9fe70e77b36d36ae34997fe25fe47beacf8709bnicholes#else
4990e910dd8574b9b40beda0cf1aaa72334d6837bnicholes ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, cmd->server,
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe "LDAP: Connection timout option not supported by the "
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe "LDAP SDK in use." );
1c9fe70e77b36d36ae34997fe25fe47beacf8709bnicholes#endif
0894cd17fe3f614bf01dbf84f1414756bd5a34c3bnicholes
0894cd17fe3f614bf01dbf84f1414756bd5a34c3bnicholes return NULL;
0894cd17fe3f614bf01dbf84f1414756bd5a34c3bnicholes}
0894cd17fe3f614bf01dbf84f1414756bd5a34c3bnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
8113dac419143273351446c3ad653f3fe5ba5cfdwrowestatic void *util_ldap_create_config(apr_pool_t *p, server_rec *s)
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes{
e8f95a682820a599fe41b22977010636be5c2717jim util_ldap_state_t *st =
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes (util_ldap_state_t *)apr_pcalloc(p, sizeof(util_ldap_state_t));
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
a0b44ec81b32ffb946537d4e43e1c3a3f7594137gregames /* Create a per vhost pool for mod_ldap to use, serialized with
1233ffe2092021833c2a642f1017d6c332075469gregames * st->mutex (also one per vhost). both are replicated by fork(),
1233ffe2092021833c2a642f1017d6c332075469gregames * no shared memory managed by either.
a0b44ec81b32ffb946537d4e43e1c3a3f7594137gregames */
490046d2a164ad86cc63bd789f32eaed663d239abnicholes apr_pool_create(&st->pool, p);
490046d2a164ad86cc63bd789f32eaed663d239abnicholes#if APR_HAS_THREADS
490046d2a164ad86cc63bd789f32eaed663d239abnicholes apr_thread_mutex_create(&st->mutex, APR_THREAD_MUTEX_DEFAULT, st->pool);
490046d2a164ad86cc63bd789f32eaed663d239abnicholes#endif
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes st->cache_bytes = 100000;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes st->search_cache_ttl = 600000000;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes st->search_cache_size = 1024;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes st->compare_cache_ttl = 600000000;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes st->compare_cache_size = 1024;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes st->connections = NULL;
54d22ed1c429b903b029bbd62621f11a9e286137minfrin st->ssl_supported = 0;
54d22ed1c429b903b029bbd62621f11a9e286137minfrin st->global_certs = apr_array_make(p, 10, sizeof(apr_ldap_opt_tls_cert_t));
54d22ed1c429b903b029bbd62621f11a9e286137minfrin st->client_certs = apr_array_make(p, 10, sizeof(apr_ldap_opt_tls_cert_t));
54d22ed1c429b903b029bbd62621f11a9e286137minfrin st->secure = APR_LDAP_NONE;
54d22ed1c429b903b029bbd62621f11a9e286137minfrin st->secure_set = 0;
0894cd17fe3f614bf01dbf84f1414756bd5a34c3bnicholes st->connectionTimeout = 10;
141e1368614dc7564e1627671361b01b4869b491bnicholes st->verify_svr_cert = 1;
54d22ed1c429b903b029bbd62621f11a9e286137minfrin
54d22ed1c429b903b029bbd62621f11a9e286137minfrin return st;
54d22ed1c429b903b029bbd62621f11a9e286137minfrin}
54d22ed1c429b903b029bbd62621f11a9e286137minfrin
e8f95a682820a599fe41b22977010636be5c2717jimstatic void *util_ldap_merge_config(apr_pool_t *p, void *basev,
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe void *overridesv)
54d22ed1c429b903b029bbd62621f11a9e286137minfrin{
54d22ed1c429b903b029bbd62621f11a9e286137minfrin util_ldap_state_t *st = apr_pcalloc(p, sizeof(util_ldap_state_t));
54d22ed1c429b903b029bbd62621f11a9e286137minfrin util_ldap_state_t *base = (util_ldap_state_t *) basev;
54d22ed1c429b903b029bbd62621f11a9e286137minfrin util_ldap_state_t *overrides = (util_ldap_state_t *) overridesv;
54d22ed1c429b903b029bbd62621f11a9e286137minfrin
9c247afacdbb56fa794715f2ac218eb1cae39fe8bnicholes st->pool = overrides->pool;
490046d2a164ad86cc63bd789f32eaed663d239abnicholes#if APR_HAS_THREADS
9c247afacdbb56fa794715f2ac218eb1cae39fe8bnicholes st->mutex = overrides->mutex;
490046d2a164ad86cc63bd789f32eaed663d239abnicholes#endif
54d22ed1c429b903b029bbd62621f11a9e286137minfrin
9c247afacdbb56fa794715f2ac218eb1cae39fe8bnicholes /* The cache settings can not be modified in a
9c247afacdbb56fa794715f2ac218eb1cae39fe8bnicholes virtual host since all server use the same
9c247afacdbb56fa794715f2ac218eb1cae39fe8bnicholes shared memory cache. */
54d22ed1c429b903b029bbd62621f11a9e286137minfrin st->cache_bytes = base->cache_bytes;
54d22ed1c429b903b029bbd62621f11a9e286137minfrin st->search_cache_ttl = base->search_cache_ttl;
54d22ed1c429b903b029bbd62621f11a9e286137minfrin st->search_cache_size = base->search_cache_size;
54d22ed1c429b903b029bbd62621f11a9e286137minfrin st->compare_cache_ttl = base->compare_cache_ttl;
54d22ed1c429b903b029bbd62621f11a9e286137minfrin st->compare_cache_size = base->compare_cache_size;
9ab5933c174cb21de69e8305f80544cbe7ed2a7ccovener st->util_ldap_cache_lock = base->util_ldap_cache_lock;
9c247afacdbb56fa794715f2ac218eb1cae39fe8bnicholes
9c247afacdbb56fa794715f2ac218eb1cae39fe8bnicholes st->connections = NULL;
9c247afacdbb56fa794715f2ac218eb1cae39fe8bnicholes st->ssl_supported = 0;
e8f95a682820a599fe41b22977010636be5c2717jim st->global_certs = apr_array_append(p, base->global_certs,
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe overrides->global_certs);
e8f95a682820a599fe41b22977010636be5c2717jim st->client_certs = apr_array_append(p, base->client_certs,
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe overrides->client_certs);
e8f95a682820a599fe41b22977010636be5c2717jim st->secure = (overrides->secure_set == 0) ? base->secure
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe : overrides->secure;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
cbbfa8f4222ecc7b2e0f16db3032d0118d6a0accbnicholes /* These LDAP connection settings can not be overwritten in
cbbfa8f4222ecc7b2e0f16db3032d0118d6a0accbnicholes a virtual host. Once set in the base server, they must
cbbfa8f4222ecc7b2e0f16db3032d0118d6a0accbnicholes remain the same. None of the LDAP SDKs seem to be able
cbbfa8f4222ecc7b2e0f16db3032d0118d6a0accbnicholes to handle setting the verify_svr_cert flag on a
cbbfa8f4222ecc7b2e0f16db3032d0118d6a0accbnicholes per-connection basis. The OpenLDAP client appears to be
cbbfa8f4222ecc7b2e0f16db3032d0118d6a0accbnicholes able to handle the connection timeout per-connection
cbbfa8f4222ecc7b2e0f16db3032d0118d6a0accbnicholes but the Novell SDK cannot. Allowing the timeout to
cbbfa8f4222ecc7b2e0f16db3032d0118d6a0accbnicholes be set by each vhost is of little value so rather than
cbbfa8f4222ecc7b2e0f16db3032d0118d6a0accbnicholes trying to make special expections for one LDAP SDK, GLOBAL_ONLY
cbbfa8f4222ecc7b2e0f16db3032d0118d6a0accbnicholes is being enforced on this setting as well. */
cbbfa8f4222ecc7b2e0f16db3032d0118d6a0accbnicholes st->connectionTimeout = base->connectionTimeout;
cbbfa8f4222ecc7b2e0f16db3032d0118d6a0accbnicholes st->verify_svr_cert = base->verify_svr_cert;
9c247afacdbb56fa794715f2ac218eb1cae39fe8bnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes return st;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes}
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholesstatic apr_status_t util_ldap_cleanup_module(void *data)
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes{
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes server_rec *s = data;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes util_ldap_state_t *st = (util_ldap_state_t *)ap_get_module_config(
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes s->module_config, &ldap_module);
e8f95a682820a599fe41b22977010636be5c2717jim
54d22ed1c429b903b029bbd62621f11a9e286137minfrin if (st->ssl_supported) {
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes apr_ldap_ssl_deinit();
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes return APR_SUCCESS;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes}
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
e8f95a682820a599fe41b22977010636be5c2717jimstatic int util_ldap_post_config(apr_pool_t *p, apr_pool_t *plog,
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes apr_pool_t *ptemp, server_rec *s)
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes{
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes apr_status_t result;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes server_rec *s_vhost;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes util_ldap_state_t *st_vhost;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe util_ldap_state_t *st = (util_ldap_state_t *)
e8f95a682820a599fe41b22977010636be5c2717jim ap_get_module_config(s->module_config,
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe &ldap_module);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes void *data;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes const char *userdata_key = "util_ldap_init";
d5cff0d8e871bf2528aadd8736fb50dc044b1e6dbnicholes apr_ldap_err_t *result_err = NULL;
d5cff0d8e871bf2528aadd8736fb50dc044b1e6dbnicholes int rc;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes /* util_ldap_post_config() will be called twice. Don't bother
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * going through all of the initialization on the first call
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * because it will just be thrown away.*/
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes apr_pool_userdata_get(&data, userdata_key, s->process->pool);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes if (!data) {
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes apr_pool_userdata_set((const void *)1, userdata_key,
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes apr_pool_cleanup_null, s->process->pool);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes#if APR_HAS_SHARED_MEMORY
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes /* If the cache file already exists then delete it. Otherwise we are
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * going to run into problems creating the shared memory. */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes if (st->cache_file) {
490046d2a164ad86cc63bd789f32eaed663d239abnicholes char *lck_file = apr_pstrcat(ptemp, st->cache_file, ".lck",
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe NULL);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes apr_file_remove(lck_file, ptemp);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes#endif
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes return OK;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes#if APR_HAS_SHARED_MEMORY
e8f95a682820a599fe41b22977010636be5c2717jim /* initializing cache if shared memory size is not zero and we already
e8f95a682820a599fe41b22977010636be5c2717jim * don't have shm address
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes if (!st->cache_shm && st->cache_bytes > 0) {
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes#endif
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes result = util_ldap_cache_init(p, st);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes if (result != APR_SUCCESS) {
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes ap_log_error(APLOG_MARK, APLOG_ERR, result, s,
e70cf415769ad0b3704e98b3f6da38e916ff7228jorton "LDAP cache: could not create shared memory segment");
e70cf415769ad0b3704e98b3f6da38e916ff7228jorton return DONE;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes#if APR_HAS_SHARED_MEMORY
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes if (st->cache_file) {
e8f95a682820a599fe41b22977010636be5c2717jim st->lock_file = apr_pstrcat(st->pool, st->cache_file, ".lck",
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe NULL);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes#endif
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
e8f95a682820a599fe41b22977010636be5c2717jim result = apr_global_mutex_create(&st->util_ldap_cache_lock,
e8f95a682820a599fe41b22977010636be5c2717jim st->lock_file, APR_LOCK_DEFAULT,
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe st->pool);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes if (result != APR_SUCCESS) {
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes return result;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d266c3777146d36a4c23c17aad6f153aebea1bf4jorton#ifdef AP_NEED_SET_MUTEX_PERMS
d266c3777146d36a4c23c17aad6f153aebea1bf4jorton result = unixd_set_global_mutex_perms(st->util_ldap_cache_lock);
d266c3777146d36a4c23c17aad6f153aebea1bf4jorton if (result != APR_SUCCESS) {
e8f95a682820a599fe41b22977010636be5c2717jim ap_log_error(APLOG_MARK, APLOG_CRIT, result, s,
d266c3777146d36a4c23c17aad6f153aebea1bf4jorton "LDAP cache: failed to set mutex permissions");
d266c3777146d36a4c23c17aad6f153aebea1bf4jorton return result;
d266c3777146d36a4c23c17aad6f153aebea1bf4jorton }
d266c3777146d36a4c23c17aad6f153aebea1bf4jorton#endif
d266c3777146d36a4c23c17aad6f153aebea1bf4jorton
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;
e8f95a682820a599fe41b22977010636be5c2717jim ap_log_error(APLOG_MARK, APLOG_DEBUG, result, s,
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe "LDAP merging Shared Cache conf: shm=0x%pp rmm=0x%pp "
e8f95a682820a599fe41b22977010636be5c2717jim "for VHOST: %s", st->cache_shm, st->cache_rmm,
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe s_vhost->server_hostname);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes#endif
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes st_vhost->lock_file = st->lock_file;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes s_vhost = s_vhost->next;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes#if APR_HAS_SHARED_MEMORY
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes else {
e8f95a682820a599fe41b22977010636be5c2717jim ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe "LDAP cache: LDAPSharedCacheSize is zero, disabling "
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe "shared memory cache");
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes#endif
e8f95a682820a599fe41b22977010636be5c2717jim
e8f95a682820a599fe41b22977010636be5c2717jim /* log the LDAP SDK used
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes {
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes apr_ldap_err_t *result = NULL;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes apr_ldap_info(p, &(result));
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes if (result != NULL) {
e70cf415769ad0b3704e98b3f6da38e916ff7228jorton ap_log_error(APLOG_MARK, APLOG_INFO, 0, s, "%s", result->reason);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes apr_pool_cleanup_register(p, s, util_ldap_cleanup_module,
e8f95a682820a599fe41b22977010636be5c2717jim util_ldap_cleanup_module);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
54d22ed1c429b903b029bbd62621f11a9e286137minfrin /*
54d22ed1c429b903b029bbd62621f11a9e286137minfrin * Initialize SSL support, and log the result for the benefit of the admin.
54d22ed1c429b903b029bbd62621f11a9e286137minfrin *
54d22ed1c429b903b029bbd62621f11a9e286137minfrin * If SSL is not supported it is not necessarily an error, as the
54d22ed1c429b903b029bbd62621f11a9e286137minfrin * application may not want to use it.
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes */
e8f95a682820a599fe41b22977010636be5c2717jim rc = apr_ldap_ssl_init(p,
e8f95a682820a599fe41b22977010636be5c2717jim NULL,
e8f95a682820a599fe41b22977010636be5c2717jim 0,
d5cff0d8e871bf2528aadd8736fb50dc044b1e6dbnicholes &(result_err));
54d22ed1c429b903b029bbd62621f11a9e286137minfrin if (APR_SUCCESS == rc) {
ebe5305f8b22507374358f32b74d12fb50c05a25covener rc = apr_ldap_set_option(ptemp, NULL, APR_LDAP_OPT_TLS_CERT,
54d22ed1c429b903b029bbd62621f11a9e286137minfrin (void *)st->global_certs, &(result_err));
54d22ed1c429b903b029bbd62621f11a9e286137minfrin }
54d22ed1c429b903b029bbd62621f11a9e286137minfrin
54d22ed1c429b903b029bbd62621f11a9e286137minfrin if (APR_SUCCESS == rc) {
54d22ed1c429b903b029bbd62621f11a9e286137minfrin st->ssl_supported = 1;
e70cf415769ad0b3704e98b3f6da38e916ff7228jorton ap_log_error(APLOG_MARK, APLOG_INFO, 0, s,
e70cf415769ad0b3704e98b3f6da38e916ff7228jorton "LDAP: SSL support available" );
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes else {
54d22ed1c429b903b029bbd62621f11a9e286137minfrin st->ssl_supported = 0;
e8f95a682820a599fe41b22977010636be5c2717jim ap_log_error(APLOG_MARK, APLOG_INFO, 0, s,
e70cf415769ad0b3704e98b3f6da38e916ff7228jorton "LDAP: SSL support unavailable%s%s",
e70cf415769ad0b3704e98b3f6da38e916ff7228jorton result_err ? ": " : "",
e70cf415769ad0b3704e98b3f6da38e916ff7228jorton result_err ? result_err->reason : "");
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
0894cd17fe3f614bf01dbf84f1414756bd5a34c3bnicholes
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,
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe st->lock_file, p);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes if (sts != APR_SUCCESS) {
af6d8b02b2fd4ea9a0f6bfb95940d6075030e9a7minfrin ap_log_error(APLOG_MARK, APLOG_CRIT, sts, s,
41774018aa66ddb54ce7fd8fe049ccf3b3f7262aminfrin "Failed to initialise global mutex %s in child process %"
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe APR_PID_T_FMT ".",
af6d8b02b2fd4ea9a0f6bfb95940d6075030e9a7minfrin st->lock_file, getpid());
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes }
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes}
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
e025b9c2dbc3e2873142a775c37336a75ead222bjortonstatic const command_rec util_ldap_cmds[] = {
e8f95a682820a599fe41b22977010636be5c2717jim AP_INIT_TAKE1("LDAPSharedCacheSize", util_ldap_set_cache_bytes,
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe NULL, RSRC_CONF,
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe "Set the size of the shared memory cache (in bytes). Use "
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe "0 to disable the shared memory cache. (default: 100000)"),
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe
e8f95a682820a599fe41b22977010636be5c2717jim AP_INIT_TAKE1("LDAPSharedCacheFile", util_ldap_set_cache_file,
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe NULL, RSRC_CONF,
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe "Set the file name for the shared memory cache."),
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe
e8f95a682820a599fe41b22977010636be5c2717jim AP_INIT_TAKE1("LDAPCacheEntries", util_ldap_set_cache_entries,
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe NULL, RSRC_CONF,
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe "Set the maximum number of entries that are possible in the "
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe "LDAP search cache. Use 0 for no limit. "
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe "-1 disables the cache. (default: 1024)"),
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe
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 "
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe "in the LDAP compare cache. Use 0 for no limit. "
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe "Use -1 to disable the cache. (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,
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe "Takes three args; the file and/or directory containing "
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe "the trusted CA certificates (and global client certs "
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe "for Netware) used to validate the LDAP server. Second "
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe "arg is the cert type for the first arg, one of CA_DER, "
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe "CA_BASE64, CA_CERT7_DB, CA_SECMOD, CERT_DER, CERT_BASE64, "
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe "CERT_KEY3_DB, CERT_NICKNAME, KEY_DER, or KEY_BASE64. "
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe "Third arg is an optional passphrase if applicable."),
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe AP_INIT_TAKE23("LDAPTrustedClientCert", util_ldap_set_trusted_client_cert,
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe NULL, RSRC_CONF,
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe "Takes three args; the file and/or directory containing "
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe "the client certificate, or certificate ID used to "
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe "validate this LDAP client. Second arg is the cert type "
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe "for the first arg, one of CA_DER, CA_BASE64, CA_CERT7_DB, "
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe "CA_SECMOD, CERT_DER, CERT_BASE64, CERT_KEY3_DB, "
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe "CERT_NICKNAME, KEY_DER, or KEY_BASE64. Third arg is an "
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe "optional passphrase if 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,
141e1368614dc7564e1627671361b01b4869b491bnicholes "Set to 'ON' requires that the server certificate be verified "
141e1368614dc7564e1627671361b01b4869b491bnicholes "before a secure LDAP connection can be establish. Default '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
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes {NULL}
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes};
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholesstatic void util_ldap_register_hooks(apr_pool_t *p)
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes{
f43b67c5a9d29b572eac916f8335cedc80c908bebnicholes APR_REGISTER_OPTIONAL_FN(uldap_connection_open);
f43b67c5a9d29b572eac916f8335cedc80c908bebnicholes APR_REGISTER_OPTIONAL_FN(uldap_connection_close);
f43b67c5a9d29b572eac916f8335cedc80c908bebnicholes APR_REGISTER_OPTIONAL_FN(uldap_connection_unbind);
f43b67c5a9d29b572eac916f8335cedc80c908bebnicholes APR_REGISTER_OPTIONAL_FN(uldap_connection_cleanup);
f43b67c5a9d29b572eac916f8335cedc80c908bebnicholes APR_REGISTER_OPTIONAL_FN(uldap_connection_find);
f43b67c5a9d29b572eac916f8335cedc80c908bebnicholes APR_REGISTER_OPTIONAL_FN(uldap_cache_comparedn);
f43b67c5a9d29b572eac916f8335cedc80c908bebnicholes APR_REGISTER_OPTIONAL_FN(uldap_cache_compare);
f43b67c5a9d29b572eac916f8335cedc80c908bebnicholes APR_REGISTER_OPTIONAL_FN(uldap_cache_checkuserid);
f43b67c5a9d29b572eac916f8335cedc80c908bebnicholes APR_REGISTER_OPTIONAL_FN(uldap_cache_getuserdn);
f43b67c5a9d29b572eac916f8335cedc80c908bebnicholes APR_REGISTER_OPTIONAL_FN(uldap_ssl_supported);
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj APR_REGISTER_OPTIONAL_FN(uldap_cache_check_subgroups);
f43b67c5a9d29b572eac916f8335cedc80c908bebnicholes
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
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowemodule AP_MODULE_DECLARE_DATA ldap_module = {
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes STANDARD20_MODULE_STUFF,
f05787953018140838ad51456c86c965d6a86267jim NULL, /* 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};