util_ldap.c revision f43b67c5a9d29b572eac916f8335cedc80c908be
/* Copyright 2001-2005 The Apache Software Foundation or its licensors, as
* applicable.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*
* util_ldap.c: LDAP things
*
* Original code from auth_ldap module for Apache v1.3:
* Copyright 1998, 1999 Enbridge Pipelines Inc.
* Copyright 1999-2001 Dave Carrigan
*/
#include "httpd.h"
#include "http_config.h"
#include "http_core.h"
#include "http_log.h"
#include "http_protocol.h"
#include "http_request.h"
#include "util_ldap.h"
#include "util_ldap_cache.h"
#include <apr_strings.h>
#include <unistd.h>
#endif
#if !APR_HAS_LDAP
#endif
#ifdef AP_NEED_SET_MUTEX_PERMS
#include "unixd.h"
#endif
/* defines for certificate file types
*/
#define LDAP_CA_TYPE_UNKNOWN 0
#define LDAP_CA_TYPE_DER 1
#define LDAP_CA_TYPE_BASE64 2
#define LDAP_CA_TYPE_CERT7_DB 3
int util_ldap_handler(request_rec *r);
/*
* Some definitions to help between various versions of apache.
*/
#ifndef DOCTYPE_HTML_2_0
#define DOCTYPE_HTML_2_0 "<!DOCTYPE HTML PUBLIC \"-//IETF//" \
"DTD HTML 2.0//EN\">\n"
#endif
#ifndef DOCTYPE_HTML_3_2
#define DOCTYPE_HTML_3_2 "<!DOCTYPE HTML PUBLIC \"-//W3C//" \
"DTD HTML 3.2 Final//EN\">\n"
#endif
#ifndef DOCTYPE_HTML_4_0S
#define DOCTYPE_HTML_4_0S "<!DOCTYPE HTML PUBLIC \"-//W3C//" \
"DTD HTML 4.0//EN\"\n" \
#endif
#ifndef DOCTYPE_HTML_4_0T
#define DOCTYPE_HTML_4_0T "<!DOCTYPE HTML PUBLIC \"-//W3C//" \
"DTD HTML 4.0 Transitional//EN\"\n" \
#endif
#ifndef DOCTYPE_HTML_4_0F
#define DOCTYPE_HTML_4_0F "<!DOCTYPE HTML PUBLIC \"-//W3C//" \
"DTD HTML 4.0 Frameset//EN\"\n" \
#endif
#define LDAP_CACHE_LOCK() \
if (st->util_ldap_cache_lock) \
#define LDAP_CACHE_UNLOCK() \
if (st->util_ldap_cache_lock) \
{
if (*str) {
}
if (newstr) {
}
}
/*
* Status Handler
* --------------
*
* This handler generates a status page about the current performance of
* the LDAP cache. It is enabled as follows:
*
* <Location /ldap-status>
* SetHandler ldap-status
* </Location>
*
*/
int util_ldap_handler(request_rec *r)
{
util_ldap_state_t *st = (util_ldap_state_t *)ap_get_module_config(r->server->module_config, &ldap_module);
if (r->method_number != M_GET)
return DECLINED;
return DECLINED;
}
r->content_type = "text/html";
if (r->header_only)
return OK;
"<html><head><title>LDAP Cache Information</title></head>\n", r);
ap_rputs("<body bgcolor='#ffffff'><h1 align=center>LDAP Cache Information</h1>\n", r);
util_ald_cache_display(r, st);
return OK;
}
/* ------------------------------------------------------------------ */
/*
* Closes an LDAP connection by unlocking it. The next time
* uldap_connection_find() is called this connection will be
* available for reuse.
*/
{
/*
* QUESTION:
*
* Is it safe leaving bound connections floating around between the
* different modules? Keeping the user bound is a performance boost,
* but it is also a potential security problem - maybe.
*
* For now we unbind the user when we finish with a connection, but
* we don't have to...
*/
/* mark our connection as available for reuse */
#if APR_HAS_THREADS
#endif
}
/*
* Destroys an LDAP connection by unbinding and closing the connection to
* the LDAP server. It is used to bring the connection back to a known
* state after an error, and during pool cleanup.
*/
{
if (ldc) {
}
}
return APR_SUCCESS;
}
/*
* Clean up an LDAP connection by unbinding and unlocking the connection.
* This function is registered with the pool cleanup function - causing
* the LDAP connections to be shut down cleanly on graceful restart.
*/
{
if (ldc) {
/* unbind and disconnect from the LDAP server */
/* free the username and password */
}
}
/* unlock this entry */
}
return APR_SUCCESS;
}
/*
* Connect to the LDAP server and binds. Does not connect if already
* connected (i.e. ldc->ldap is non-NULL.) Does not bind if already bound.
*
* Returns LDAP_SUCCESS on success; and an error code on failure
*/
{
int rc = 0;
int failures = 0;
int version = LDAP_VERSION3;
/* sanity check for NULL */
if (!ldc) {
return -1;
}
/* If the connection is already bound, return
*/
{
return LDAP_SUCCESS;
}
/* create the ldap session handle
*/
{
/* Since the host will include a port if the default port is not used,
* always specify the default ports for the port parameter. This will
* allow a host string that contains multiple hosts the ability to mix
* some hosts with ports and some without. All hosts which do not
* specify a port will use the default port.
*/
&(result));
}
{
}
else {
}
}
/* set client certificates */
}
}
}
}
/* Set the alias dereferencing option */
/* always default to LDAP V3 */
}
/* loop trying to bind up to 10 times if LDAP_SERVER_DOWN error is
* returned. Break out of the loop on Success or any other error.
*
* NOTE: Looping is probably not a great idea. If the server isn't
* responding the chances it will respond after a few tries are poor.
* However, the original code looped and it only happens on
* the error condition.
*/
{
if (LDAP_SERVER_DOWN != rc) {
break;
}
}
/* free the handle if there was an error
*/
if (LDAP_SUCCESS != rc)
{
}
else {
}
return(rc);
}
/*
* Compare client certificate arrays.
*
* Returns 1 on compare failure, 0 otherwise.
*/
{
int i = 0;
/* arrays both NULL? if so, then equal */
return 0;
}
/* arrays different length or either NULL? If so, then not equal */
return 1;
}
/* run an actual comparison */
return 1;
}
}
/* if we got here, the cert arrays were identical */
return 0;
}
/*
* Find an existing ldap connection struct that matches the
* provided ldap connection parameters.
*
* If not found in the cache, a new ldc structure will be allocated from st->pool
* and returned to the caller. If found in the cache, a pointer to the existing
* ldc structure will be returned.
*/
struct util_ldap_connection_t *l, *p; /* To traverse the linked list */
int secureflag = secure;
&ldap_module);
#if APR_HAS_THREADS
/* mutex lock this function */
}
#endif
if (secure < APR_LDAP_NONE) {
}
/* Search for an exact connection match in the list that is not
* being used.
*/
#if APR_HAS_THREADS
#endif
break;
}
#if APR_HAS_THREADS
/* If this connection didn't match the criteria, then we
* need to unlock the mutex so it is available to be reused.
*/
}
#endif
p = l;
}
/* If nothing found, search again, but we don't care about the
* binddn and bindpw this time.
*/
if (!l) {
#if APR_HAS_THREADS
#endif
/* the bind credentials have changed */
l->bound = 0;
break;
}
#if APR_HAS_THREADS
/* If this connection didn't match the criteria, then we
* need to unlock the mutex so it is available to be reused.
*/
}
#endif
p = l;
}
}
/* artificially disable cache */
/* l = NULL; */
/* If no connection what found after the second search, we
* must create one.
*/
if (!l) {
/*
* Add the new connection entry to the linked list. Note that we
* don't actually establish an LDAP connection yet; that happens
* the first time authentication is requested.
*/
/* create the details to the pool in st */
#if APR_HAS_THREADS
#endif
l->bound = 0;
/* The security mode after parsing the URL will always be either
* APR_LDAP_NONE (ldap://) or APR_LDAP_SSL (ldaps://).
* If the security setting is NONE, override it to the security
* setting optionally supplied by the admin using LDAPTrustedMode
*/
l->secure = secureflag;
/* save away a copy of the client cert list that is presently valid */
/* add the cleanup to the pool */
apr_pool_cleanup_register(l->pool, l,
if (p) {
p->next = l;
}
else {
st->connections = l;
}
}
#if APR_HAS_THREADS
#endif
return l;
}
/* ------------------------------------------------------------------ */
/*
* Compares two DNs to see if they're equal. The only way to do this correctly is to
* search for the dn and then do ldap_get_dn() on the result. This should match the
* initial dn, since it would have been also retrieved with ldap_get_dn(). This is
* expensive, so if the configuration value compare_dn_on_server is
* false, just does an ordinary strcmp.
*
* The lock for the ldap cache should already be acquired.
*/
int compare_dn_on_server)
{
int result = 0;
int failures = 0;
char *searchdn;
util_ldap_state_t *st = (util_ldap_state_t *)ap_get_module_config(r->server->module_config, &ldap_module);
/* get cache entry (or create one) */
}
/* a simple compare? */
if (!compare_dn_on_server) {
/* unlock this read lock */
return LDAP_COMPARE_FALSE;
}
else {
return LDAP_COMPARE_TRUE;
}
}
if (curl) {
/* no - it's a server side compare */
/* is it in the compare cache? */
/* If it's in the cache, it's good */
/* unlock this read lock */
return LDAP_COMPARE_TRUE;
}
/* unlock this read lock */
}
if (failures++ > 10) {
/* too many failures */
return result;
}
/* make a server connection */
/* connect to server failed */
return result;
}
/* search for reqdn */
goto start_over;
}
if (result != LDAP_SUCCESS) {
/* search for reqdn failed - no match */
return result;
}
/* compare unsuccessful */
}
else {
if (curl) {
/* compare successful - add to the compare cache */
}
}
}
return result;
}
/*
* Does an generic ldap_compare operation. It accepts a cache that it will use
* to lookup the compare in the cache. We cache two kinds of compares
* (require group compares) and (require user compares). Each compare has a different
* cache node: require group includes the DN; require user does not because the
* require user cache is owned by the
*
*/
{
int result = 0;
int failures = 0;
&ldap_module);
/* get cache entry (or create one) */
}
if (curl) {
/* make a comparison to the cache */
curtime = apr_time_now();
the_compare_node.result = 0;
if (compare_nodep != NULL) {
/* found it... */
/* ...but it is too old */
}
else {
/* ...and it is good */
/* unlock this read lock */
return compare_nodep->result;
}
return compare_nodep->result;
}
return compare_nodep->result;
}
else {
return compare_nodep->result;
}
}
}
/* unlock this read lock */
}
if (failures++ > 10) {
/* too many failures */
return result;
}
/* connect failed */
return result;
}
(char *)dn,
(char *)attrib,
(char *)value))
== LDAP_SERVER_DOWN) {
/* connection failed - try again */
goto start_over;
}
if ((LDAP_COMPARE_TRUE == result) ||
(LDAP_COMPARE_FALSE == result) ||
(LDAP_NO_SUCH_ATTRIBUTE == result)) {
if (curl) {
/* compare completed; caching result */
/* If the node doesn't exist then insert it, otherwise just update it with
the last results */
if ((compare_nodep == NULL) ||
}
else {
}
}
if (LDAP_COMPARE_TRUE == result) {
return LDAP_COMPARE_TRUE;
}
else if (LDAP_COMPARE_FALSE == result) {
return LDAP_COMPARE_FALSE;
}
else {
return LDAP_NO_SUCH_ATTRIBUTE;
}
}
return result;
}
const char ***retvals)
{
int numvals = 0;
int result = 0;
char *dn;
int count;
int failures = 0;
&ldap_module);
/* Get the cache node for this url */
}
if (curl) {
if (search_nodep != NULL) {
/* found entry in search cache... */
curtime = apr_time_now();
/*
* Remove this item from the cache if its expired. If the sent password
* doesn't match the storepassword, the entry will be removed and readded
* later if the credentials pass authentication.
*/
/* ...but entry is too old */
}
/* ...and entry is valid */
return LDAP_SUCCESS;
}
}
/* unlock this read lock */
}
/*
* At this point, there is no valid cached search, so lets do the search.
*/
/*
* If any LDAP operation fails due to LDAP_SERVER_DOWN, control returns here.
*/
if (failures++ > 10) {
return result;
}
return result;
}
/* try do the search */
goto start_over;
}
/* if there is an error (including LDAP_NO_SUCH_OBJECT) return now */
if (result != LDAP_SUCCESS) {
return result;
}
/*
* We should have found exactly one entry; to find a different
* number is an error.
*/
if (count != 1)
{
if (count == 0 )
else
return LDAP_NO_SUCH_OBJECT;
}
/* Grab the dn, copy it into the pool, and free it again */
/*
* A bind to the server with an empty password always succeeds, so
* we check to ensure that the password is not empty. This implies
* that users who actually do have empty passwords will never be
* able to authenticate with this module. I don't see this as a big
* problem.
*/
return LDAP_INVALID_CREDENTIALS;
}
/*
* Attempt to bind with the retrieved dn and the password. If the bind
* fails, it means that the password is wrong (the dn obviously
* exists, since we just retrieved it)
*/
(char *)*binddn,
(char *)bindpw)) == LDAP_SERVER_DOWN) {
"failed with server down";
goto start_over;
}
/* failure? if so - return */
if (result != LDAP_SUCCESS) {
return result;
}
else {
/*
* We have just bound the connection to a different user and password
* combination, which might be reused unintentionally next time this
* connection is used from the connection pool. To ensure no confusion,
* we mark the connection as unbound.
*/
}
/*
* Get values for the provided attributes.
*/
if (attrs) {
int k = 0;
int i = 0;
while (attrs[k++]);
numvals = k;
while (attrs[i]) {
char **values;
int j = 0;
/* get values */
j++;
}
i++;
}
}
/*
* Add the new username to the search cache.
*/
if (curl) {
/* Search again to make sure that another thread didn't ready insert this node
into the cache before we got here. If it does exist then update the lastbind */
if ((search_nodep == NULL) ||
/* Nothing in cache, insert new entry */
}
else if ((!search_nodep->bindpw) ||
/* Entry in cache is invalid, remove it and insert new one */
}
else {
/* Cache entry is valid, update lastbind */
}
}
return LDAP_SUCCESS;
}
/*
* This function will return the DN of the entry matching userid.
* It is used to get the DN in case some other module than mod_auth_ldap
* has authenticated the user.
* The function is basically a copy of uldap_cache_checkuserid
* with password checking removed.
*/
const char ***retvals)
{
int numvals = 0;
int result = 0;
char *dn;
int count;
int failures = 0;
&ldap_module);
/* Get the cache node for this url */
}
if (curl) {
if (search_nodep != NULL) {
/* found entry in search cache... */
curtime = apr_time_now();
/*
* Remove this item from the cache if its expired.
*/
/* ...but entry is too old */
}
else {
/* ...and entry is valid */
return LDAP_SUCCESS;
}
}
/* unlock this read lock */
}
/*
* At this point, there is no valid cached search, so lets do the search.
*/
/*
* If any LDAP operation fails due to LDAP_SERVER_DOWN, control returns here.
*/
if (failures++ > 10) {
return result;
}
return result;
}
/* try do the search */
goto start_over;
}
/* if there is an error (including LDAP_NO_SUCH_OBJECT) return now */
if (result != LDAP_SUCCESS) {
return result;
}
/*
* We should have found exactly one entry; to find a different
* number is an error.
*/
if (count != 1)
{
if (count == 0 )
else
return LDAP_NO_SUCH_OBJECT;
}
/* Grab the dn, copy it into the pool, and free it again */
/*
* Get values for the provided attributes.
*/
if (attrs) {
int k = 0;
int i = 0;
while (attrs[k++]);
numvals = k;
while (attrs[i]) {
char **values;
int j = 0;
/* get values */
j++;
}
i++;
}
}
/*
* Add the new username to the search cache.
*/
if (curl) {
/* Search again to make sure that another thread didn't ready insert this node
into the cache before we got here. If it does exist then update the lastbind */
if ((search_nodep == NULL) ||
/* Nothing in cache, insert new entry */
}
/*
* Don't update lastbind on entries with bindpw because
* we haven't verified that password. It's OK to update
* the entry if there is no password in it.
*/
else if (!search_nodep->bindpw) {
/* Cache entry is valid, update lastbind */
}
}
return LDAP_SUCCESS;
}
/*
* Reports if ssl support is enabled
*
* 1 = enabled, 0 = not enabled
*/
{
return(st->ssl_supported);
}
/* ---------------------------------------- */
/* config directives */
{
&ldap_module);
return NULL;
}
{
&ldap_module);
if (file) {
}
else {
}
"LDAP cache: Setting shared memory cache file to %s bytes.",
st->cache_file);
return NULL;
}
{
&ldap_module);
"[%d] ldap cache: Setting cache TTL to %ld microseconds.",
return NULL;
}
{
&ldap_module);
if (st->search_cache_size < 0) {
st->search_cache_size = 0;
}
"[%d] ldap cache: Setting search cache size to %ld entries.",
return NULL;
}
{
&ldap_module);
"[%d] ldap cache: Setting operation cache TTL to %ld microseconds.",
return NULL;
}
{
&ldap_module);
if (st->compare_cache_size < 0) {
st->compare_cache_size = 0;
}
"[%d] ldap cache: Setting operation cache size to %ld entries.",
return NULL;
}
/**
* Parse the certificate type.
*
* The type can be one of the following:
* CA_DER, CA_BASE64, CA_CERT7_DB, CA_SECMOD, CERT_DER, CERT_BASE64,
* CERT_KEY3_DB, CERT_NICKNAME, KEY_DER, KEY_BASE64
*
* If no matches are found, APR_LDAP_CA_TYPE_UNKNOWN is returned.
*/
static const int util_ldap_parse_cert_type(const char *type) {
/* Authority file in binary DER format */
return APR_LDAP_CA_TYPE_DER;
}
/* Authority file in Base64 format */
return APR_LDAP_CA_TYPE_BASE64;
}
return APR_LDAP_CA_TYPE_CERT7_DB;
}
return APR_LDAP_CA_TYPE_SECMOD;
}
/* Client cert file in DER format */
return APR_LDAP_CERT_TYPE_DER;
}
/* Client cert file in Base64 format */
return APR_LDAP_CERT_TYPE_BASE64;
}
/* Client cert file in PKCS#12 format */
return APR_LDAP_CERT_TYPE_PFX;
}
return APR_LDAP_CERT_TYPE_KEY3_DB;
}
/* Netscape client cert nickname */
return APR_LDAP_CERT_TYPE_NICKNAME;
}
/* Client cert key file in DER format */
return APR_LDAP_KEY_TYPE_DER;
}
/* Client cert key file in Base64 format */
return APR_LDAP_KEY_TYPE_BASE64;
}
/* Client cert key file in PKCS#12 format */
return APR_LDAP_KEY_TYPE_PFX;
}
else {
return APR_LDAP_CA_TYPE_UNKNOWN;
}
}
/**
* Set LDAPTrustedGlobalCert.
*
* This directive takes either two or three arguments:
* - certificate type
* - certificate file / directory / nickname
* - certificate password (optional)
*
* This directive may only be used globally.
*/
static const char *util_ldap_set_trusted_global_cert(cmd_parms *cmd, void *dummy, const char *type, const char *file, const char *password)
{
&ldap_module);
int cert_type = 0;
return err;
}
/* handle the certificate type */
if (type) {
if (APR_LDAP_CA_TYPE_UNKNOWN == cert_type) {
"not recognised. It should be one "
"of CA_DER, CA_BASE64, CA_CERT7_DB, "
"CA_SECMOD, CERT_DER, CERT_BASE64, "
"CERT_KEY3_DB, CERT_NICKNAME, "
"KEY_DER, KEY_BASE64", type);
}
}
else {
return "Certificate type was not specified.";
}
"LDAP: SSL trusted global cert - %s (type %s)",
/* add the certificate to the global array */
/* if file is a file or path, fix the path */
if (cert_type != APR_LDAP_CA_TYPE_UNKNOWN &&
"LDAP: Could not open SSL trusted certificate "
"authority file - %s",
return "Invalid global certificate file path";
}
}
return(NULL);
}
/**
* Set LDAPTrustedClientCert.
*
* This directive takes either two or three arguments:
* - certificate type
* - certificate file / directory / nickname
* - certificate password (optional)
*/
static const char *util_ldap_set_trusted_client_cert(cmd_parms *cmd, void *config, const char *type, const char *file, const char *password)
{
&ldap_module);
int cert_type = 0;
/* handle the certificate type */
if (type) {
if (APR_LDAP_CA_TYPE_UNKNOWN == cert_type) {
"not recognised. It should be one "
"of CERT_DER, CERT_BASE64, "
"CERT_NICKNAME, CERT_PFX,"
"KEY_DER, KEY_BASE64, KEY_PFX", type);
}
else if (APR_LDAP_CA_TYPE_DER == cert_type ||
"only valid within a "
"LDAPTrustedGlobalCert directive. "
"Only CERT_DER, CERT_BASE64, "
"CERT_NICKNAME, KEY_DER, and "
"KEY_BASE64 may be used.", type);
}
}
else {
return "Certificate type was not specified.";
}
"LDAP: SSL trusted client cert - %s (type %s)",
/* add the certificate to the global array */
/* if file is a file or path, fix the path */
if (cert_type != APR_LDAP_CA_TYPE_UNKNOWN &&
"LDAP: Could not open SSL client certificate "
"file - %s",
return "Invalid client certificate file path";
}
}
return(NULL);
}
/**
* Set LDAPTrustedMode.
*
* This directive sets what encryption mode to use on a connection:
* - None (No encryption)
* - SSL (SSL encryption)
* - STARTTLS (TLS encryption)
*/
{
&ldap_module);
"LDAP: SSL trusted mode - %s",
mode);
}
}
}
else {
return "Invalid LDAPTrustedMode setting: must be one of NONE, "
}
return(NULL);
}
{
&ldap_module);
return err;
}
#ifdef LDAP_OPT_NETWORK_TIMEOUT
"[%d] ldap connection: Setting connection timeout to %ld seconds.",
#else
"LDAP: Connection timout option not supported by the LDAP SDK in use." );
#endif
return NULL;
}
{
st->ssl_supported = 0;
st->secure_set = 0;
return st;
}
{
return st;
}
{
server_rec *s = data;
s->module_config, &ldap_module);
if (st->ssl_supported) {
}
return APR_SUCCESS;
}
{
char buf[MAX_STRING_LEN];
void *data;
const char *userdata_key = "util_ldap_init";
int rc;
/* util_ldap_post_config() will be called twice. Don't bother
* going through all of the initialization on the first call
* because it will just be thrown away.*/
if (!data) {
/* If the cache file already exists then delete it. Otherwise we are
* going to run into problems creating the shared memory. */
if (st->cache_file) {
}
#endif
return OK;
}
/* initializing cache if shared memory size is not zero and we already don't have shm address */
#endif
if (result != APR_SUCCESS) {
"LDAP cache: error while creating a shared memory segment: %s", buf);
}
if (st->cache_file) {
}
else
#endif
result = apr_global_mutex_create(&st->util_ldap_cache_lock, st->lock_file, APR_LOCK_DEFAULT, st->pool);
if (result != APR_SUCCESS) {
return result;
}
#ifdef AP_NEED_SET_MUTEX_PERMS
if (result != APR_SUCCESS) {
"LDAP cache: failed to set mutex permissions");
return result;
}
#endif
/* merge config in all vhost */
while (s_vhost) {
"LDAP merging Shared Cache conf: shm=0x%pp rmm=0x%pp for VHOST: %s",
#endif
}
}
else {
ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, "LDAP cache: LDAPSharedCacheSize is zero, disabling shared memory cache");
}
#endif
/* log the LDAP SDK used
*/
{
apr_ldap_info(p, &(result));
}
}
/*
* Initialize SSL support, and log the result for the benefit of the admin.
*
* If SSL is not supported it is not necessarily an error, as the
* application may not want to use it.
*/
rc = apr_ldap_ssl_init(p,
NULL,
0,
&(result_err));
if (APR_SUCCESS == rc) {
}
if (APR_SUCCESS == rc) {
"LDAP: SSL support available" );
}
else {
st->ssl_supported = 0;
if (NULL != result_err) {
}
"LDAP: SSL support unavailable" );
}
#ifdef LDAP_OPT_NETWORK_TIMEOUT
if (st->connectionTimeout > 0) {
}
if (st->connectionTimeout >= 0) {
(void *)&timeOut, &(result_err));
if (APR_SUCCESS != rc) {
"LDAP: Could not set the connection timeout" );
}
}
#endif
return(OK);
}
{
if (!st->util_ldap_cache_lock) return;
if (sts != APR_SUCCESS) {
"Failed to initialise global mutex %s in child process %"
".",
return;
}
else {
"Initialisation of global mutex %s in child process %"
" successful.",
}
}
command_rec util_ldap_cmds[] = {
"Sets the size of the shared memory cache in bytes. "
"Zero means disable the shared memory cache. Defaults to 100KB."),
"Sets the file of the shared memory cache."
"Nothing means disable the shared memory cache."),
"Sets the maximum number of entries that are possible in the LDAP "
"search cache. "
"Zero means no limit; -1 disables the cache. Defaults to 1024 entries."),
"Sets the maximum time (in seconds) that an item can be cached in the LDAP "
"search cache. Zero means no limit. Defaults to 600 seconds (10 minutes)."),
"Sets the maximum number of entries that are possible in the LDAP "
"compare cache. "
"Zero means no limit; -1 disables the cache. Defaults to 1024 entries."),
"Sets the maximum time (in seconds) that an item is cached in the LDAP "
"operation cache. Zero means no limit. Defaults to 600 seconds (10 minutes)."),
"certificate authority certificates, and global client "
"certificates (Netware). Used to validate the LDAP server "
"The following types are supported: "
" CA_DER - Authority file in binary DER format "
" CA_BASE64 - Authority file in Base64 format "
" CERT_DER - Client cert file in DER format "
" CERT_BASE64 - Client cert file in Base64 format "
" CERT_NICKNAME - Netscape client cert nickname "
" KEY_DER - Client cert key file in DER format "
" KEY_BASE64 - Client cert key file in Base64 format "),
"Specifies a file containing a client certificate or private "
"key, or the ID of the certificate to usethe type of the Certificate Authority file. "
"The following types are supported: "
" CA_DER - Authority file in binary DER format "
" CA_BASE64 - Authority file in Base64 format "
" CERT_DER - Client cert file in DER format "
" CERT_BASE64 - Client cert file in Base64 format "
" CERT_NICKNAME - Netscape client cert nickname "
" KEY_DER - Client cert key file in DER format "
" KEY_BASE64 - Client cert key file in Base64 format "),
"Specifies the type of security that should be applied to "
"an LDAP connection. The types supported are: "
" NONE - no encryption enabled "
" SSL - SSL encryption enabled (forced by ldaps://) "
" STARTTLS - STARTTLS MUST be enabled "),
"Specifies the LDAP socket connection timeout in seconds. "
"Default is 10 seconds. "),
{NULL}
};
static void util_ldap_register_hooks(apr_pool_t *p)
{
}
module ldap_module = {
NULL, /* dir config creater */
NULL, /* dir merger --- default is to override */
util_ldap_create_config, /* server config */
util_ldap_merge_config, /* merge server config */
util_ldap_cmds, /* command table */
util_ldap_register_hooks, /* set up request processing hooks */
};