mirror of
https://github.com/apache/httpd.git
synced 2025-08-10 02:56:11 +00:00
Revert r1129808:
Incorporate the ap_ldap incomplete API, as there is no interest or effort at APR to make this a complete abstraction, and it was voted 'off the island' with APR 2.0. This will allow httpd 2.3 to build against either apr-2.0 or apr+util 1.x. This also reverts part of r1142938, which needs to be re-done. git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/revert-ap-ldap@1150172 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
@ -1,195 +0,0 @@
|
||||
/* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You 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
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* ap_ldap_init.c: LDAP v2/v3 common initialise
|
||||
*
|
||||
* Original code from auth_ldap module for Apache v1.3:
|
||||
* Copyright 1998, 1999 Enbridge Pipelines Inc.
|
||||
* Copyright 1999-2001 Dave Carrigan
|
||||
*/
|
||||
|
||||
#include "apr.h"
|
||||
#include "apu.h"
|
||||
|
||||
#include "ap_config.h"
|
||||
#include "ap_ldap.h"
|
||||
#include "apr_errno.h"
|
||||
#include "apr_pools.h"
|
||||
#include "apr_strings.h"
|
||||
|
||||
#if AP_HAS_LDAP
|
||||
|
||||
/**
|
||||
* APR LDAP SSL Initialise function
|
||||
*
|
||||
* This function initialises SSL on the underlying LDAP toolkit
|
||||
* if this is necessary.
|
||||
*
|
||||
* If a CA certificate is provided, this is set, however the setting
|
||||
* of certificates via this method has been deprecated and will be removed in
|
||||
* APR v2.0.
|
||||
*
|
||||
* The ap_ldap_set_option() function with the AP_LDAP_OPT_TLS_CERT option
|
||||
* should be used instead to set certificates.
|
||||
*
|
||||
* If SSL support is not available on this platform, or a problem
|
||||
* was encountered while trying to set the certificate, the function
|
||||
* will return APR_EGENERAL. Further LDAP specific error information
|
||||
* can be found in result_err.
|
||||
*/
|
||||
MODLDAP_DECLARE(int) ap_ldap_ssl_init(apr_pool_t *pool,
|
||||
const char *cert_auth_file,
|
||||
int cert_file_type,
|
||||
ap_ldap_err_t **result_err)
|
||||
{
|
||||
|
||||
ap_ldap_err_t *result = (ap_ldap_err_t *)apr_pcalloc(pool, sizeof(ap_ldap_err_t));
|
||||
*result_err = result;
|
||||
|
||||
#if AP_HAS_LDAP_SSL /* compiled with ssl support */
|
||||
|
||||
/* Novell */
|
||||
#if AP_HAS_NOVELL_LDAPSDK
|
||||
ldapssl_client_init(NULL, NULL);
|
||||
#endif
|
||||
|
||||
/* if a certificate was specified, set it */
|
||||
if (cert_auth_file) {
|
||||
ap_ldap_opt_tls_cert_t *cert = (ap_ldap_opt_tls_cert_t *)apr_pcalloc(pool, sizeof(ap_ldap_opt_tls_cert_t));
|
||||
cert->type = cert_file_type;
|
||||
cert->path = cert_auth_file;
|
||||
return ap_ldap_set_option(pool, NULL, AP_LDAP_OPT_TLS_CERT, (void *)cert, result_err);
|
||||
}
|
||||
|
||||
#else /* not compiled with SSL Support */
|
||||
if (cert_auth_file) {
|
||||
result->reason = "LDAP: Attempt to set certificate store failed. "
|
||||
"Not built with SSL support";
|
||||
result->rc = -1;
|
||||
}
|
||||
#endif /* AP_HAS_LDAP_SSL */
|
||||
|
||||
if (result->rc != -1) {
|
||||
result->msg = ldap_err2string(result->rc);
|
||||
}
|
||||
|
||||
if (LDAP_SUCCESS != result->rc) {
|
||||
return APR_EGENERAL;
|
||||
}
|
||||
|
||||
return APR_SUCCESS;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* APR LDAP SSL De-Initialise function
|
||||
*
|
||||
* This function tears down any SSL certificate setup previously
|
||||
* set using ap_ldap_ssl_init(). It should be called to clean
|
||||
* up if a graceful restart of a service is attempted.
|
||||
*
|
||||
* This function only does anything on Netware.
|
||||
*
|
||||
* @todo currently we do not check whether ap_ldap_ssl_init()
|
||||
* has been called first - should we?
|
||||
*/
|
||||
MODLDAP_DECLARE(int) ap_ldap_ssl_deinit(void)
|
||||
{
|
||||
|
||||
#if AP_HAS_LDAP_SSL && AP_HAS_LDAPSSL_CLIENT_DEINIT
|
||||
ldapssl_client_deinit();
|
||||
#endif
|
||||
return APR_SUCCESS;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* APR LDAP initialise function
|
||||
*
|
||||
* This function is responsible for initialising an LDAP
|
||||
* connection in a toolkit independant way. It does the
|
||||
* job of ldap_init() from the C api.
|
||||
*
|
||||
* It handles both the SSL and non-SSL case, and attempts
|
||||
* to hide the complexity setup from the user. This function
|
||||
* assumes that any certificate setup necessary has already
|
||||
* been done.
|
||||
*
|
||||
* If SSL or STARTTLS needs to be enabled, and the underlying
|
||||
* toolkit supports it, the following values are accepted for
|
||||
* secure:
|
||||
*
|
||||
* AP_LDAP_NONE: No encryption
|
||||
* AP_LDAP_SSL: SSL encryption (ldaps://)
|
||||
* AP_LDAP_STARTTLS: Force STARTTLS on ldap://
|
||||
*/
|
||||
MODLDAP_DECLARE(int) ap_ldap_init(apr_pool_t *pool,
|
||||
LDAP **ldap,
|
||||
const char *hostname,
|
||||
int portno,
|
||||
int secure,
|
||||
ap_ldap_err_t **result_err)
|
||||
{
|
||||
|
||||
ap_ldap_err_t *result = (ap_ldap_err_t *)apr_pcalloc(pool, sizeof(ap_ldap_err_t));
|
||||
*result_err = result;
|
||||
|
||||
#if AP_HAS_LDAPSSL_INIT
|
||||
*ldap = ldapssl_init(hostname, portno, 0);
|
||||
#elif AP_HAS_LDAP_SSLINIT
|
||||
*ldap = ldap_sslinit((char *)hostname, portno, 0);
|
||||
#else
|
||||
*ldap = ldap_init((char *)hostname, portno);
|
||||
#endif
|
||||
if (*ldap != NULL) {
|
||||
return ap_ldap_set_option(pool, *ldap, AP_LDAP_OPT_TLS, &secure, result_err);
|
||||
}
|
||||
else {
|
||||
/* handle the error case */
|
||||
ap_ldap_err_t *result = (ap_ldap_err_t *)apr_pcalloc(pool, sizeof(ap_ldap_err_t));
|
||||
*result_err = result;
|
||||
|
||||
result->reason = "APR LDAP: Unable to initialize the LDAP connection";
|
||||
result->rc = -1;
|
||||
return APR_EGENERAL;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* APR LDAP info function
|
||||
*
|
||||
* This function returns a string describing the LDAP toolkit
|
||||
* currently in use. The string is placed inside result_err->reason.
|
||||
*/
|
||||
MODLDAP_DECLARE(int) ap_ldap_info(apr_pool_t *pool,
|
||||
ap_ldap_err_t **result_err)
|
||||
{
|
||||
ap_ldap_err_t *result = (ap_ldap_err_t *)apr_pcalloc(pool, sizeof(ap_ldap_err_t));
|
||||
*result_err = result;
|
||||
|
||||
result->reason = "APR LDAP: Built with "
|
||||
LDAP_VENDOR_NAME
|
||||
" LDAP SDK";
|
||||
return APR_SUCCESS;
|
||||
|
||||
}
|
||||
|
||||
#endif /* AP_HAS_LDAP */
|
@ -1,667 +0,0 @@
|
||||
/* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You 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
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/* ap_ldap_option.c -- LDAP options
|
||||
*
|
||||
* The LDAP SDK allows the getting and setting of options on an LDAP
|
||||
* connection.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "apr.h"
|
||||
#include "apu.h"
|
||||
#include "ap_config.h"
|
||||
#include "ap_ldap.h"
|
||||
#include "apr_errno.h"
|
||||
#include "apr_pools.h"
|
||||
#include "apr_strings.h"
|
||||
#include "apr_tables.h"
|
||||
|
||||
#if AP_HAS_LDAP
|
||||
|
||||
static void option_set_cert(apr_pool_t *pool, LDAP *ldap, const void *invalue,
|
||||
ap_ldap_err_t *result);
|
||||
static void option_set_tls(apr_pool_t *pool, LDAP *ldap, const void *invalue,
|
||||
ap_ldap_err_t *result);
|
||||
|
||||
/**
|
||||
* MODLDAP get option function
|
||||
*
|
||||
* This function gets option values from a given LDAP session if
|
||||
* one was specified.
|
||||
*/
|
||||
MODLDAP_DECLARE(int) ap_ldap_get_option(apr_pool_t *pool,
|
||||
LDAP *ldap,
|
||||
int option,
|
||||
void *outvalue,
|
||||
ap_ldap_err_t **result_err)
|
||||
{
|
||||
ap_ldap_err_t *result;
|
||||
|
||||
result = apr_pcalloc(pool, sizeof(ap_ldap_err_t));
|
||||
*result_err = result;
|
||||
if (!result) {
|
||||
return APR_ENOMEM;
|
||||
}
|
||||
|
||||
/* get the option specified using the native LDAP function */
|
||||
result->rc = ldap_get_option(ldap, option, outvalue);
|
||||
|
||||
/* handle the error case */
|
||||
if (result->rc != LDAP_SUCCESS) {
|
||||
result->msg = ldap_err2string(result-> rc);
|
||||
result->reason = apr_pstrdup(pool, "LDAP: Could not get an option");
|
||||
return APR_EGENERAL;
|
||||
}
|
||||
|
||||
return APR_SUCCESS;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* MODLDAP set option function
|
||||
*
|
||||
* This function sets option values to a given LDAP session if
|
||||
* one was specified.
|
||||
*
|
||||
* Where an option is not supported by an LDAP toolkit, this function
|
||||
* will try and apply legacy functions to achieve the same effect,
|
||||
* depending on the platform.
|
||||
*/
|
||||
MODLDAP_DECLARE(int) ap_ldap_set_option(apr_pool_t *pool,
|
||||
LDAP *ldap,
|
||||
int option,
|
||||
const void *invalue,
|
||||
ap_ldap_err_t **result_err)
|
||||
{
|
||||
ap_ldap_err_t *result;
|
||||
|
||||
result = apr_pcalloc(pool, sizeof(ap_ldap_err_t));
|
||||
*result_err = result;
|
||||
if (!result) {
|
||||
return APR_ENOMEM;
|
||||
}
|
||||
|
||||
switch (option) {
|
||||
case AP_LDAP_OPT_TLS_CERT:
|
||||
option_set_cert(pool, ldap, invalue, result);
|
||||
break;
|
||||
|
||||
case AP_LDAP_OPT_TLS:
|
||||
option_set_tls(pool, ldap, invalue, result);
|
||||
break;
|
||||
|
||||
case AP_LDAP_OPT_VERIFY_CERT:
|
||||
#if AP_HAS_NETSCAPE_LDAPSDK || AP_HAS_SOLARIS_LDAPSDK || AP_HAS_MOZILLA_LDAPSK
|
||||
result->reason = "LDAP: Verify certificate not yet supported on the "
|
||||
"Netscape, Solaris or Mozilla LDAP SDKs";
|
||||
result->rc = -1;
|
||||
return APR_EGENERAL;
|
||||
#endif
|
||||
#if AP_HAS_NOVELL_LDAPSDK
|
||||
if (*((int*)invalue)) {
|
||||
result->rc = ldapssl_set_verify_mode(LDAPSSL_VERIFY_SERVER);
|
||||
}
|
||||
else {
|
||||
result->rc = ldapssl_set_verify_mode(LDAPSSL_VERIFY_NONE);
|
||||
}
|
||||
#endif
|
||||
#if AP_HAS_OPENLDAP_LDAPSDK
|
||||
#ifdef LDAP_OPT_X_TLS
|
||||
/* This is not a per-connection setting so just pass NULL for the
|
||||
Ldap connection handle */
|
||||
if (*((int*)invalue)) {
|
||||
int i = LDAP_OPT_X_TLS_DEMAND;
|
||||
result->rc = ldap_set_option(NULL, LDAP_OPT_X_TLS_REQUIRE_CERT, &i);
|
||||
}
|
||||
else {
|
||||
int i = LDAP_OPT_X_TLS_NEVER;
|
||||
result->rc = ldap_set_option(NULL, LDAP_OPT_X_TLS_REQUIRE_CERT, &i);
|
||||
}
|
||||
#else
|
||||
result->reason = "LDAP: SSL/TLS not yet supported on this "
|
||||
"version of the OpenLDAP toolkit";
|
||||
result->rc = -1;
|
||||
return APR_EGENERAL;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* handle the error case */
|
||||
if (result->rc != LDAP_SUCCESS) {
|
||||
result->msg = ldap_err2string(result->rc);
|
||||
result->reason = "LDAP: Could not set verify mode";
|
||||
}
|
||||
break;
|
||||
|
||||
case AP_LDAP_OPT_REFERRALS:
|
||||
/* Setting this option is supported on at least TIVOLI_SDK and OpenLDAP. Folks
|
||||
* who know the NOVELL, NETSCAPE, MOZILLA, and SOLARIS SDKs should note here if
|
||||
* the SDK at least tolerates this option being set, or add an elif to handle
|
||||
* special cases (i.e. different LDAP_OPT_X value).
|
||||
*/
|
||||
result->rc = ldap_set_option(ldap, LDAP_OPT_REFERRALS, (void *)invalue);
|
||||
|
||||
if (result->rc != LDAP_SUCCESS) {
|
||||
result->reason = "Unable to set LDAP_OPT_REFERRALS.";
|
||||
return(result->rc);
|
||||
}
|
||||
break;
|
||||
|
||||
case AP_LDAP_OPT_REFHOPLIMIT:
|
||||
#if !defined(LDAP_OPT_REFHOPLIMIT) || AP_HAS_NOVELL_LDAPSDK
|
||||
/* If the LDAP_OPT_REFHOPLIMIT symbol is missing, assume that the
|
||||
* particular LDAP library has a reasonable default. So far certain
|
||||
* versions of the OpenLDAP SDK miss this symbol (but default to 5),
|
||||
* and the Microsoft SDK misses the symbol (the default is not known).
|
||||
*/
|
||||
result->rc = LDAP_SUCCESS;
|
||||
#else
|
||||
/* Setting this option is supported on at least TIVOLI_SDK. Folks who know
|
||||
* the NOVELL, NETSCAPE, MOZILLA, and SOLARIS SDKs should note here if
|
||||
* the SDK at least tolerates this option being set, or add an elif to handle
|
||||
* special cases so an error isn't returned if there is a perfectly good
|
||||
* default value that just can't be changed (like openLDAP).
|
||||
*/
|
||||
result->rc = ldap_set_option(ldap, LDAP_OPT_REFHOPLIMIT, (void *)invalue);
|
||||
#endif
|
||||
|
||||
if (result->rc != LDAP_SUCCESS) {
|
||||
result->reason = "Unable to set LDAP_OPT_REFHOPLIMIT.";
|
||||
return(result->rc);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
/* set the option specified using the native LDAP function */
|
||||
result->rc = ldap_set_option(ldap, option, (void *)invalue);
|
||||
|
||||
/* handle the error case */
|
||||
if (result->rc != LDAP_SUCCESS) {
|
||||
result->msg = ldap_err2string(result->rc);
|
||||
result->reason = "LDAP: Could not set an option";
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
/* handle the error case */
|
||||
if (result->rc != LDAP_SUCCESS) {
|
||||
return APR_EGENERAL;
|
||||
}
|
||||
|
||||
return APR_SUCCESS;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle AP_LDAP_OPT_TLS
|
||||
*
|
||||
* This function sets the type of TLS to be applied to this connection.
|
||||
* The options are:
|
||||
* AP_LDAP_NONE: no encryption
|
||||
* AP_LDAP_SSL: SSL encryption (ldaps://)
|
||||
* AP_LDAP_STARTTLS: STARTTLS encryption
|
||||
* AP_LDAP_STOPTLS: Stop existing TLS connecttion
|
||||
*/
|
||||
static void option_set_tls(apr_pool_t *pool, LDAP *ldap, const void *invalue,
|
||||
ap_ldap_err_t *result)
|
||||
{
|
||||
#if AP_HAS_LDAP_SSL /* compiled with ssl support */
|
||||
|
||||
int tls = * (const int *)invalue;
|
||||
|
||||
/* Netscape/Mozilla/Solaris SDK */
|
||||
#if AP_HAS_NETSCAPE_LDAPSDK || AP_HAS_SOLARIS_LDAPSDK || AP_HAS_MOZILLA_LDAPSK
|
||||
#if AP_HAS_LDAPSSL_INSTALL_ROUTINES
|
||||
if (tls == AP_LDAP_SSL) {
|
||||
result->rc = ldapssl_install_routines(ldap);
|
||||
#ifdef LDAP_OPT_SSL
|
||||
/* apparently Netscape and Mozilla need this too, Solaris doesn't */
|
||||
if (result->rc == LDAP_SUCCESS) {
|
||||
result->rc = ldap_set_option(ldap, LDAP_OPT_SSL, LDAP_OPT_ON);
|
||||
}
|
||||
#endif
|
||||
if (result->rc != LDAP_SUCCESS) {
|
||||
result->msg = ldap_err2string(result->rc);
|
||||
result->reason = "LDAP: Could not switch SSL on for this "
|
||||
"connection.";
|
||||
}
|
||||
}
|
||||
else if (tls == AP_LDAP_STARTTLS) {
|
||||
result->reason = "LDAP: STARTTLS is not supported by the "
|
||||
"Netscape/Mozilla/Solaris SDK";
|
||||
result->rc = -1;
|
||||
}
|
||||
else if (tls == AP_LDAP_STOPTLS) {
|
||||
result->reason = "LDAP: STOPTLS is not supported by the "
|
||||
"Netscape/Mozilla/Solaris SDK";
|
||||
result->rc = -1;
|
||||
}
|
||||
#else
|
||||
if (tls != AP_LDAP_NONE) {
|
||||
result->reason = "LDAP: SSL/TLS is not supported by this version "
|
||||
"of the Netscape/Mozilla/Solaris SDK";
|
||||
result->rc = -1;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Novell SDK */
|
||||
#if AP_HAS_NOVELL_LDAPSDK
|
||||
/* ldapssl_install_routines(ldap)
|
||||
* Behavior is unpredictable when other LDAP functions are called
|
||||
* between the ldap_init function and the ldapssl_install_routines
|
||||
* function.
|
||||
*
|
||||
* STARTTLS is supported by the ldap_start_tls_s() method
|
||||
*/
|
||||
if (tls == AP_LDAP_SSL) {
|
||||
result->rc = ldapssl_install_routines(ldap);
|
||||
if (result->rc != LDAP_SUCCESS) {
|
||||
result->msg = ldap_err2string(result->rc);
|
||||
result->reason = "LDAP: Could not switch SSL on for this "
|
||||
"connection.";
|
||||
}
|
||||
}
|
||||
if (tls == AP_LDAP_STARTTLS) {
|
||||
result->rc = ldapssl_start_tls(ldap);
|
||||
if (result->rc != LDAP_SUCCESS) {
|
||||
result->msg = ldap_err2string(result->rc);
|
||||
result->reason = "LDAP: Could not start TLS on this connection";
|
||||
}
|
||||
}
|
||||
else if (tls == AP_LDAP_STOPTLS) {
|
||||
result->rc = ldapssl_stop_tls(ldap);
|
||||
if (result->rc != LDAP_SUCCESS) {
|
||||
result->msg = ldap_err2string(result->rc);
|
||||
result->reason = "LDAP: Could not stop TLS on this connection";
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* OpenLDAP SDK */
|
||||
#if AP_HAS_OPENLDAP_LDAPSDK
|
||||
#ifdef LDAP_OPT_X_TLS
|
||||
if (tls == AP_LDAP_SSL) {
|
||||
int SSLmode = LDAP_OPT_X_TLS_HARD;
|
||||
result->rc = ldap_set_option(ldap, LDAP_OPT_X_TLS, &SSLmode);
|
||||
if (result->rc != LDAP_SUCCESS) {
|
||||
result->reason = "LDAP: ldap_set_option failed. "
|
||||
"Could not set LDAP_OPT_X_TLS to "
|
||||
"LDAP_OPT_X_TLS_HARD";
|
||||
result->msg = ldap_err2string(result->rc);
|
||||
}
|
||||
}
|
||||
else if (tls == AP_LDAP_STARTTLS) {
|
||||
result->rc = ldap_start_tls_s(ldap, NULL, NULL);
|
||||
if (result->rc != LDAP_SUCCESS) {
|
||||
result->reason = "LDAP: ldap_start_tls_s() failed";
|
||||
result->msg = ldap_err2string(result->rc);
|
||||
}
|
||||
}
|
||||
else if (tls == AP_LDAP_STOPTLS) {
|
||||
result->reason = "LDAP: STOPTLS is not supported by the "
|
||||
"OpenLDAP SDK";
|
||||
result->rc = -1;
|
||||
}
|
||||
#else
|
||||
if (tls != AP_LDAP_NONE) {
|
||||
result->reason = "LDAP: SSL/TLS not yet supported on this "
|
||||
"version of the OpenLDAP toolkit";
|
||||
result->rc = -1;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Microsoft SDK */
|
||||
#if AP_HAS_MICROSOFT_LDAPSDK
|
||||
if (tls == AP_LDAP_NONE) {
|
||||
ULONG ul = (ULONG) LDAP_OPT_OFF;
|
||||
result->rc = ldap_set_option(ldap, LDAP_OPT_SSL, &ul);
|
||||
if (result->rc != LDAP_SUCCESS) {
|
||||
result->reason = "LDAP: an attempt to set LDAP_OPT_SSL off "
|
||||
"failed.";
|
||||
result->msg = ldap_err2string(result->rc);
|
||||
}
|
||||
}
|
||||
else if (tls == AP_LDAP_SSL) {
|
||||
ULONG ul = (ULONG) LDAP_OPT_ON;
|
||||
result->rc = ldap_set_option(ldap, LDAP_OPT_SSL, &ul);
|
||||
if (result->rc != LDAP_SUCCESS) {
|
||||
result->reason = "LDAP: an attempt to set LDAP_OPT_SSL on "
|
||||
"failed.";
|
||||
result->msg = ldap_err2string(result->rc);
|
||||
}
|
||||
}
|
||||
#if AP_HAS_LDAP_START_TLS_S
|
||||
else if (tls == AP_LDAP_STARTTLS) {
|
||||
result->rc = ldap_start_tls_s(ldap, NULL, NULL, NULL, NULL);
|
||||
if (result->rc != LDAP_SUCCESS) {
|
||||
result->reason = "LDAP: ldap_start_tls_s() failed";
|
||||
result->msg = ldap_err2string(result->rc);
|
||||
}
|
||||
}
|
||||
else if (tls == AP_LDAP_STOPTLS) {
|
||||
result->rc = ldap_stop_tls_s(ldap);
|
||||
if (result->rc != LDAP_SUCCESS) {
|
||||
result->reason = "LDAP: ldap_stop_tls_s() failed";
|
||||
result->msg = ldap_err2string(result->rc);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if AP_HAS_OTHER_LDAPSDK
|
||||
if (tls != AP_LDAP_NONE) {
|
||||
result->reason = "LDAP: SSL/TLS is currently not supported "
|
||||
"on this LDAP SDK";
|
||||
result->rc = -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* AP_HAS_LDAP_SSL */
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle AP_LDAP_OPT_TLS_CACERTFILE
|
||||
*
|
||||
* This function sets the CA certificate for further SSL/TLS connections.
|
||||
*
|
||||
* The file provided are in different formats depending on the toolkit used:
|
||||
*
|
||||
* Netscape: cert7.db file
|
||||
* Novell: PEM or DER
|
||||
* OpenLDAP: PEM (others supported?)
|
||||
* Microsoft: unknown
|
||||
* Solaris: unknown
|
||||
*/
|
||||
static void option_set_cert(apr_pool_t *pool, LDAP *ldap,
|
||||
const void *invalue, ap_ldap_err_t *result)
|
||||
{
|
||||
#if AP_HAS_LDAP_SSL
|
||||
#if AP_HAS_LDAPSSL_CLIENT_INIT || AP_HAS_OPENLDAP_LDAPSDK
|
||||
apr_array_header_t *certs = (apr_array_header_t *)invalue;
|
||||
struct ap_ldap_opt_tls_cert_t *ents = (struct ap_ldap_opt_tls_cert_t *)certs->elts;
|
||||
int i = 0;
|
||||
#endif
|
||||
|
||||
/* Netscape/Mozilla/Solaris SDK */
|
||||
#if AP_HAS_NETSCAPE_LDAPSDK || AP_HAS_SOLARIS_LDAPSDK || AP_HAS_MOZILLA_LDAPSDK
|
||||
#if AP_HAS_LDAPSSL_CLIENT_INIT
|
||||
const char *nickname = NULL;
|
||||
const char *secmod = NULL;
|
||||
const char *key3db = NULL;
|
||||
const char *cert7db = NULL;
|
||||
const char *password = NULL;
|
||||
|
||||
/* set up cert7.db, key3.db and secmod parameters */
|
||||
for (i = 0; i < certs->nelts; i++) {
|
||||
switch (ents[i].type) {
|
||||
case AP_LDAP_CA_TYPE_CERT7_DB:
|
||||
cert7db = ents[i].path;
|
||||
break;
|
||||
case AP_LDAP_CA_TYPE_SECMOD:
|
||||
secmod = ents[i].path;
|
||||
break;
|
||||
case AP_LDAP_CERT_TYPE_KEY3_DB:
|
||||
key3db = ents[i].path;
|
||||
break;
|
||||
case AP_LDAP_CERT_TYPE_NICKNAME:
|
||||
nickname = ents[i].path;
|
||||
password = ents[i].password;
|
||||
break;
|
||||
default:
|
||||
result->rc = -1;
|
||||
result->reason = "LDAP: The Netscape/Mozilla LDAP SDK only "
|
||||
"understands the CERT7, KEY3 and SECMOD "
|
||||
"file types.";
|
||||
break;
|
||||
}
|
||||
if (result->rc != LDAP_SUCCESS) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* actually set the certificate parameters */
|
||||
if (result->rc == LDAP_SUCCESS) {
|
||||
if (nickname) {
|
||||
result->rc = ldapssl_enable_clientauth(ldap, "",
|
||||
(char *)password,
|
||||
(char *)nickname);
|
||||
if (result->rc != LDAP_SUCCESS) {
|
||||
result->reason = "LDAP: could not set client certificate: "
|
||||
"ldapssl_enable_clientauth() failed.";
|
||||
result->msg = ldap_err2string(result->rc);
|
||||
}
|
||||
}
|
||||
else if (secmod) {
|
||||
result->rc = ldapssl_advclientauth_init(cert7db, NULL,
|
||||
key3db ? 1 : 0, key3db, NULL,
|
||||
1, secmod, LDAPSSL_AUTH_CNCHECK);
|
||||
if (result->rc != LDAP_SUCCESS) {
|
||||
result->reason = "LDAP: ldapssl_advclientauth_init() failed.";
|
||||
result->msg = ldap_err2string(result->rc);
|
||||
}
|
||||
}
|
||||
else if (key3db) {
|
||||
result->rc = ldapssl_clientauth_init(cert7db, NULL,
|
||||
1, key3db, NULL);
|
||||
if (result->rc != LDAP_SUCCESS) {
|
||||
result->reason = "LDAP: ldapssl_clientauth_init() failed.";
|
||||
result->msg = ldap_err2string(result->rc);
|
||||
}
|
||||
}
|
||||
else {
|
||||
result->rc = ldapssl_client_init(cert7db, NULL);
|
||||
if (result->rc != LDAP_SUCCESS) {
|
||||
result->reason = "LDAP: ldapssl_client_init() failed.";
|
||||
result->msg = ldap_err2string(result->rc);
|
||||
}
|
||||
}
|
||||
}
|
||||
#else
|
||||
result->reason = "LDAP: SSL/TLS ldapssl_client_init() function not "
|
||||
"supported by this Netscape/Mozilla/Solaris SDK. "
|
||||
"Certificate authority file not set";
|
||||
result->rc = -1;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Novell SDK */
|
||||
#if AP_HAS_NOVELL_LDAPSDK
|
||||
#if AP_HAS_LDAPSSL_CLIENT_INIT && AP_HAS_LDAPSSL_ADD_TRUSTED_CERT && AP_HAS_LDAPSSL_CLIENT_DEINIT
|
||||
/* The Novell library cannot support per connection certificates. Error
|
||||
* out if the ldap handle is provided.
|
||||
*/
|
||||
if (ldap) {
|
||||
result->rc = -1;
|
||||
result->reason = "LDAP: The Novell LDAP SDK cannot support the setting "
|
||||
"of certificates or keys on a per connection basis.";
|
||||
}
|
||||
/* Novell's library needs to be initialised first */
|
||||
else {
|
||||
result->rc = ldapssl_client_init(NULL, NULL);
|
||||
if (result->rc != LDAP_SUCCESS) {
|
||||
result->msg = ldap_err2string(result-> rc);
|
||||
result->reason = apr_pstrdup(pool, "LDAP: Could not "
|
||||
"initialize SSL");
|
||||
}
|
||||
}
|
||||
/* set one or more certificates */
|
||||
for (i = 0; LDAP_SUCCESS == result->rc && i < certs->nelts; i++) {
|
||||
/* Novell SDK supports DER or BASE64 files. */
|
||||
switch (ents[i].type) {
|
||||
case AP_LDAP_CA_TYPE_DER:
|
||||
result->rc = ldapssl_add_trusted_cert((void *)ents[i].path,
|
||||
LDAPSSL_CERT_FILETYPE_DER);
|
||||
result->msg = ldap_err2string(result->rc);
|
||||
break;
|
||||
case AP_LDAP_CA_TYPE_BASE64:
|
||||
result->rc = ldapssl_add_trusted_cert((void *)ents[i].path,
|
||||
LDAPSSL_CERT_FILETYPE_B64);
|
||||
result->msg = ldap_err2string(result->rc);
|
||||
break;
|
||||
case AP_LDAP_CERT_TYPE_DER:
|
||||
result->rc = ldapssl_set_client_cert((void *)ents[i].path,
|
||||
LDAPSSL_CERT_FILETYPE_DER,
|
||||
(void*)ents[i].password);
|
||||
result->msg = ldap_err2string(result->rc);
|
||||
break;
|
||||
case AP_LDAP_CERT_TYPE_BASE64:
|
||||
result->rc = ldapssl_set_client_cert((void *)ents[i].path,
|
||||
LDAPSSL_CERT_FILETYPE_B64,
|
||||
(void*)ents[i].password);
|
||||
result->msg = ldap_err2string(result->rc);
|
||||
break;
|
||||
case AP_LDAP_CERT_TYPE_PFX:
|
||||
result->rc = ldapssl_set_client_cert((void *)ents[i].path,
|
||||
LDAPSSL_FILETYPE_P12,
|
||||
(void*)ents[i].password);
|
||||
result->msg = ldap_err2string(result->rc);
|
||||
break;
|
||||
case AP_LDAP_KEY_TYPE_DER:
|
||||
result->rc = ldapssl_set_client_private_key((void *)ents[i].path,
|
||||
LDAPSSL_CERT_FILETYPE_DER,
|
||||
(void*)ents[i].password);
|
||||
result->msg = ldap_err2string(result->rc);
|
||||
break;
|
||||
case AP_LDAP_KEY_TYPE_BASE64:
|
||||
result->rc = ldapssl_set_client_private_key((void *)ents[i].path,
|
||||
LDAPSSL_CERT_FILETYPE_B64,
|
||||
(void*)ents[i].password);
|
||||
result->msg = ldap_err2string(result->rc);
|
||||
break;
|
||||
case AP_LDAP_KEY_TYPE_PFX:
|
||||
result->rc = ldapssl_set_client_private_key((void *)ents[i].path,
|
||||
LDAPSSL_FILETYPE_P12,
|
||||
(void*)ents[i].password);
|
||||
result->msg = ldap_err2string(result->rc);
|
||||
break;
|
||||
default:
|
||||
result->rc = -1;
|
||||
result->reason = "LDAP: The Novell LDAP SDK only understands the "
|
||||
"DER and PEM (BASE64) file types.";
|
||||
break;
|
||||
}
|
||||
if (result->rc != LDAP_SUCCESS) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
#else
|
||||
result->reason = "LDAP: ldapssl_client_init(), "
|
||||
"ldapssl_add_trusted_cert() or "
|
||||
"ldapssl_client_deinit() functions not supported "
|
||||
"by this Novell SDK. Certificate authority file "
|
||||
"not set";
|
||||
result->rc = -1;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* OpenLDAP SDK */
|
||||
#if AP_HAS_OPENLDAP_LDAPSDK
|
||||
#ifdef LDAP_OPT_X_TLS_CACERTFILE
|
||||
#ifndef LDAP_OPT_X_TLS_NEWCTX
|
||||
if (ldap) {
|
||||
result->reason = "LDAP: The OpenLDAP SDK cannot support the setting "
|
||||
"of certificates or keys on a per connection basis.";
|
||||
result->rc = -1;
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* set one or more certificates */
|
||||
/* FIXME: make it support setting directories as well as files */
|
||||
for (i = 0; i < certs->nelts; i++) {
|
||||
/* OpenLDAP SDK supports BASE64 files. */
|
||||
switch (ents[i].type) {
|
||||
case AP_LDAP_CA_TYPE_BASE64:
|
||||
result->rc = ldap_set_option(ldap, LDAP_OPT_X_TLS_CACERTFILE,
|
||||
(void *)ents[i].path);
|
||||
result->msg = ldap_err2string(result->rc);
|
||||
break;
|
||||
case AP_LDAP_CERT_TYPE_BASE64:
|
||||
result->rc = ldap_set_option(ldap, LDAP_OPT_X_TLS_CERTFILE,
|
||||
(void *)ents[i].path);
|
||||
result->msg = ldap_err2string(result->rc);
|
||||
break;
|
||||
case AP_LDAP_KEY_TYPE_BASE64:
|
||||
result->rc = ldap_set_option(ldap, LDAP_OPT_X_TLS_KEYFILE,
|
||||
(void *)ents[i].path);
|
||||
result->msg = ldap_err2string(result->rc);
|
||||
break;
|
||||
#ifdef LDAP_OPT_X_TLS_CACERTDIR
|
||||
case AP_LDAP_CA_TYPE_CACERTDIR_BASE64:
|
||||
result->rc = ldap_set_option(ldap, LDAP_OPT_X_TLS_CACERTDIR,
|
||||
(void *)ents[i].path);
|
||||
result->msg = ldap_err2string(result->rc);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
result->rc = -1;
|
||||
result->reason = "LDAP: The OpenLDAP SDK only understands the "
|
||||
"PEM (BASE64) file type.";
|
||||
break;
|
||||
}
|
||||
if (result->rc != LDAP_SUCCESS) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
#ifdef LDAP_OPT_X_TLS_NEWCTX
|
||||
/* Certificate settings are now configured, but we also need a new
|
||||
* TLS context to be created. This applies to both gnuTLS and openssl
|
||||
*/
|
||||
if (ldap && (result->rc == LDAP_SUCCESS)) {
|
||||
int IS_SERVER = 0;
|
||||
result->rc = ldap_set_option(ldap, LDAP_OPT_X_TLS_NEWCTX, &IS_SERVER);
|
||||
result->msg = ldap_err2string(result->rc);
|
||||
}
|
||||
#endif
|
||||
|
||||
#else
|
||||
result->reason = "LDAP: LDAP_OPT_X_TLS_CACERTFILE not "
|
||||
"defined by this OpenLDAP SDK. Certificate "
|
||||
"authority file not set";
|
||||
result->rc = -1;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Microsoft SDK */
|
||||
#if AP_HAS_MICROSOFT_LDAPSDK
|
||||
/* Microsoft SDK use the registry certificate store - error out
|
||||
* here with a message explaining this. */
|
||||
result->reason = "LDAP: CA certificates cannot be set using this method, "
|
||||
"as they are stored in the registry instead.";
|
||||
result->rc = -1;
|
||||
#endif
|
||||
|
||||
/* SDK not recognised */
|
||||
#if AP_HAS_OTHER_LDAPSDK
|
||||
result->reason = "LDAP: LDAP_OPT_X_TLS_CACERTFILE not "
|
||||
"defined by this LDAP SDK. Certificate "
|
||||
"authority file not set";
|
||||
result->rc = -1;
|
||||
#endif
|
||||
|
||||
#else /* not compiled with SSL Support */
|
||||
result->reason = "LDAP: Attempt to set certificate(s) failed. "
|
||||
"Not built with SSL support";
|
||||
result->rc = -1;
|
||||
#endif /* AP_HAS_LDAP_SSL */
|
||||
|
||||
}
|
||||
|
||||
#endif /* AP_HAS_LDAP */
|
||||
|
@ -1,371 +0,0 @@
|
||||
/* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You 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
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/* ap_ldap_rebind.c -- LDAP rebind callbacks for referrals
|
||||
*
|
||||
* The LDAP SDK allows a callback to be set to enable rebinding
|
||||
* for referral processing.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "apr.h"
|
||||
#include "ap_config.h"
|
||||
#include "ap_ldap.h"
|
||||
|
||||
#if AP_HAS_LDAP
|
||||
|
||||
#include "apr_errno.h"
|
||||
#include "apr_strings.h"
|
||||
|
||||
#include "stdio.h"
|
||||
|
||||
/* Used to store information about connections for use in the referral rebind callback. */
|
||||
struct ap_ldap_rebind_entry {
|
||||
apr_pool_t *pool;
|
||||
LDAP *index;
|
||||
const char *bindDN;
|
||||
const char *bindPW;
|
||||
struct ap_ldap_rebind_entry *next;
|
||||
};
|
||||
typedef struct ap_ldap_rebind_entry ap_ldap_rebind_entry_t;
|
||||
|
||||
|
||||
#ifdef NETWARE
|
||||
#define get_apd \
|
||||
APP_DATA* apd = (APP_DATA*)get_app_data(gLibId); \
|
||||
ap_ldap_xref_lock = (apr_thread_mutex_t *)apd->gs_ldap_xref_lock; \
|
||||
xref_head = (ap_ldap_rebind_entry_t *)apd->gs_xref_head;
|
||||
#endif
|
||||
|
||||
#if APR_HAS_THREADS
|
||||
static apr_thread_mutex_t *ap_ldap_xref_lock = NULL;
|
||||
#endif
|
||||
static ap_ldap_rebind_entry_t *xref_head = NULL;
|
||||
|
||||
static int ap_ldap_rebind_set_callback(LDAP *ld);
|
||||
static apr_status_t ap_ldap_rebind_remove_helper(void *data);
|
||||
|
||||
static apr_status_t ap_ldap_pool_cleanup_set_null(void *data_)
|
||||
{
|
||||
void **ptr = (void **)data_;
|
||||
*ptr = NULL;
|
||||
return APR_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/* AP utility routine used to create the xref_lock. */
|
||||
MODLDAP_DECLARE(apr_status_t) ap_ldap_rebind_init(apr_pool_t *pool)
|
||||
{
|
||||
apr_status_t retcode = APR_SUCCESS;
|
||||
|
||||
#ifdef NETWARE
|
||||
get_apd
|
||||
#endif
|
||||
|
||||
/* run after apr_thread_mutex_create cleanup */
|
||||
apr_pool_cleanup_register(pool, &ap_ldap_xref_lock, ap_ldap_pool_cleanup_set_null,
|
||||
apr_pool_cleanup_null);
|
||||
|
||||
#if APR_HAS_THREADS
|
||||
if (ap_ldap_xref_lock == NULL) {
|
||||
retcode = apr_thread_mutex_create(&ap_ldap_xref_lock, APR_THREAD_MUTEX_DEFAULT, pool);
|
||||
}
|
||||
#endif
|
||||
|
||||
return(retcode);
|
||||
}
|
||||
|
||||
|
||||
MODLDAP_DECLARE(apr_status_t) ap_ldap_rebind_add(apr_pool_t *pool,
|
||||
LDAP *ld,
|
||||
const char *bindDN,
|
||||
const char *bindPW)
|
||||
{
|
||||
apr_status_t retcode = APR_SUCCESS;
|
||||
ap_ldap_rebind_entry_t *new_xref;
|
||||
|
||||
#ifdef NETWARE
|
||||
get_apd
|
||||
#endif
|
||||
|
||||
new_xref = (ap_ldap_rebind_entry_t *)apr_pcalloc(pool, sizeof(ap_ldap_rebind_entry_t));
|
||||
if (new_xref) {
|
||||
new_xref->pool = pool;
|
||||
new_xref->index = ld;
|
||||
if (bindDN) {
|
||||
new_xref->bindDN = apr_pstrdup(pool, bindDN);
|
||||
}
|
||||
if (bindPW) {
|
||||
new_xref->bindPW = apr_pstrdup(pool, bindPW);
|
||||
}
|
||||
|
||||
#if APR_HAS_THREADS
|
||||
retcode = apr_thread_mutex_lock(ap_ldap_xref_lock);
|
||||
if (retcode != APR_SUCCESS) {
|
||||
return retcode;
|
||||
}
|
||||
#endif
|
||||
|
||||
new_xref->next = xref_head;
|
||||
xref_head = new_xref;
|
||||
|
||||
#if APR_HAS_THREADS
|
||||
retcode = apr_thread_mutex_unlock(ap_ldap_xref_lock);
|
||||
if (retcode != APR_SUCCESS) {
|
||||
return retcode;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
return(APR_ENOMEM);
|
||||
}
|
||||
|
||||
retcode = ap_ldap_rebind_set_callback(ld);
|
||||
if (APR_SUCCESS != retcode) {
|
||||
ap_ldap_rebind_remove(ld);
|
||||
return retcode;
|
||||
}
|
||||
|
||||
apr_pool_cleanup_register(pool, ld,
|
||||
ap_ldap_rebind_remove_helper,
|
||||
apr_pool_cleanup_null);
|
||||
|
||||
return(APR_SUCCESS);
|
||||
}
|
||||
|
||||
|
||||
MODLDAP_DECLARE(apr_status_t) ap_ldap_rebind_remove(LDAP *ld)
|
||||
{
|
||||
ap_ldap_rebind_entry_t *tmp_xref, *prev = NULL;
|
||||
apr_status_t retcode = 0;
|
||||
|
||||
#ifdef NETWARE
|
||||
get_apd
|
||||
#endif
|
||||
|
||||
#if APR_HAS_THREADS
|
||||
retcode = apr_thread_mutex_lock(ap_ldap_xref_lock);
|
||||
if (retcode != APR_SUCCESS) {
|
||||
return retcode;
|
||||
}
|
||||
#endif
|
||||
tmp_xref = xref_head;
|
||||
|
||||
while ((tmp_xref) && (tmp_xref->index != ld)) {
|
||||
prev = tmp_xref;
|
||||
tmp_xref = tmp_xref->next;
|
||||
}
|
||||
|
||||
if (tmp_xref) {
|
||||
if (tmp_xref == xref_head) {
|
||||
xref_head = xref_head->next;
|
||||
}
|
||||
else {
|
||||
prev->next = tmp_xref->next;
|
||||
}
|
||||
|
||||
/* tmp_xref and its contents were pool allocated so they don't need to be freed here. */
|
||||
|
||||
/* remove the cleanup, just in case this was done manually */
|
||||
apr_pool_cleanup_kill(tmp_xref->pool, tmp_xref->index,
|
||||
ap_ldap_rebind_remove_helper);
|
||||
}
|
||||
|
||||
#if APR_HAS_THREADS
|
||||
retcode = apr_thread_mutex_unlock(ap_ldap_xref_lock);
|
||||
if (retcode != APR_SUCCESS) {
|
||||
return retcode;
|
||||
}
|
||||
#endif
|
||||
return APR_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
static apr_status_t ap_ldap_rebind_remove_helper(void *data)
|
||||
{
|
||||
LDAP *ld = (LDAP *)data;
|
||||
ap_ldap_rebind_remove(ld);
|
||||
return APR_SUCCESS;
|
||||
}
|
||||
|
||||
#if AP_HAS_TIVOLI_LDAPSDK || AP_HAS_OPENLDAP_LDAPSDK || AP_HAS_NOVELL_LDAPSDK
|
||||
static ap_ldap_rebind_entry_t *ap_ldap_rebind_lookup(LDAP *ld)
|
||||
{
|
||||
ap_ldap_rebind_entry_t *tmp_xref, *match = NULL;
|
||||
|
||||
#ifdef NETWARE
|
||||
get_apd
|
||||
#endif
|
||||
|
||||
#if APR_HAS_THREADS
|
||||
apr_thread_mutex_lock(ap_ldap_xref_lock);
|
||||
#endif
|
||||
tmp_xref = xref_head;
|
||||
|
||||
while (tmp_xref) {
|
||||
if (tmp_xref->index == ld) {
|
||||
match = tmp_xref;
|
||||
tmp_xref = NULL;
|
||||
}
|
||||
else {
|
||||
tmp_xref = tmp_xref->next;
|
||||
}
|
||||
}
|
||||
|
||||
#if APR_HAS_THREADS
|
||||
apr_thread_mutex_unlock(ap_ldap_xref_lock);
|
||||
#endif
|
||||
|
||||
return (match);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if AP_HAS_TIVOLI_LDAPSDK
|
||||
|
||||
/* LDAP_rebindproc() Tivoli LDAP style
|
||||
* Rebind callback function. Called when chasing referrals. See API docs.
|
||||
* ON ENTRY:
|
||||
* ld Pointer to an LDAP control structure. (input only)
|
||||
* binddnp Pointer to an Application DName used for binding (in *or* out)
|
||||
* passwdp Pointer to the password associated with the DName (in *or* out)
|
||||
* methodp Pointer to the Auth method (output only)
|
||||
* freeit Flag to indicate if this is a lookup or a free request (input only)
|
||||
*/
|
||||
static int LDAP_rebindproc(LDAP *ld, char **binddnp, char **passwdp, int *methodp, int freeit)
|
||||
{
|
||||
if (!freeit) {
|
||||
ap_ldap_rebind_entry_t *my_conn;
|
||||
|
||||
*methodp = LDAP_AUTH_SIMPLE;
|
||||
my_conn = ap_ldap_rebind_lookup(ld);
|
||||
|
||||
if ((my_conn) && (my_conn->bindDN != NULL)) {
|
||||
*binddnp = strdup(my_conn->bindDN);
|
||||
*passwdp = strdup(my_conn->bindPW);
|
||||
} else {
|
||||
*binddnp = NULL;
|
||||
*passwdp = NULL;
|
||||
}
|
||||
} else {
|
||||
if (*binddnp) {
|
||||
free(*binddnp);
|
||||
}
|
||||
if (*passwdp) {
|
||||
free(*passwdp);
|
||||
}
|
||||
}
|
||||
|
||||
return LDAP_SUCCESS;
|
||||
}
|
||||
|
||||
static int ap_ldap_rebind_set_callback(LDAP *ld)
|
||||
{
|
||||
ldap_set_rebind_proc(ld, (LDAPRebindProc)LDAP_rebindproc);
|
||||
return APR_SUCCESS;
|
||||
}
|
||||
|
||||
#elif AP_HAS_OPENLDAP_LDAPSDK
|
||||
|
||||
/* LDAP_rebindproc() openLDAP V3 style
|
||||
* ON ENTRY:
|
||||
* ld Pointer to an LDAP control structure. (input only)
|
||||
* url Unused in this routine
|
||||
* request Unused in this routine
|
||||
* msgid Unused in this routine
|
||||
* params Unused in this routine
|
||||
*
|
||||
* or
|
||||
*
|
||||
* ld Pointer to an LDAP control structure. (input only)
|
||||
* url Unused in this routine
|
||||
* request Unused in this routine
|
||||
* msgid Unused in this routine
|
||||
*/
|
||||
#if defined(LDAP_SET_REBIND_PROC_THREE)
|
||||
static int LDAP_rebindproc(LDAP *ld, LDAP_CONST char *url, ber_tag_t request,
|
||||
ber_int_t msgid, void *params)
|
||||
#else
|
||||
static int LDAP_rebindproc(LDAP *ld, LDAP_CONST char *url, int request,
|
||||
ber_int_t msgid)
|
||||
#endif
|
||||
{
|
||||
ap_ldap_rebind_entry_t *my_conn;
|
||||
const char *bindDN = NULL;
|
||||
const char *bindPW = NULL;
|
||||
|
||||
my_conn = ap_ldap_rebind_lookup(ld);
|
||||
|
||||
if ((my_conn) && (my_conn->bindDN != NULL)) {
|
||||
bindDN = my_conn->bindDN;
|
||||
bindPW = my_conn->bindPW;
|
||||
}
|
||||
|
||||
return (ldap_bind_s(ld, bindDN, bindPW, LDAP_AUTH_SIMPLE));
|
||||
}
|
||||
|
||||
static int ap_ldap_rebind_set_callback(LDAP *ld)
|
||||
{
|
||||
#if defined(LDAP_SET_REBIND_PROC_THREE)
|
||||
ldap_set_rebind_proc(ld, LDAP_rebindproc, NULL);
|
||||
#else
|
||||
ldap_set_rebind_proc(ld, LDAP_rebindproc);
|
||||
#endif
|
||||
return APR_SUCCESS;
|
||||
}
|
||||
|
||||
#elif AP_HAS_NOVELL_LDAPSDK
|
||||
|
||||
/* LDAP_rebindproc() openLDAP V3 style
|
||||
* ON ENTRY:
|
||||
* ld Pointer to an LDAP control structure. (input only)
|
||||
* url Unused in this routine
|
||||
* request Unused in this routine
|
||||
* msgid Unused in this routine
|
||||
*/
|
||||
static int LDAP_rebindproc(LDAP *ld, LDAP_CONST char *url, int request, ber_int_t msgid)
|
||||
{
|
||||
|
||||
ap_ldap_rebind_entry_t *my_conn;
|
||||
const char *bindDN = NULL;
|
||||
const char *bindPW = NULL;
|
||||
|
||||
my_conn = ap_ldap_rebind_lookup(ld);
|
||||
|
||||
if ((my_conn) && (my_conn->bindDN != NULL)) {
|
||||
bindDN = my_conn->bindDN;
|
||||
bindPW = my_conn->bindPW;
|
||||
}
|
||||
|
||||
return (ldap_bind_s(ld, bindDN, bindPW, LDAP_AUTH_SIMPLE));
|
||||
}
|
||||
|
||||
static int ap_ldap_rebind_set_callback(LDAP *ld)
|
||||
{
|
||||
ldap_set_rebind_proc(ld, LDAP_rebindproc);
|
||||
return APR_SUCCESS;
|
||||
}
|
||||
|
||||
#else /* Implementation not recognised */
|
||||
|
||||
static int ap_ldap_rebind_set_callback(LDAP *ld)
|
||||
{
|
||||
return APR_ENOTIMPL;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* AP_HAS_LDAP */
|
@ -1,695 +0,0 @@
|
||||
/* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You 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
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/* Portions Copyright 1998-2002 The OpenLDAP Foundation
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted only as authorized by the OpenLDAP
|
||||
* Public License. A copy of this license is available at
|
||||
* http://www.OpenLDAP.org/license.html or in file LICENSE in the
|
||||
* top-level directory of the distribution.
|
||||
*
|
||||
* OpenLDAP is a registered trademark of the OpenLDAP Foundation.
|
||||
*
|
||||
* Individual files and/or contributed packages may be copyright by
|
||||
* other parties and subject to additional restrictions.
|
||||
*
|
||||
* This work is derived from the University of Michigan LDAP v3.3
|
||||
* distribution. Information concerning this software is available
|
||||
* at: http://www.umich.edu/~dirsvcs/ldap/
|
||||
*
|
||||
* This work also contains materials derived from public sources.
|
||||
*
|
||||
* Additional information about OpenLDAP can be obtained at:
|
||||
* http://www.openldap.org/
|
||||
*/
|
||||
|
||||
/*
|
||||
* Portions Copyright (c) 1992-1996 Regents of the University of Michigan.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms are permitted
|
||||
* provided that this notice is preserved and that due credit is given
|
||||
* to the University of Michigan at Ann Arbor. The name of the University
|
||||
* may not be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission. This software
|
||||
* is provided ``as is'' without express or implied warranty.
|
||||
*/
|
||||
|
||||
/* ap_ldap_url.c -- LDAP URL (RFC 2255) related routines
|
||||
*
|
||||
* Win32 and perhaps other non-OpenLDAP based ldap libraries may be
|
||||
* missing ldap_url_* APIs. We focus here on the one significant
|
||||
* aspect, which is parsing. We have [for the time being] omitted
|
||||
* the ldap_url_search APIs.
|
||||
*
|
||||
* LDAP URLs look like this:
|
||||
* ldap[is]://host:port[/[dn[?[attributes][?[scope][?[filter][?exts]]]]]]
|
||||
*
|
||||
* where:
|
||||
* attributes is a comma separated list
|
||||
* scope is one of these three strings: base one sub (default=base)
|
||||
* filter is an string-represented filter as in RFC 2254
|
||||
*
|
||||
* e.g., ldap://host:port/dc=com?o,cn?base?o=openldap?extension
|
||||
*
|
||||
* Tolerates URLs that look like: <ldapurl> and <URL:ldapurl>
|
||||
*/
|
||||
|
||||
#include "apu.h"
|
||||
#include "apr_pools.h"
|
||||
#include "apr_general.h"
|
||||
#include "apr_strings.h"
|
||||
#include "ap_config.h"
|
||||
#include "ap_ldap.h"
|
||||
|
||||
#if AP_HAS_LDAP
|
||||
|
||||
#if APR_HAVE_STDLIB_H
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
|
||||
#ifndef LDAPS_PORT
|
||||
#define LDAPS_PORT 636 /* ldaps:/// default LDAP over TLS port */
|
||||
#endif
|
||||
|
||||
#define AP_LDAP_URL_PREFIX "ldap://"
|
||||
#define AP_LDAP_URL_PREFIX_LEN (sizeof(AP_LDAP_URL_PREFIX)-1)
|
||||
#define AP_LDAPS_URL_PREFIX "ldaps://"
|
||||
#define AP_LDAPS_URL_PREFIX_LEN (sizeof(AP_LDAPS_URL_PREFIX)-1)
|
||||
#define AP_LDAPI_URL_PREFIX "ldapi://"
|
||||
#define AP_LDAPI_URL_PREFIX_LEN (sizeof(AP_LDAPI_URL_PREFIX)-1)
|
||||
#define AP_LDAP_URL_URLCOLON "URL:"
|
||||
#define AP_LDAP_URL_URLCOLON_LEN (sizeof(AP_LDAP_URL_URLCOLON)-1)
|
||||
|
||||
|
||||
/* local functions */
|
||||
static const char* skip_url_prefix(const char *url,
|
||||
int *enclosedp,
|
||||
const char **scheme);
|
||||
|
||||
static void ap_ldap_pvt_hex_unescape(char *s);
|
||||
|
||||
static int ap_ldap_pvt_unhex(int c);
|
||||
|
||||
static char **ap_ldap_str2charray(apr_pool_t *pool,
|
||||
const char *str,
|
||||
const char *brkstr);
|
||||
|
||||
|
||||
/**
|
||||
* Is this URL an ldap url?
|
||||
*
|
||||
*/
|
||||
MODLDAP_DECLARE(int) ap_ldap_is_ldap_url(const char *url)
|
||||
{
|
||||
int enclosed;
|
||||
const char * scheme;
|
||||
|
||||
if( url == NULL ) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if( skip_url_prefix( url, &enclosed, &scheme ) == NULL ) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is this URL a secure ldap url?
|
||||
*
|
||||
*/
|
||||
MODLDAP_DECLARE(int) ap_ldap_is_ldaps_url(const char *url)
|
||||
{
|
||||
int enclosed;
|
||||
const char * scheme;
|
||||
|
||||
if( url == NULL ) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if( skip_url_prefix( url, &enclosed, &scheme ) == NULL ) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return strcmp(scheme, "ldaps") == 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is this URL an ldap socket url?
|
||||
*
|
||||
*/
|
||||
MODLDAP_DECLARE(int) ap_ldap_is_ldapi_url(const char *url)
|
||||
{
|
||||
int enclosed;
|
||||
const char * scheme;
|
||||
|
||||
if( url == NULL ) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if( skip_url_prefix( url, &enclosed, &scheme ) == NULL ) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return strcmp(scheme, "ldapi") == 0;
|
||||
}
|
||||
|
||||
|
||||
static const char *skip_url_prefix(const char *url, int *enclosedp,
|
||||
const char **scheme)
|
||||
{
|
||||
/*
|
||||
* return non-zero if this looks like a LDAP URL; zero if not
|
||||
* if non-zero returned, *urlp will be moved past "ldap://" part of URL
|
||||
*/
|
||||
const char *p;
|
||||
|
||||
if ( url == NULL ) {
|
||||
return( NULL );
|
||||
}
|
||||
|
||||
p = url;
|
||||
|
||||
/* skip leading '<' (if any) */
|
||||
if ( *p == '<' ) {
|
||||
*enclosedp = 1;
|
||||
++p;
|
||||
} else {
|
||||
*enclosedp = 0;
|
||||
}
|
||||
|
||||
/* skip leading "URL:" (if any) */
|
||||
if ( strncasecmp( p, AP_LDAP_URL_URLCOLON, AP_LDAP_URL_URLCOLON_LEN ) == 0 ) {
|
||||
p += AP_LDAP_URL_URLCOLON_LEN;
|
||||
}
|
||||
|
||||
/* check for "ldap://" prefix */
|
||||
if ( strncasecmp( p, AP_LDAP_URL_PREFIX, AP_LDAP_URL_PREFIX_LEN ) == 0 ) {
|
||||
/* skip over "ldap://" prefix and return success */
|
||||
p += AP_LDAP_URL_PREFIX_LEN;
|
||||
*scheme = "ldap";
|
||||
return( p );
|
||||
}
|
||||
|
||||
/* check for "ldaps://" prefix */
|
||||
if ( strncasecmp( p, AP_LDAPS_URL_PREFIX, AP_LDAPS_URL_PREFIX_LEN ) == 0 ) {
|
||||
/* skip over "ldaps://" prefix and return success */
|
||||
p += AP_LDAPS_URL_PREFIX_LEN;
|
||||
*scheme = "ldaps";
|
||||
return( p );
|
||||
}
|
||||
|
||||
/* check for "ldapi://" prefix */
|
||||
if ( strncasecmp( p, AP_LDAPI_URL_PREFIX, AP_LDAPI_URL_PREFIX_LEN ) == 0 ) {
|
||||
/* skip over "ldapi://" prefix and return success */
|
||||
p += AP_LDAPI_URL_PREFIX_LEN;
|
||||
*scheme = "ldapi";
|
||||
return( p );
|
||||
}
|
||||
|
||||
return( NULL );
|
||||
}
|
||||
|
||||
|
||||
static int str2scope(const char *p)
|
||||
{
|
||||
if ( strcasecmp( p, "one" ) == 0 ) {
|
||||
return LDAP_SCOPE_ONELEVEL;
|
||||
|
||||
} else if ( strcasecmp( p, "onetree" ) == 0 ) {
|
||||
return LDAP_SCOPE_ONELEVEL;
|
||||
|
||||
} else if ( strcasecmp( p, "base" ) == 0 ) {
|
||||
return LDAP_SCOPE_BASE;
|
||||
|
||||
} else if ( strcasecmp( p, "sub" ) == 0 ) {
|
||||
return LDAP_SCOPE_SUBTREE;
|
||||
|
||||
} else if ( strcasecmp( p, "subtree" ) == 0 ) {
|
||||
return LDAP_SCOPE_SUBTREE;
|
||||
}
|
||||
|
||||
return( -1 );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Parse the URL provided into an ap_ldap_url_desc_t object.
|
||||
*
|
||||
* APR_SUCCESS is returned on success, APR_EGENERAL on failure.
|
||||
* The LDAP result code and reason string is returned in the
|
||||
* ap_ldap_err_t structure.
|
||||
*/
|
||||
MODLDAP_DECLARE(int) ap_ldap_url_parse_ext(apr_pool_t *pool,
|
||||
const char *url_in,
|
||||
ap_ldap_url_desc_t **ludpp,
|
||||
ap_ldap_err_t **result_err)
|
||||
{
|
||||
ap_ldap_url_desc_t *ludp;
|
||||
char *p, *q, *r;
|
||||
int i, enclosed;
|
||||
const char *scheme = NULL;
|
||||
const char *url_tmp;
|
||||
char *url;
|
||||
|
||||
ap_ldap_err_t *result = (ap_ldap_err_t *)apr_pcalloc(pool, sizeof(ap_ldap_err_t));
|
||||
*result_err = result;
|
||||
|
||||
/* sanity check our parameters */
|
||||
if( url_in == NULL || ludpp == NULL ) {
|
||||
result->reason = "Either the LDAP URL, or the URL structure was NULL. Oops.";
|
||||
result->rc = AP_LDAP_URL_ERR_PARAM;
|
||||
return APR_EGENERAL;
|
||||
}
|
||||
|
||||
*ludpp = NULL; /* pessimistic */
|
||||
|
||||
url_tmp = skip_url_prefix( url_in, &enclosed, &scheme );
|
||||
if ( url_tmp == NULL ) {
|
||||
result->reason = "The scheme was not recognised as a valid LDAP URL scheme.";
|
||||
result->rc = AP_LDAP_URL_ERR_BADSCHEME;
|
||||
return APR_EGENERAL;
|
||||
}
|
||||
|
||||
/* make working copy of the remainder of the URL */
|
||||
url = (char *)apr_pstrdup(pool, url_tmp);
|
||||
if ( url == NULL ) {
|
||||
result->reason = "Out of memory parsing LDAP URL.";
|
||||
result->rc = AP_LDAP_URL_ERR_MEM;
|
||||
return APR_EGENERAL;
|
||||
}
|
||||
|
||||
if ( enclosed ) {
|
||||
p = &url[strlen(url)-1];
|
||||
|
||||
if( *p != '>' ) {
|
||||
result->reason = "Bad enclosure error while parsing LDAP URL.";
|
||||
result->rc = AP_LDAP_URL_ERR_BADENCLOSURE;
|
||||
return APR_EGENERAL;
|
||||
}
|
||||
|
||||
*p = '\0';
|
||||
}
|
||||
|
||||
/* allocate return struct */
|
||||
ludp = (ap_ldap_url_desc_t *)apr_pcalloc(pool, sizeof(ap_ldap_url_desc_t));
|
||||
if ( ludp == NULL ) {
|
||||
result->reason = "Out of memory parsing LDAP URL.";
|
||||
result->rc = AP_LDAP_URL_ERR_MEM;
|
||||
return APR_EGENERAL;
|
||||
}
|
||||
|
||||
ludp->lud_next = NULL;
|
||||
ludp->lud_host = NULL;
|
||||
ludp->lud_port = LDAP_PORT;
|
||||
ludp->lud_dn = NULL;
|
||||
ludp->lud_attrs = NULL;
|
||||
ludp->lud_filter = NULL;
|
||||
ludp->lud_scope = -1;
|
||||
ludp->lud_filter = NULL;
|
||||
ludp->lud_exts = NULL;
|
||||
|
||||
ludp->lud_scheme = (char *)apr_pstrdup(pool, scheme);
|
||||
if ( ludp->lud_scheme == NULL ) {
|
||||
result->reason = "Out of memory parsing LDAP URL.";
|
||||
result->rc = AP_LDAP_URL_ERR_MEM;
|
||||
return APR_EGENERAL;
|
||||
}
|
||||
|
||||
if( strcasecmp( ludp->lud_scheme, "ldaps" ) == 0 ) {
|
||||
ludp->lud_port = LDAPS_PORT;
|
||||
}
|
||||
|
||||
/* scan forward for '/' that marks end of hostport and begin. of dn */
|
||||
p = strchr( url, '/' );
|
||||
|
||||
if( p != NULL ) {
|
||||
/* terminate hostport; point to start of dn */
|
||||
*p++ = '\0';
|
||||
}
|
||||
|
||||
/* IPv6 syntax with [ip address]:port */
|
||||
if ( *url == '[' ) {
|
||||
r = strchr( url, ']' );
|
||||
if ( r == NULL ) {
|
||||
result->reason = "Bad LDAP URL while parsing IPV6 syntax.";
|
||||
result->rc = AP_LDAP_URL_ERR_BADURL;
|
||||
return APR_EGENERAL;
|
||||
}
|
||||
*r++ = '\0';
|
||||
q = strrchr( r, ':' );
|
||||
} else {
|
||||
q = strrchr( url, ':' );
|
||||
}
|
||||
|
||||
if ( q != NULL ) {
|
||||
ap_ldap_pvt_hex_unescape( ++q );
|
||||
|
||||
if( *q == '\0' ) {
|
||||
result->reason = "Bad LDAP URL while parsing.";
|
||||
result->rc = AP_LDAP_URL_ERR_BADURL;
|
||||
return APR_EGENERAL;
|
||||
}
|
||||
|
||||
ludp->lud_port = atoi( q );
|
||||
}
|
||||
|
||||
ap_ldap_pvt_hex_unescape( url );
|
||||
|
||||
/* If [ip address]:port syntax, url is [ip and we skip the [ */
|
||||
ludp->lud_host = (char *)apr_pstrdup(pool, url + ( *url == '[' ));
|
||||
if( ludp->lud_host == NULL ) {
|
||||
result->reason = "Out of memory parsing LDAP URL.";
|
||||
result->rc = AP_LDAP_URL_ERR_MEM;
|
||||
return APR_EGENERAL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Kludge. ldap://111.222.333.444:389??cn=abc,o=company
|
||||
*
|
||||
* On early Novell releases, search references/referrals were returned
|
||||
* in this format, i.e., the dn was kind of in the scope position,
|
||||
* but the required slash is missing. The whole thing is illegal syntax,
|
||||
* but we need to account for it. Fortunately it can't be confused with
|
||||
* anything real.
|
||||
*/
|
||||
if( (p == NULL) && (q != NULL) && ((q = strchr( q, '?')) != NULL)) {
|
||||
q++;
|
||||
/* ? immediately followed by question */
|
||||
if( *q == '?') {
|
||||
q++;
|
||||
if( *q != '\0' ) {
|
||||
/* parse dn part */
|
||||
ap_ldap_pvt_hex_unescape( q );
|
||||
ludp->lud_dn = (char *)apr_pstrdup(pool, q);
|
||||
} else {
|
||||
ludp->lud_dn = (char *)apr_pstrdup(pool, "");
|
||||
}
|
||||
|
||||
if( ludp->lud_dn == NULL ) {
|
||||
result->reason = "Out of memory parsing LDAP URL.";
|
||||
result->rc = AP_LDAP_URL_ERR_MEM;
|
||||
return APR_EGENERAL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( p == NULL ) {
|
||||
*ludpp = ludp;
|
||||
return APR_SUCCESS;
|
||||
}
|
||||
|
||||
/* scan forward for '?' that may marks end of dn */
|
||||
q = strchr( p, '?' );
|
||||
|
||||
if( q != NULL ) {
|
||||
/* terminate dn part */
|
||||
*q++ = '\0';
|
||||
}
|
||||
|
||||
if( *p != '\0' ) {
|
||||
/* parse dn part */
|
||||
ap_ldap_pvt_hex_unescape( p );
|
||||
ludp->lud_dn = (char *)apr_pstrdup(pool, p);
|
||||
} else {
|
||||
ludp->lud_dn = (char *)apr_pstrdup(pool, "");
|
||||
}
|
||||
|
||||
if( ludp->lud_dn == NULL ) {
|
||||
result->reason = "Out of memory parsing LDAP URL.";
|
||||
result->rc = AP_LDAP_URL_ERR_MEM;
|
||||
return APR_EGENERAL;
|
||||
}
|
||||
|
||||
if( q == NULL ) {
|
||||
/* no more */
|
||||
*ludpp = ludp;
|
||||
return APR_SUCCESS;
|
||||
}
|
||||
|
||||
/* scan forward for '?' that may marks end of attributes */
|
||||
p = q;
|
||||
q = strchr( p, '?' );
|
||||
|
||||
if( q != NULL ) {
|
||||
/* terminate attributes part */
|
||||
*q++ = '\0';
|
||||
}
|
||||
|
||||
if( *p != '\0' ) {
|
||||
/* parse attributes */
|
||||
ap_ldap_pvt_hex_unescape( p );
|
||||
ludp->lud_attrs = ap_ldap_str2charray(pool, p, ",");
|
||||
|
||||
if( ludp->lud_attrs == NULL ) {
|
||||
result->reason = "Bad attributes encountered while parsing LDAP URL.";
|
||||
result->rc = AP_LDAP_URL_ERR_BADATTRS;
|
||||
return APR_EGENERAL;
|
||||
}
|
||||
}
|
||||
|
||||
if ( q == NULL ) {
|
||||
/* no more */
|
||||
*ludpp = ludp;
|
||||
return APR_SUCCESS;
|
||||
}
|
||||
|
||||
/* scan forward for '?' that may marks end of scope */
|
||||
p = q;
|
||||
q = strchr( p, '?' );
|
||||
|
||||
if( q != NULL ) {
|
||||
/* terminate the scope part */
|
||||
*q++ = '\0';
|
||||
}
|
||||
|
||||
if( *p != '\0' ) {
|
||||
/* parse the scope */
|
||||
ap_ldap_pvt_hex_unescape( p );
|
||||
ludp->lud_scope = str2scope( p );
|
||||
|
||||
if( ludp->lud_scope == -1 ) {
|
||||
result->reason = "Bad scope encountered while parsing LDAP URL.";
|
||||
result->rc = AP_LDAP_URL_ERR_BADSCOPE;
|
||||
return APR_EGENERAL;
|
||||
}
|
||||
}
|
||||
|
||||
if ( q == NULL ) {
|
||||
/* no more */
|
||||
*ludpp = ludp;
|
||||
return APR_SUCCESS;
|
||||
}
|
||||
|
||||
/* scan forward for '?' that may marks end of filter */
|
||||
p = q;
|
||||
q = strchr( p, '?' );
|
||||
|
||||
if( q != NULL ) {
|
||||
/* terminate the filter part */
|
||||
*q++ = '\0';
|
||||
}
|
||||
|
||||
if( *p != '\0' ) {
|
||||
/* parse the filter */
|
||||
ap_ldap_pvt_hex_unescape( p );
|
||||
|
||||
if( ! *p ) {
|
||||
/* missing filter */
|
||||
result->reason = "Bad filter encountered while parsing LDAP URL.";
|
||||
result->rc = AP_LDAP_URL_ERR_BADFILTER;
|
||||
return APR_EGENERAL;
|
||||
}
|
||||
|
||||
ludp->lud_filter = (char *)apr_pstrdup(pool, p);
|
||||
if( ludp->lud_filter == NULL ) {
|
||||
result->reason = "Out of memory parsing LDAP URL.";
|
||||
result->rc = AP_LDAP_URL_ERR_MEM;
|
||||
return APR_EGENERAL;
|
||||
}
|
||||
}
|
||||
|
||||
if ( q == NULL ) {
|
||||
/* no more */
|
||||
*ludpp = ludp;
|
||||
return APR_SUCCESS;
|
||||
}
|
||||
|
||||
/* scan forward for '?' that may marks end of extensions */
|
||||
p = q;
|
||||
q = strchr( p, '?' );
|
||||
|
||||
if( q != NULL ) {
|
||||
/* extra '?' */
|
||||
result->reason = "Bad URL encountered while parsing LDAP URL.";
|
||||
result->rc = AP_LDAP_URL_ERR_BADURL;
|
||||
return APR_EGENERAL;
|
||||
}
|
||||
|
||||
/* parse the extensions */
|
||||
ludp->lud_exts = ap_ldap_str2charray(pool, p, ",");
|
||||
if( ludp->lud_exts == NULL ) {
|
||||
result->reason = "Bad extensions encountered while parsing LDAP URL.";
|
||||
result->rc = AP_LDAP_URL_ERR_BADEXTS;
|
||||
return APR_EGENERAL;
|
||||
}
|
||||
|
||||
for( i=0; ludp->lud_exts[i] != NULL; i++ ) {
|
||||
ap_ldap_pvt_hex_unescape( ludp->lud_exts[i] );
|
||||
|
||||
if( *ludp->lud_exts[i] == '!' ) {
|
||||
/* count the number of critical extensions */
|
||||
ludp->lud_crit_exts++;
|
||||
}
|
||||
}
|
||||
|
||||
if( i == 0 ) {
|
||||
/* must have 1 or more */
|
||||
result->reason = "Bad extensions encountered while parsing LDAP URL.";
|
||||
result->rc = AP_LDAP_URL_ERR_BADEXTS;
|
||||
return APR_EGENERAL;
|
||||
}
|
||||
|
||||
/* no more */
|
||||
*ludpp = ludp;
|
||||
return APR_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Parse the URL provided into an ap_ldap_url_desc_t object.
|
||||
*
|
||||
* APR_SUCCESS is returned on success, APR_EGENERAL on failure.
|
||||
* The LDAP result code and reason string is returned in the
|
||||
* ap_ldap_err_t structure.
|
||||
*/
|
||||
MODLDAP_DECLARE(int) ap_ldap_url_parse(apr_pool_t *pool,
|
||||
const char *url_in,
|
||||
ap_ldap_url_desc_t **ludpp,
|
||||
ap_ldap_err_t **result_err)
|
||||
{
|
||||
|
||||
int rc = ap_ldap_url_parse_ext(pool, url_in, ludpp, result_err);
|
||||
if( rc != APR_SUCCESS ) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
if ((*ludpp)->lud_scope == -1) {
|
||||
(*ludpp)->lud_scope = LDAP_SCOPE_BASE;
|
||||
}
|
||||
|
||||
if ((*ludpp)->lud_host != NULL && *(*ludpp)->lud_host == '\0') {
|
||||
(*ludpp)->lud_host = NULL;
|
||||
}
|
||||
|
||||
return rc;
|
||||
|
||||
}
|
||||
|
||||
|
||||
static void ap_ldap_pvt_hex_unescape(char *s)
|
||||
{
|
||||
/*
|
||||
* Remove URL hex escapes from s... done in place. The basic concept for
|
||||
* this routine is borrowed from the WWW library HTUnEscape() routine.
|
||||
*/
|
||||
char *p;
|
||||
|
||||
for ( p = s; *s != '\0'; ++s ) {
|
||||
if ( *s == '%' ) {
|
||||
if ( *++s == '\0' ) {
|
||||
break;
|
||||
}
|
||||
*p = ap_ldap_pvt_unhex( *s ) << 4;
|
||||
if ( *++s == '\0' ) {
|
||||
break;
|
||||
}
|
||||
*p++ += ap_ldap_pvt_unhex( *s );
|
||||
} else {
|
||||
*p++ = *s;
|
||||
}
|
||||
}
|
||||
|
||||
*p = '\0';
|
||||
}
|
||||
|
||||
|
||||
static int ap_ldap_pvt_unhex(int c)
|
||||
{
|
||||
return( c >= '0' && c <= '9' ? c - '0'
|
||||
: c >= 'A' && c <= 'F' ? c - 'A' + 10
|
||||
: c - 'a' + 10 );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Convert a string to a character array
|
||||
*/
|
||||
static char **ap_ldap_str2charray(apr_pool_t *pool,
|
||||
const char *str_in,
|
||||
const char *brkstr)
|
||||
{
|
||||
char **res;
|
||||
char *str, *s;
|
||||
char *lasts;
|
||||
int i;
|
||||
|
||||
/* protect the input string from strtok */
|
||||
str = (char *)apr_pstrdup(pool, str_in);
|
||||
if( str == NULL ) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
i = 1;
|
||||
for ( s = str; *s; s++ ) {
|
||||
/* Warning: this strchr was previously ldap_utf8_strchr(), check
|
||||
* whether this particular code has any charset issues.
|
||||
*/
|
||||
if ( strchr( brkstr, *s ) != NULL ) {
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
res = (char **) apr_pcalloc(pool, (i + 1) * sizeof(char *));
|
||||
if( res == NULL ) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
i = 0;
|
||||
|
||||
for ( s = (char *)apr_strtok( str, brkstr, &lasts );
|
||||
s != NULL;
|
||||
s = (char *)apr_strtok( NULL, brkstr, &lasts ) ) {
|
||||
|
||||
res[i] = (char *)apr_pstrdup(pool, s);
|
||||
if(res[i] == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
res[i] = NULL;
|
||||
|
||||
return( res );
|
||||
|
||||
}
|
||||
|
||||
#endif /* AP_HAS_LDAP */
|
@ -3,22 +3,12 @@ dnl APACHE_MODULE(name, helptext[, objects[, structname[, default[, config]]]])
|
||||
|
||||
APACHE_MODPATH_INIT(ldap)
|
||||
|
||||
ldap_objects="dnl
|
||||
util_ldap.lo dnl
|
||||
util_ldap_cache.lo dnl
|
||||
util_ldap_cache_mgr.lo dnl
|
||||
ap_ldap_init.lo dnl
|
||||
ap_ldap_option.lo dnl
|
||||
ap_ldap_rebind.lo dnl
|
||||
ap_ldap_url.lo dnl
|
||||
"
|
||||
|
||||
ldap_objects="util_ldap.lo util_ldap_cache.lo util_ldap_cache_mgr.lo"
|
||||
APACHE_MODULE(ldap, LDAP caching and connection pooling services, $ldap_objects, , no, [
|
||||
AP_FIND_LDAP
|
||||
if test -z "$apu_config" ; then
|
||||
APR_ADDTO(MOD_LDAP_LDADD, [$LDADD_ldap])
|
||||
MOD_LDAP_LDADD="`$apr_config --ldap-libs`"
|
||||
else
|
||||
APR_ADDTO(MOD_LDAP_LDADD, [$LDADD_ldap])
|
||||
MOD_LDAP_LDADD="`$apu_config --ldap-libs`"
|
||||
fi
|
||||
AC_SUBST(MOD_LDAP_LDADD)
|
||||
])
|
||||
|
@ -38,8 +38,17 @@
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#if !AP_HAS_LDAP
|
||||
#error mod_ldap requires httpd to detect LDAP support
|
||||
#if !APR_HAS_LDAP
|
||||
#error mod_ldap requires APR-util to have LDAP support built in
|
||||
#endif
|
||||
|
||||
/* Default define for ldap functions that need a SIZELIMIT but
|
||||
* do not have the define
|
||||
* XXX This should be removed once a supporting #define is
|
||||
* released through APR-Util.
|
||||
*/
|
||||
#ifndef APR_LDAP_SIZELIMIT
|
||||
#define APR_LDAP_SIZELIMIT -1
|
||||
#endif
|
||||
|
||||
#ifdef LDAP_OPT_DEBUG_LEVEL
|
||||
@ -172,7 +181,7 @@ static apr_status_t uldap_connection_unbind(void *param)
|
||||
|
||||
/* forget the rebind info for this conn */
|
||||
if (ldc->ChaseReferrals == AP_LDAP_CHASEREFERRALS_ON) {
|
||||
ap_ldap_rebind_remove(ldc->ldap);
|
||||
apr_ldap_rebind_remove(ldc->ldap);
|
||||
apr_pool_clear(ldc->rebind_pool);
|
||||
}
|
||||
}
|
||||
@ -242,7 +251,7 @@ static int uldap_connection_init(request_rec *r,
|
||||
{
|
||||
int rc = 0, ldap_option = 0;
|
||||
int version = LDAP_VERSION3;
|
||||
ap_ldap_err_t *result = NULL;
|
||||
apr_ldap_err_t *result = NULL;
|
||||
#ifdef LDAP_OPT_NETWORK_TIMEOUT
|
||||
struct timeval connectionTimeout = {10,0}; /* 10 second connection timeout */
|
||||
#endif
|
||||
@ -256,10 +265,10 @@ static int uldap_connection_init(request_rec *r,
|
||||
* some hosts with ports and some without. All hosts which do not
|
||||
* specify a port will use the default port.
|
||||
*/
|
||||
ap_ldap_init(r->pool, &(ldc->ldap),
|
||||
apr_ldap_init(r->pool, &(ldc->ldap),
|
||||
ldc->host,
|
||||
AP_LDAP_SSL == ldc->secure ? LDAPS_PORT : LDAP_PORT,
|
||||
AP_LDAP_NONE,
|
||||
APR_LDAP_SSL == ldc->secure ? LDAPS_PORT : LDAP_PORT,
|
||||
APR_LDAP_NONE,
|
||||
&(result));
|
||||
|
||||
if (NULL == result) {
|
||||
@ -291,7 +300,7 @@ static int uldap_connection_init(request_rec *r,
|
||||
|
||||
if (ldc->ChaseReferrals == AP_LDAP_CHASEREFERRALS_ON) {
|
||||
/* Now that we have an ldap struct, add it to the referral list for rebinds. */
|
||||
rc = ap_ldap_rebind_add(ldc->rebind_pool, ldc->ldap, ldc->binddn, ldc->bindpw);
|
||||
rc = apr_ldap_rebind_add(ldc->rebind_pool, ldc->ldap, ldc->binddn, ldc->bindpw);
|
||||
if (rc != APR_SUCCESS) {
|
||||
ap_log_error(APLOG_MARK, APLOG_ERR, rc, r->server,
|
||||
"LDAP: Unable to add rebind cross reference entry. Out of memory?");
|
||||
@ -306,7 +315,7 @@ static int uldap_connection_init(request_rec *r,
|
||||
|
||||
/* set client certificates */
|
||||
if (!apr_is_empty_array(ldc->client_certs)) {
|
||||
ap_ldap_set_option(r->pool, ldc->ldap, AP_LDAP_OPT_TLS_CERT,
|
||||
apr_ldap_set_option(r->pool, ldc->ldap, APR_LDAP_OPT_TLS_CERT,
|
||||
ldc->client_certs, &(result));
|
||||
if (LDAP_SUCCESS != result->rc) {
|
||||
uldap_connection_unbind( ldc );
|
||||
@ -316,9 +325,9 @@ static int uldap_connection_init(request_rec *r,
|
||||
}
|
||||
|
||||
/* switch on SSL/TLS */
|
||||
if (AP_LDAP_NONE != ldc->secure) {
|
||||
ap_ldap_set_option(r->pool, ldc->ldap,
|
||||
AP_LDAP_OPT_TLS, &ldc->secure, &(result));
|
||||
if (APR_LDAP_NONE != ldc->secure) {
|
||||
apr_ldap_set_option(r->pool, ldc->ldap,
|
||||
APR_LDAP_OPT_TLS, &ldc->secure, &(result));
|
||||
if (LDAP_SUCCESS != result->rc) {
|
||||
uldap_connection_unbind( ldc );
|
||||
ldc->reason = result->reason;
|
||||
@ -335,8 +344,8 @@ static int uldap_connection_init(request_rec *r,
|
||||
ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,
|
||||
"LDAP: Setting referrals to %s.",
|
||||
((ldc->ChaseReferrals == AP_LDAP_CHASEREFERRALS_ON) ? "On" : "Off"));
|
||||
ap_ldap_set_option(r->pool, ldc->ldap,
|
||||
AP_LDAP_OPT_REFERRALS,
|
||||
apr_ldap_set_option(r->pool, ldc->ldap,
|
||||
APR_LDAP_OPT_REFERRALS,
|
||||
(void *)((ldc->ChaseReferrals == AP_LDAP_CHASEREFERRALS_ON) ?
|
||||
LDAP_OPT_ON : LDAP_OPT_OFF),
|
||||
&(result));
|
||||
@ -356,8 +365,8 @@ static int uldap_connection_init(request_rec *r,
|
||||
ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,
|
||||
"Setting referral hop limit to %d.",
|
||||
ldc->ReferralHopLimit);
|
||||
ap_ldap_set_option(r->pool, ldc->ldap,
|
||||
AP_LDAP_OPT_REFHOPLIMIT,
|
||||
apr_ldap_set_option(r->pool, ldc->ldap,
|
||||
APR_LDAP_OPT_REFHOPLIMIT,
|
||||
(void *)&ldc->ReferralHopLimit,
|
||||
&(result));
|
||||
if (result->rc != LDAP_SUCCESS) {
|
||||
@ -373,8 +382,31 @@ static int uldap_connection_init(request_rec *r,
|
||||
}
|
||||
}
|
||||
|
||||
ap_ldap_set_option(r->pool, ldc->ldap, AP_LDAP_OPT_VERIFY_CERT,
|
||||
/*XXX All of the #ifdef's need to be removed once apr-util 1.2 is released */
|
||||
#ifdef APR_LDAP_OPT_VERIFY_CERT
|
||||
apr_ldap_set_option(r->pool, ldc->ldap, APR_LDAP_OPT_VERIFY_CERT,
|
||||
&(st->verify_svr_cert), &(result));
|
||||
#else
|
||||
#if defined(LDAPSSL_VERIFY_SERVER)
|
||||
if (st->verify_svr_cert) {
|
||||
result->rc = ldapssl_set_verify_mode(LDAPSSL_VERIFY_SERVER);
|
||||
}
|
||||
else {
|
||||
result->rc = ldapssl_set_verify_mode(LDAPSSL_VERIFY_NONE);
|
||||
}
|
||||
#elif defined(LDAP_OPT_X_TLS_REQUIRE_CERT)
|
||||
/* This is not a per-connection setting so just pass NULL for the
|
||||
Ldap connection handle */
|
||||
if (st->verify_svr_cert) {
|
||||
int i = LDAP_OPT_X_TLS_DEMAND;
|
||||
result->rc = ldap_set_option(NULL, LDAP_OPT_X_TLS_REQUIRE_CERT, &i);
|
||||
}
|
||||
else {
|
||||
int i = LDAP_OPT_X_TLS_NEVER;
|
||||
result->rc = ldap_set_option(NULL, LDAP_OPT_X_TLS_REQUIRE_CERT, &i);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef LDAP_OPT_NETWORK_TIMEOUT
|
||||
if (st->connectionTimeout > 0) {
|
||||
@ -382,7 +414,7 @@ static int uldap_connection_init(request_rec *r,
|
||||
}
|
||||
|
||||
if (st->connectionTimeout >= 0) {
|
||||
rc = ap_ldap_set_option(r->pool, ldc->ldap, LDAP_OPT_NETWORK_TIMEOUT,
|
||||
rc = apr_ldap_set_option(r->pool, ldc->ldap, LDAP_OPT_NETWORK_TIMEOUT,
|
||||
(void *)&connectionTimeout, &(result));
|
||||
if (APR_SUCCESS != rc) {
|
||||
ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server,
|
||||
@ -401,7 +433,7 @@ static int uldap_connection_init(request_rec *r,
|
||||
* XXX: ldap_result() with a timeout.
|
||||
*/
|
||||
if (st->opTimeout) {
|
||||
rc = ap_ldap_set_option(r->pool, ldc->ldap, LDAP_OPT_TIMEOUT,
|
||||
rc = apr_ldap_set_option(r->pool, ldc->ldap, LDAP_OPT_TIMEOUT,
|
||||
st->opTimeout, &(result));
|
||||
if (APR_SUCCESS != rc) {
|
||||
ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server,
|
||||
@ -556,7 +588,7 @@ static int compare_client_certs(apr_array_header_t *srcs,
|
||||
apr_array_header_t *dests)
|
||||
{
|
||||
int i = 0;
|
||||
struct ap_ldap_opt_tls_cert_t *src, *dest;
|
||||
struct apr_ldap_opt_tls_cert_t *src, *dest;
|
||||
|
||||
/* arrays both NULL? if so, then equal */
|
||||
if (srcs == NULL && dests == NULL) {
|
||||
@ -569,8 +601,8 @@ static int compare_client_certs(apr_array_header_t *srcs,
|
||||
}
|
||||
|
||||
/* run an actual comparison */
|
||||
src = (struct ap_ldap_opt_tls_cert_t *)srcs->elts;
|
||||
dest = (struct ap_ldap_opt_tls_cert_t *)dests->elts;
|
||||
src = (struct apr_ldap_opt_tls_cert_t *)srcs->elts;
|
||||
dest = (struct apr_ldap_opt_tls_cert_t *)dests->elts;
|
||||
for (i = 0; i < srcs->nelts; i++) {
|
||||
if ((strcmp(src[i].path, dest[i].path)) ||
|
||||
(src[i].type != dest[i].type) ||
|
||||
@ -617,7 +649,7 @@ static util_ldap_connection_t *
|
||||
apr_thread_mutex_lock(st->mutex);
|
||||
#endif
|
||||
|
||||
if (secure < AP_LDAP_NONE) {
|
||||
if (secure < APR_LDAP_NONE) {
|
||||
secureflag = st->secure;
|
||||
}
|
||||
|
||||
@ -731,7 +763,7 @@ static util_ldap_connection_t *
|
||||
l->ReferralHopLimit = dc->ReferralHopLimit;
|
||||
|
||||
/* The security mode after parsing the URL will always be either
|
||||
* AP_LDAP_NONE (ldap://) or AP_LDAP_SSL (ldaps://).
|
||||
* 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
|
||||
*/
|
||||
@ -853,7 +885,7 @@ start_over:
|
||||
/* search for reqdn */
|
||||
result = ldap_search_ext_s(ldc->ldap, (char *)reqdn, LDAP_SCOPE_BASE,
|
||||
"(objectclass=*)", NULL, 1,
|
||||
NULL, NULL, st->opTimeout, AP_LDAP_SIZELIMIT, &res);
|
||||
NULL, NULL, st->opTimeout, APR_LDAP_SIZELIMIT, &res);
|
||||
if (AP_LDAP_IS_SERVER_DOWN(result))
|
||||
{
|
||||
ldc->reason = "DN Comparison ldap_search_ext_s() "
|
||||
@ -1112,7 +1144,7 @@ start_over:
|
||||
/* try to do the search */
|
||||
result = ldap_search_ext_s(ldc->ldap, (char *)dn, LDAP_SCOPE_BASE,
|
||||
(char *)"cn=*", subgroupAttrs, 0,
|
||||
NULL, NULL, NULL, AP_LDAP_SIZELIMIT, &sga_res);
|
||||
NULL, NULL, NULL, APR_LDAP_SIZELIMIT, &sga_res);
|
||||
if (AP_LDAP_IS_SERVER_DOWN(result)) {
|
||||
ldc->reason = "ldap_search_ext_s() for subgroups failed with server"
|
||||
" down";
|
||||
@ -1583,7 +1615,7 @@ start_over:
|
||||
result = ldap_search_ext_s(ldc->ldap,
|
||||
(char *)basedn, scope,
|
||||
(char *)filter, attrs, 0,
|
||||
NULL, NULL, st->opTimeout, AP_LDAP_SIZELIMIT, &res);
|
||||
NULL, NULL, st->opTimeout, APR_LDAP_SIZELIMIT, &res);
|
||||
if (AP_LDAP_IS_SERVER_DOWN(result))
|
||||
{
|
||||
ldc->reason = "ldap_search_ext_s() for user failed with server down";
|
||||
@ -1834,7 +1866,7 @@ start_over:
|
||||
result = ldap_search_ext_s(ldc->ldap,
|
||||
(char *)basedn, scope,
|
||||
(char *)filter, attrs, 0,
|
||||
NULL, NULL, st->opTimeout, AP_LDAP_SIZELIMIT, &res);
|
||||
NULL, NULL, st->opTimeout, APR_LDAP_SIZELIMIT, &res);
|
||||
if (AP_LDAP_IS_SERVER_DOWN(result))
|
||||
{
|
||||
ldc->reason = "ldap_search_ext_s() for user failed with server down";
|
||||
@ -2104,72 +2136,72 @@ static const char *util_ldap_set_opcache_entries(cmd_parms *cmd, void *dummy,
|
||||
* 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, AP_LDAP_CA_TYPE_UNKNOWN is returned.
|
||||
* If no matches are found, APR_LDAP_CA_TYPE_UNKNOWN is returned.
|
||||
*/
|
||||
static int util_ldap_parse_cert_type(const char *type)
|
||||
{
|
||||
/* Authority file in binary DER format */
|
||||
if (0 == strcasecmp("CA_DER", type)) {
|
||||
return AP_LDAP_CA_TYPE_DER;
|
||||
return APR_LDAP_CA_TYPE_DER;
|
||||
}
|
||||
|
||||
/* Authority file in Base64 format */
|
||||
else if (0 == strcasecmp("CA_BASE64", type)) {
|
||||
return AP_LDAP_CA_TYPE_BASE64;
|
||||
return APR_LDAP_CA_TYPE_BASE64;
|
||||
}
|
||||
|
||||
/* Netscape certificate database file/directory */
|
||||
else if (0 == strcasecmp("CA_CERT7_DB", type)) {
|
||||
return AP_LDAP_CA_TYPE_CERT7_DB;
|
||||
return APR_LDAP_CA_TYPE_CERT7_DB;
|
||||
}
|
||||
|
||||
/* Netscape secmod file/directory */
|
||||
else if (0 == strcasecmp("CA_SECMOD", type)) {
|
||||
return AP_LDAP_CA_TYPE_SECMOD;
|
||||
return APR_LDAP_CA_TYPE_SECMOD;
|
||||
}
|
||||
|
||||
/* Client cert file in DER format */
|
||||
else if (0 == strcasecmp("CERT_DER", type)) {
|
||||
return AP_LDAP_CERT_TYPE_DER;
|
||||
return APR_LDAP_CERT_TYPE_DER;
|
||||
}
|
||||
|
||||
/* Client cert file in Base64 format */
|
||||
else if (0 == strcasecmp("CERT_BASE64", type)) {
|
||||
return AP_LDAP_CERT_TYPE_BASE64;
|
||||
return APR_LDAP_CERT_TYPE_BASE64;
|
||||
}
|
||||
|
||||
/* Client cert file in PKCS#12 format */
|
||||
else if (0 == strcasecmp("CERT_PFX", type)) {
|
||||
return AP_LDAP_CERT_TYPE_PFX;
|
||||
return APR_LDAP_CERT_TYPE_PFX;
|
||||
}
|
||||
|
||||
/* Netscape client cert database file/directory */
|
||||
else if (0 == strcasecmp("CERT_KEY3_DB", type)) {
|
||||
return AP_LDAP_CERT_TYPE_KEY3_DB;
|
||||
return APR_LDAP_CERT_TYPE_KEY3_DB;
|
||||
}
|
||||
|
||||
/* Netscape client cert nickname */
|
||||
else if (0 == strcasecmp("CERT_NICKNAME", type)) {
|
||||
return AP_LDAP_CERT_TYPE_NICKNAME;
|
||||
return APR_LDAP_CERT_TYPE_NICKNAME;
|
||||
}
|
||||
|
||||
/* Client cert key file in DER format */
|
||||
else if (0 == strcasecmp("KEY_DER", type)) {
|
||||
return AP_LDAP_KEY_TYPE_DER;
|
||||
return APR_LDAP_KEY_TYPE_DER;
|
||||
}
|
||||
|
||||
/* Client cert key file in Base64 format */
|
||||
else if (0 == strcasecmp("KEY_BASE64", type)) {
|
||||
return AP_LDAP_KEY_TYPE_BASE64;
|
||||
return APR_LDAP_KEY_TYPE_BASE64;
|
||||
}
|
||||
|
||||
/* Client cert key file in PKCS#12 format */
|
||||
else if (0 == strcasecmp("KEY_PFX", type)) {
|
||||
return AP_LDAP_KEY_TYPE_PFX;
|
||||
return APR_LDAP_KEY_TYPE_PFX;
|
||||
}
|
||||
|
||||
else {
|
||||
return AP_LDAP_CA_TYPE_UNKNOWN;
|
||||
return APR_LDAP_CA_TYPE_UNKNOWN;
|
||||
}
|
||||
|
||||
}
|
||||
@ -2198,7 +2230,7 @@ static const char *util_ldap_set_trusted_global_cert(cmd_parms *cmd,
|
||||
apr_finfo_t finfo;
|
||||
apr_status_t rv;
|
||||
int cert_type = 0;
|
||||
ap_ldap_opt_tls_cert_t *cert;
|
||||
apr_ldap_opt_tls_cert_t *cert;
|
||||
|
||||
if (err != NULL) {
|
||||
return err;
|
||||
@ -2207,7 +2239,7 @@ static const char *util_ldap_set_trusted_global_cert(cmd_parms *cmd,
|
||||
/* handle the certificate type */
|
||||
if (type) {
|
||||
cert_type = util_ldap_parse_cert_type(type);
|
||||
if (AP_LDAP_CA_TYPE_UNKNOWN == cert_type) {
|
||||
if (APR_LDAP_CA_TYPE_UNKNOWN == cert_type) {
|
||||
return apr_psprintf(cmd->pool, "The certificate type %s is "
|
||||
"not recognised. It should be one "
|
||||
"of CA_DER, CA_BASE64, CA_CERT7_DB, "
|
||||
@ -2225,14 +2257,14 @@ static const char *util_ldap_set_trusted_global_cert(cmd_parms *cmd,
|
||||
file, type);
|
||||
|
||||
/* add the certificate to the global array */
|
||||
cert = (ap_ldap_opt_tls_cert_t *)apr_array_push(st->global_certs);
|
||||
cert = (apr_ldap_opt_tls_cert_t *)apr_array_push(st->global_certs);
|
||||
cert->type = cert_type;
|
||||
cert->path = file;
|
||||
cert->password = password;
|
||||
|
||||
/* if file is a file or path, fix the path */
|
||||
if (cert_type != AP_LDAP_CA_TYPE_UNKNOWN &&
|
||||
cert_type != AP_LDAP_CERT_TYPE_NICKNAME) {
|
||||
if (cert_type != APR_LDAP_CA_TYPE_UNKNOWN &&
|
||||
cert_type != APR_LDAP_CERT_TYPE_NICKNAME) {
|
||||
|
||||
cert->path = ap_server_root_relative(cmd->pool, file);
|
||||
if (cert->path &&
|
||||
@ -2269,12 +2301,12 @@ static const char *util_ldap_set_trusted_client_cert(cmd_parms *cmd,
|
||||
apr_finfo_t finfo;
|
||||
apr_status_t rv;
|
||||
int cert_type = 0;
|
||||
ap_ldap_opt_tls_cert_t *cert;
|
||||
apr_ldap_opt_tls_cert_t *cert;
|
||||
|
||||
/* handle the certificate type */
|
||||
if (type) {
|
||||
cert_type = util_ldap_parse_cert_type(type);
|
||||
if (AP_LDAP_CA_TYPE_UNKNOWN == cert_type) {
|
||||
if (APR_LDAP_CA_TYPE_UNKNOWN == cert_type) {
|
||||
return apr_psprintf(cmd->pool, "The certificate type \"%s\" is "
|
||||
"not recognised. It should be one "
|
||||
"of CA_DER, CA_BASE64, "
|
||||
@ -2283,10 +2315,10 @@ static const char *util_ldap_set_trusted_client_cert(cmd_parms *cmd,
|
||||
"KEY_DER, KEY_BASE64, KEY_PFX",
|
||||
type);
|
||||
}
|
||||
else if ( AP_LDAP_CA_TYPE_CERT7_DB == cert_type ||
|
||||
AP_LDAP_CA_TYPE_SECMOD == cert_type ||
|
||||
AP_LDAP_CERT_TYPE_PFX == cert_type ||
|
||||
AP_LDAP_CERT_TYPE_KEY3_DB == cert_type) {
|
||||
else if ( APR_LDAP_CA_TYPE_CERT7_DB == cert_type ||
|
||||
APR_LDAP_CA_TYPE_SECMOD == cert_type ||
|
||||
APR_LDAP_CERT_TYPE_PFX == cert_type ||
|
||||
APR_LDAP_CERT_TYPE_KEY3_DB == cert_type) {
|
||||
return apr_psprintf(cmd->pool, "The certificate type \"%s\" is "
|
||||
"only valid within a "
|
||||
"LDAPTrustedGlobalCert directive. "
|
||||
@ -2305,14 +2337,14 @@ static const char *util_ldap_set_trusted_client_cert(cmd_parms *cmd,
|
||||
file, type);
|
||||
|
||||
/* add the certificate to the client array */
|
||||
cert = (ap_ldap_opt_tls_cert_t *)apr_array_push(dc->client_certs);
|
||||
cert = (apr_ldap_opt_tls_cert_t *)apr_array_push(dc->client_certs);
|
||||
cert->type = cert_type;
|
||||
cert->path = file;
|
||||
cert->password = password;
|
||||
|
||||
/* if file is a file or path, fix the path */
|
||||
if (cert_type != AP_LDAP_CA_TYPE_UNKNOWN &&
|
||||
cert_type != AP_LDAP_CERT_TYPE_NICKNAME) {
|
||||
if (cert_type != APR_LDAP_CA_TYPE_UNKNOWN &&
|
||||
cert_type != APR_LDAP_CERT_TYPE_NICKNAME) {
|
||||
|
||||
cert->path = ap_server_root_relative(cmd->pool, file);
|
||||
if (cert->path &&
|
||||
@ -2352,14 +2384,14 @@ static const char *util_ldap_set_trusted_mode(cmd_parms *cmd, void *dummy,
|
||||
mode);
|
||||
|
||||
if (0 == strcasecmp("NONE", mode)) {
|
||||
st->secure = AP_LDAP_NONE;
|
||||
st->secure = APR_LDAP_NONE;
|
||||
}
|
||||
else if (0 == strcasecmp("SSL", mode)) {
|
||||
st->secure = AP_LDAP_SSL;
|
||||
st->secure = APR_LDAP_SSL;
|
||||
}
|
||||
else if ( (0 == strcasecmp("TLS", mode))
|
||||
|| (0 == strcasecmp("STARTTLS", mode))) {
|
||||
st->secure = AP_LDAP_STARTTLS;
|
||||
st->secure = APR_LDAP_STARTTLS;
|
||||
}
|
||||
else {
|
||||
return "Invalid LDAPTrustedMode setting: must be one of NONE, "
|
||||
@ -2485,7 +2517,7 @@ static void *util_ldap_create_dir_config(apr_pool_t *p, char *d) {
|
||||
(util_ldap_config_t *) apr_pcalloc(p,sizeof(util_ldap_config_t));
|
||||
|
||||
/* defaults are AP_LDAP_CHASEREFERRALS_ON and AP_LDAP_DEFAULT_HOPLIMIT */
|
||||
dc->client_certs = apr_array_make(p, 10, sizeof(ap_ldap_opt_tls_cert_t));
|
||||
dc->client_certs = apr_array_make(p, 10, sizeof(apr_ldap_opt_tls_cert_t));
|
||||
dc->ChaseReferrals = AP_LDAP_CHASEREFERRALS_ON;
|
||||
dc->ReferralHopLimit = AP_LDAP_HOPLIMIT_UNSET;
|
||||
|
||||
@ -2584,8 +2616,8 @@ static void *util_ldap_create_config(apr_pool_t *p, server_rec *s)
|
||||
st->compare_cache_size = 1024;
|
||||
st->connections = NULL;
|
||||
st->ssl_supported = 0;
|
||||
st->global_certs = apr_array_make(p, 10, sizeof(ap_ldap_opt_tls_cert_t));
|
||||
st->secure = AP_LDAP_NONE;
|
||||
st->global_certs = apr_array_make(p, 10, sizeof(apr_ldap_opt_tls_cert_t));
|
||||
st->secure = APR_LDAP_NONE;
|
||||
st->secure_set = 0;
|
||||
st->connectionTimeout = 10;
|
||||
st->opTimeout = apr_pcalloc(p, sizeof(struct timeval));
|
||||
@ -2657,7 +2689,7 @@ static apr_status_t util_ldap_cleanup_module(void *data)
|
||||
s->module_config, &ldap_module);
|
||||
|
||||
if (st->ssl_supported) {
|
||||
ap_ldap_ssl_deinit();
|
||||
apr_ldap_ssl_deinit();
|
||||
}
|
||||
|
||||
return APR_SUCCESS;
|
||||
@ -2689,7 +2721,7 @@ static int util_ldap_post_config(apr_pool_t *p, apr_pool_t *plog,
|
||||
ap_get_module_config(s->module_config,
|
||||
&ldap_module);
|
||||
|
||||
ap_ldap_err_t *result_err = NULL;
|
||||
apr_ldap_err_t *result_err = NULL;
|
||||
int rc;
|
||||
|
||||
/* util_ldap_post_config() will be called twice. Don't bother
|
||||
@ -2762,8 +2794,8 @@ static int util_ldap_post_config(apr_pool_t *p, apr_pool_t *plog,
|
||||
/* log the LDAP SDK used
|
||||
*/
|
||||
{
|
||||
ap_ldap_err_t *result = NULL;
|
||||
ap_ldap_info(p, &(result));
|
||||
apr_ldap_err_t *result = NULL;
|
||||
apr_ldap_info(p, &(result));
|
||||
if (result != NULL) {
|
||||
ap_log_error(APLOG_MARK, APLOG_INFO, 0, s, "%s", result->reason);
|
||||
}
|
||||
@ -2778,12 +2810,12 @@ static int util_ldap_post_config(apr_pool_t *p, apr_pool_t *plog,
|
||||
* If SSL is not supported it is not necessarily an error, as the
|
||||
* application may not want to use it.
|
||||
*/
|
||||
rc = ap_ldap_ssl_init(p,
|
||||
rc = apr_ldap_ssl_init(p,
|
||||
NULL,
|
||||
0,
|
||||
&(result_err));
|
||||
if (APR_SUCCESS == rc) {
|
||||
rc = ap_ldap_set_option(ptemp, NULL, AP_LDAP_OPT_TLS_CERT,
|
||||
rc = apr_ldap_set_option(ptemp, NULL, APR_LDAP_OPT_TLS_CERT,
|
||||
(void *)st->global_certs, &(result_err));
|
||||
}
|
||||
|
||||
@ -2801,7 +2833,7 @@ static int util_ldap_post_config(apr_pool_t *p, apr_pool_t *plog,
|
||||
}
|
||||
|
||||
/* Initialize the rebind callback's cross reference list. */
|
||||
ap_ldap_rebind_init (p);
|
||||
apr_ldap_rebind_init (p);
|
||||
|
||||
#ifdef AP_LDAP_OPT_DEBUG
|
||||
if (st->debug_level > 0) {
|
||||
|
@ -27,7 +27,7 @@
|
||||
#include "util_ldap_cache.h"
|
||||
#include <apr_strings.h>
|
||||
|
||||
#if AP_HAS_LDAP
|
||||
#if APR_HAS_LDAP
|
||||
|
||||
/* ------------------------------------------------------------------ */
|
||||
|
||||
@ -461,4 +461,4 @@ apr_status_t util_ldap_cache_init(apr_pool_t *pool, util_ldap_state_t *st)
|
||||
}
|
||||
|
||||
|
||||
#endif /* AP_HAS_LDAP */
|
||||
#endif /* APR_HAS_LDAP */
|
||||
|
@ -14,8 +14,8 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef AP_LDAP_CACHE_H
|
||||
#define AP_LDAP_CACHE_H
|
||||
#ifndef APU_LDAP_CACHE_H
|
||||
#define APU_LDAP_CACHE_H
|
||||
|
||||
/**
|
||||
* @file util_ldap_cache.h
|
||||
@ -23,7 +23,7 @@
|
||||
*/
|
||||
|
||||
/* this whole thing disappears if LDAP is not enabled */
|
||||
#if AP_HAS_LDAP
|
||||
#if APR_HAS_LDAP
|
||||
|
||||
|
||||
/*
|
||||
@ -200,5 +200,5 @@ void *util_ald_cache_insert(util_ald_cache_t *cache, void *payload);
|
||||
void util_ald_cache_remove(util_ald_cache_t *cache, void *payload);
|
||||
char *util_ald_cache_display_stats(request_rec *r, util_ald_cache_t *cache, char *name, char *id);
|
||||
|
||||
#endif /* AP_HAS_LDAP */
|
||||
#endif /* AP_LDAP_CACHE_H */
|
||||
#endif /* APR_HAS_LDAP */
|
||||
#endif /* APU_LDAP_CACHE_H */
|
||||
|
@ -29,7 +29,7 @@
|
||||
|
||||
APLOG_USE_MODULE(ldap);
|
||||
|
||||
#if AP_HAS_LDAP
|
||||
#if APR_HAS_LDAP
|
||||
|
||||
/* only here until strdup is gone */
|
||||
#include <string.h>
|
||||
@ -877,4 +877,4 @@ char *util_ald_cache_display(request_rec *r, util_ldap_state_t *st)
|
||||
return buf;
|
||||
}
|
||||
|
||||
#endif /* AP_HAS_LDAP */
|
||||
#endif /* APR_HAS_LDAP */
|
||||
|
Reference in New Issue
Block a user