⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 util_ldap.c

📁 apache服务器源代码(版本号:2.2.2)
💻 C
📖 第 1 页 / 共 5 页
字号:
/* 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 * *     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. *//* * 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>#if APR_HAVE_UNISTD_H#include <unistd.h>#endif#if !APR_HAS_LDAP#error mod_ldap requires APR-util to have LDAP support built in#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           3module AP_MODULE_DECLARE_DATA ldap_module;#define LDAP_CACHE_LOCK() do {                                  \    if (st->util_ldap_cache_lock)                               \        apr_global_mutex_lock(st->util_ldap_cache_lock);        \} while (0)#define LDAP_CACHE_UNLOCK() do {                                \    if (st->util_ldap_cache_lock)                               \        apr_global_mutex_unlock(st->util_ldap_cache_lock);      \} while (0)static void util_ldap_strdup (char **str, const char *newstr){    if (*str) {        free(*str);        *str = NULL;    }    if (newstr) {        *str = strdup(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> * */static 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);    r->allowed |= (1 << M_GET);    if (r->method_number != M_GET)        return DECLINED;    if (strcmp(r->handler, "ldap-status")) {        return DECLINED;    }    r->content_type = "text/html";    if (r->header_only)        return OK;    ap_rputs(DOCTYPE_HTML_3_2             "<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. */static void uldap_connection_close(util_ldap_connection_t *ldc){    /*     * 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    apr_thread_mutex_unlock(ldc->lock);#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. */static apr_status_t uldap_connection_unbind(void *param){    util_ldap_connection_t *ldc = param;    if (ldc) {        if (ldc->ldap) {            ldap_unbind_s(ldc->ldap);            ldc->ldap = NULL;        }        ldc->bound = 0;    }    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. */static apr_status_t uldap_connection_cleanup(void *param){    util_ldap_connection_t *ldc = param;    if (ldc) {        /* unbind and disconnect from the LDAP server */        uldap_connection_unbind(ldc);        /* free the username and password */        if (ldc->bindpw) {            free((void*)ldc->bindpw);        }        if (ldc->binddn) {            free((void*)ldc->binddn);        }        /* unlock this entry */        uldap_connection_close(ldc);    }    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 */static int uldap_connection_open(request_rec *r,                                 util_ldap_connection_t *ldc){    int rc = 0;    int failures = 0;    int version  = LDAP_VERSION3;    apr_ldap_err_t *result = NULL;    struct timeval timeOut = {10,0};    /* 10 second connection timeout */    util_ldap_state_t *st =        (util_ldap_state_t *)ap_get_module_config(r->server->module_config,        &ldap_module);    /* sanity check for NULL */    if (!ldc) {        return -1;    }    /* If the connection is already bound, return    */    if (ldc->bound)    {        ldc->reason = "LDAP: connection open successful (already bound)";        return LDAP_SUCCESS;    }    /* create the ldap session handle    */    if (NULL == ldc->ldap)    {        /* 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.         */        apr_ldap_init(ldc->pool, &(ldc->ldap),                      ldc->host,                      APR_LDAP_SSL == ldc->secure ? LDAPS_PORT : LDAP_PORT,                      APR_LDAP_NONE,                      &(result));        if (result != NULL && result->rc) {            ldc->reason = result->reason;        }        if (NULL == ldc->ldap)        {            ldc->bound = 0;            if (NULL == ldc->reason) {                ldc->reason = "LDAP: ldap initialization failed";            }            else {                ldc->reason = result->reason;            }            return(result->rc);        }        /* always default to LDAP V3 */        ldap_set_option(ldc->ldap, LDAP_OPT_PROTOCOL_VERSION, &version);        /* set client certificates */        if (!apr_is_empty_array(ldc->client_certs)) {            apr_ldap_set_option(ldc->pool, ldc->ldap, APR_LDAP_OPT_TLS_CERT,                                ldc->client_certs, &(result));            if (LDAP_SUCCESS != result->rc) {                ldap_unbind_s(ldc->ldap);                ldc->ldap = NULL;                ldc->bound = 0;                ldc->reason = result->reason;                return(result->rc);            }        }        /* switch on SSL/TLS */        if (APR_LDAP_NONE != ldc->secure) {            apr_ldap_set_option(ldc->pool, ldc->ldap,                                APR_LDAP_OPT_TLS, &ldc->secure, &(result));            if (LDAP_SUCCESS != result->rc) {                ldap_unbind_s(ldc->ldap);                ldc->ldap = NULL;                ldc->bound = 0;                ldc->reason = result->reason;                return(result->rc);            }        }        /* Set the alias dereferencing option */        ldap_set_option(ldc->ldap, LDAP_OPT_DEREF, &(ldc->deref));/*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(ldc->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) {            timeOut.tv_sec = st->connectionTimeout;        }        if (st->connectionTimeout >= 0) {            rc = apr_ldap_set_option(ldc->pool, ldc->ldap, LDAP_OPT_NETWORK_TIMEOUT,                                     (void *)&timeOut, &(result));            if (APR_SUCCESS != rc) {                ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server,                                 "LDAP: Could not set the connection timeout");            }        }#endif    }    /* 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.      */    for (failures=0; failures<10; failures++)    {        rc = ldap_simple_bind_s(ldc->ldap,                                (char *)ldc->binddn,                                (char *)ldc->bindpw);        if (LDAP_SERVER_DOWN != rc) {            break;        }    }    /* free the handle if there was an error    */    if (LDAP_SUCCESS != rc)    {        ldap_unbind_s(ldc->ldap);        ldc->ldap = NULL;        ldc->bound = 0;        ldc->reason = "LDAP: ldap_simple_bind_s() failed";    }    else {        ldc->bound = 1;        ldc->reason = "LDAP: connection open successful";    }    return(rc);}/* * Compare client certificate arrays. * * Returns 1 on compare failure, 0 otherwise. */static int compare_client_certs(apr_array_header_t *srcs,                                apr_array_header_t *dests){    int i = 0;    struct apr_ldap_opt_tls_cert_t *src, *dest;    /* arrays both NULL? if so, then equal */    if (srcs == NULL && dests == NULL) {        return 0;    }    /* arrays different length or either NULL? If so, then not equal */    if (srcs == NULL || dests == NULL || srcs->nelts != dests->nelts) {        return 1;    }    /* run an actual comparison */    src = (struct apr_ldap_opt_tls_cert_t *)srcs->elts;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -