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

📄 util_ldap.c

📁 Apache HTTP Server 是一个功能强大的灵活的与HTTP/1.1相兼容的web服务器.这里给出的是Apache HTTP服务器的源码。
💻 C
📖 第 1 页 / 共 4 页
字号:
/* 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 <apr_ldap.h>#include <apr_strings.h>#include "ap_config.h"#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"#if APR_HAVE_UNISTD_H#include <unistd.h>#endif#ifndef APU_HAS_LDAP#error mod_ldap requires APR-util to have LDAP support built in#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;int util_ldap_handler(request_rec *r);void *util_ldap_create_config(apr_pool_t *p, server_rec *s);/* * Some definitions to help between various versions of apache. */#ifndef DOCTYPE_HTML_2_0#define DOCTYPE_HTML_2_0  "<!DOCTYPE HTML PUBLIC \"-//IETF//" \                          "DTD HTML 2.0//EN\">\n"#endif#ifndef DOCTYPE_HTML_3_2#define DOCTYPE_HTML_3_2  "<!DOCTYPE HTML PUBLIC \"-//W3C//" \                          "DTD HTML 3.2 Final//EN\">\n"#endif#ifndef DOCTYPE_HTML_4_0S#define DOCTYPE_HTML_4_0S "<!DOCTYPE HTML PUBLIC \"-//W3C//" \                          "DTD HTML 4.0//EN\"\n" \                          "\"http://www.w3.org/TR/REC-html40/strict.dtd\">\n"#endif#ifndef DOCTYPE_HTML_4_0T#define DOCTYPE_HTML_4_0T "<!DOCTYPE HTML PUBLIC \"-//W3C//" \                          "DTD HTML 4.0 Transitional//EN\"\n" \                          "\"http://www.w3.org/TR/REC-html40/loose.dtd\">\n"#endif#ifndef DOCTYPE_HTML_4_0F#define DOCTYPE_HTML_4_0F "<!DOCTYPE HTML PUBLIC \"-//W3C//" \                          "DTD HTML 4.0 Frameset//EN\"\n" \                          "\"http://www.w3.org/TR/REC-html40/frameset.dtd\">\n"#endif#define LDAP_CACHE_LOCK() \    if (st->util_ldap_cache_lock) \      apr_global_mutex_lock(st->util_ldap_cache_lock)#define LDAP_CACHE_UNLOCK() \    if (st->util_ldap_cache_lock) \      apr_global_mutex_unlock(st->util_ldap_cache_lock)static void util_ldap_strdup (char **str, const char *newstr){    if (*str) {        free(*str);        *str = NULL;    }    if (newstr) {        *str = calloc(1, strlen(newstr)+1);        strcpy (*str, newstr);    }}/* * Status Handler * -------------- * * This handler generates a status page about the current performance of * the LDAP cache. It is enabled as follows: * * <Location /ldap-status> *   SetHandler ldap-status * </Location> * */int util_ldap_handler(request_rec *r){    util_ldap_state_t *st = (util_ldap_state_t *)ap_get_module_config(r->server->module_config, &ldap_module);    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 * util_ldap_connection_find() is called this connection will be * available for reuse. */LDAP_DECLARE(void) util_ldap_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. */LDAP_DECLARE_NONSTD(apr_status_t) util_ldap_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. */LDAP_DECLARE_NONSTD(apr_status_t) util_ldap_connection_cleanup(void *param){    util_ldap_connection_t *ldc = param;    if (ldc) {        /* unbind and disconnect from the LDAP server */        util_ldap_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 */        util_ldap_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 */LDAP_DECLARE(int) util_ldap_connection_open(request_rec *r,                                             util_ldap_connection_t *ldc){    int result = 0;    int failures = 0;    int version  = LDAP_VERSION3;    util_ldap_state_t *st = (util_ldap_state_t *)ap_get_module_config(                                r->server->module_config, &ldap_module);    /* 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)    {            /* clear connection requested */        if (!ldc->secure)        {            ldc->ldap = ldap_init(const_cast(ldc->host), ldc->port);        }        else /* ssl connnection requested */        {                /* check configuration to make sure it supports SSL                */            if (st->ssl_support)            {                #if APR_HAS_LDAP_SSL                                #if APR_HAS_NOVELL_LDAPSDK                 ldc->ldap = ldapssl_init(ldc->host, ldc->port, 1);                #elif APR_HAS_NETSCAPE_LDAPSDK                ldc->ldap = ldapssl_init(ldc->host, ldc->port, 1);                #elif APR_HAS_OPENLDAP_LDAPSDK                ldc->ldap = ldap_init(ldc->host, ldc->port);                if (NULL != ldc->ldap)                {                    int SSLmode = LDAP_OPT_X_TLS_HARD;                    result = ldap_set_option(ldc->ldap, LDAP_OPT_X_TLS, &SSLmode);                    if (LDAP_SUCCESS != result)                    {                        ldap_unbind_s(ldc->ldap);                        ldc->reason = "LDAP: ldap_set_option - LDAP_OPT_X_TLS_HARD failed";                        ldc->ldap = NULL;                    }                }                #elif APR_HAS_MICROSOFT_LDAPSDK                ldc->ldap = ldap_sslinit(const_cast(ldc->host), ldc->port, 1);                #else                    ldc->reason = "LDAP: ssl connections not supported";                #endif /* APR_HAS_NOVELL_LDAPSDK */                            #endif /* APR_HAS_LDAP_SSL */            }            else                ldc->reason = "LDAP: ssl connections not supported";        }        if (NULL == ldc->ldap)        {            ldc->bound = 0;            if (NULL == ldc->reason)                ldc->reason = "LDAP: ldap initialization failed";            return(-1);        }        /* Set the alias dereferencing option */        ldap_set_option(ldc->ldap, LDAP_OPT_DEREF, &(ldc->deref));        /* always default to LDAP V3 */        ldap_set_option(ldc->ldap, LDAP_OPT_PROTOCOL_VERSION, &version);    }    /* 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++)    {        result = ldap_simple_bind_s(ldc->ldap, const_cast(ldc->binddn), const_cast(ldc->bindpw));        if (LDAP_SERVER_DOWN != result)            break;    }    /* free the handle if there was an error    */    if (LDAP_SUCCESS != result)    {        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(result);}/* * Find an existing ldap connection struct that matches the * provided ldap connection parameters. * * If not found in the cache, a new ldc structure will be allocated from st->pool * and returned to the caller. If found in the cache, a pointer to the existing * ldc structure will be returned. */LDAP_DECLARE(util_ldap_connection_t *)util_ldap_connection_find(request_rec *r, const char *host, int port,                                              const char *binddn, const char *bindpw, deref_options deref,                                              int secure ){    struct util_ldap_connection_t *l, *p;	/* To traverse the linked list */    util_ldap_state_t *st =         (util_ldap_state_t *)ap_get_module_config(r->server->module_config,        &ldap_module);#if APR_HAS_THREADS    /* mutex lock this function */    if (!st->mutex) {        apr_thread_mutex_create(&st->mutex, APR_THREAD_MUTEX_DEFAULT, st->pool);    }    apr_thread_mutex_lock(st->mutex);#endif    /* Search for an exact connection match in the list that is not     * being used.     */    for (l=st->connections,p=NULL; l; l=l->next) {#if APR_HAS_THREADS        if (APR_SUCCESS == apr_thread_mutex_trylock(l->lock)) {#endif        if ((l->port == port) && (strcmp(l->host, host) == 0) &&             ((!l->binddn && !binddn) || (l->binddn && binddn && !strcmp(l->binddn, binddn))) &&             ((!l->bindpw && !bindpw) || (l->bindpw && bindpw && !strcmp(l->bindpw, bindpw))) &&             (l->deref == deref) && (l->secure == secure)) {            break;        }#if APR_HAS_THREADS            /* If this connection didn't match the criteria, then we             * need to unlock the mutex so it is available to be reused.             */            apr_thread_mutex_unlock(l->lock);        }#endif        p = l;    }    /* If nothing found, search again, but we don't care about the     * binddn and bindpw this time.     */    if (!l) {        for (l=st->connections,p=NULL; l; l=l->next) {#if APR_HAS_THREADS            if (APR_SUCCESS == apr_thread_mutex_trylock(l->lock)) {#endif            if ((l->port == port) && (strcmp(l->host, host) == 0) &&                 (l->deref == deref) && (l->secure == secure)) {                /* the bind credentials have changed */                l->bound = 0;                util_ldap_strdup((char**)&(l->binddn), binddn);                util_ldap_strdup((char**)&(l->bindpw), bindpw);                break;

⌨️ 快捷键说明

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