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

📄 mod_authnz_ldap.c

📁 Apache官方在今天放出产品系列2.2的最新版本2.2.11的源码包 最流行的HTTP服务器软件之一
💻 C
📖 第 1 页 / 共 4 页
字号:
/* 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. */#include "ap_provider.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 "mod_auth.h"#include "apr_strings.h"#include "apr_xlate.h"#define APR_WANT_STRFUNC#include "apr_want.h"#include "apr_lib.h"#if APR_HAVE_UNISTD_H/* for getpid() */#include <unistd.h>#endif#include <ctype.h>#if !APR_HAS_LDAP#error mod_authnz_ldap requires APR-util to have LDAP support built in. To fix add --with-ldap to ./configure.#endiftypedef struct {    apr_pool_t *pool;               /* Pool that this config is allocated from */#if APR_HAS_THREADS    apr_thread_mutex_t *lock;       /* Lock for this config */#endif    int auth_authoritative;         /* Is this auth method the one and only? *//*    int authz_enabled;              Is ldap authorization enabled in this directory? */    /* These parameters are all derived from the AuthLDAPURL directive */    char *url;                      /* String representation of the URL */    char *host;                     /* Name of the LDAP server (or space separated list) */    int port;                       /* Port of the LDAP server */    char *basedn;                   /* Base DN to do all searches from */    char *attribute;                /* Attribute to search for */    char **attributes;              /* Array of all the attributes to return */    int scope;                      /* Scope of the search */    char *filter;                   /* Filter to further limit the search  */    deref_options deref;            /* how to handle alias dereferening */    char *binddn;                   /* DN to bind to server (can be NULL) */    char *bindpw;                   /* Password to bind to server (can be NULL) */    int user_is_dn;                 /* If true, connection->user is DN instead of userid */    char *remote_user_attribute;    /* If set, connection->user is this attribute instead of userid */    int compare_dn_on_server;       /* If true, will use server to do DN compare */    int have_ldap_url;              /* Set if we have found an LDAP url */    apr_array_header_t *groupattr;  /* List of Group attributes */    int group_attrib_is_dn;         /* If true, the group attribute is the DN, otherwise,                                        it's the exact string passed by the HTTP client */    int secure;                     /* True if SSL connections are requested */} authn_ldap_config_t;typedef struct {    char *dn;                       /* The saved dn from a successful search */    char *user;                     /* The username provided by the client */} authn_ldap_request_t;/* maximum group elements supported */#define GROUPATTR_MAX_ELTS 10struct mod_auth_ldap_groupattr_entry_t {    char *name;};module AP_MODULE_DECLARE_DATA authnz_ldap_module;static APR_OPTIONAL_FN_TYPE(uldap_connection_close) *util_ldap_connection_close;static APR_OPTIONAL_FN_TYPE(uldap_connection_find) *util_ldap_connection_find;static APR_OPTIONAL_FN_TYPE(uldap_cache_comparedn) *util_ldap_cache_comparedn;static APR_OPTIONAL_FN_TYPE(uldap_cache_compare) *util_ldap_cache_compare;static APR_OPTIONAL_FN_TYPE(uldap_cache_checkuserid) *util_ldap_cache_checkuserid;static APR_OPTIONAL_FN_TYPE(uldap_cache_getuserdn) *util_ldap_cache_getuserdn;static APR_OPTIONAL_FN_TYPE(uldap_ssl_supported) *util_ldap_ssl_supported;static apr_hash_t *charset_conversions = NULL;static char *to_charset = NULL;           /* UTF-8 identifier derived from the charset.conv file *//* Derive a code page ID give a language name or ID */static char* derive_codepage_from_lang (apr_pool_t *p, char *language){    int lang_len;    char *charset;    if (!language)          /* our default codepage */        return apr_pstrdup(p, "ISO-8859-1");    else        lang_len = strlen(language);    charset = (char*) apr_hash_get(charset_conversions, language, APR_HASH_KEY_STRING);    if (!charset) {        language[2] = '\0';        charset = (char*) apr_hash_get(charset_conversions, language, APR_HASH_KEY_STRING);    }    if (charset) {        charset = apr_pstrdup(p, charset);    }    return charset;}static apr_xlate_t* get_conv_set (request_rec *r){    char *lang_line = (char*)apr_table_get(r->headers_in, "accept-language");    char *lang;    apr_xlate_t *convset;    if (lang_line) {        lang_line = apr_pstrdup(r->pool, lang_line);        for (lang = lang_line;*lang;lang++) {            if ((*lang == ',') || (*lang == ';')) {                *lang = '\0';                break;            }        }        lang = derive_codepage_from_lang(r->pool, lang_line);        if (lang && (apr_xlate_open(&convset, to_charset, lang, r->pool) == APR_SUCCESS)) {            return convset;        }    }    return NULL;}/* * Build the search filter, or at least as much of the search filter that * will fit in the buffer. We don't worry about the buffer not being able * to hold the entire filter. If the buffer wasn't big enough to hold the * filter, ldap_search_s will complain, but the only situation where this * is likely to happen is if the client sent a really, really long * username, most likely as part of an attack. * * The search filter consists of the filter provided with the URL, * combined with a filter made up of the attribute provided with the URL, * and the actual username passed by the HTTP client. For example, assume * that the LDAP URL is * *   ldap://ldap.airius.com/ou=People, o=Airius?uid??(posixid=*) * * Further, assume that the userid passed by the client was `userj'.  The * search filter will be (&(posixid=*)(uid=userj)). */#define FILTER_LENGTH MAX_STRING_LENstatic void authn_ldap_build_filter(char *filtbuf,                             request_rec *r,                             const char* sent_user,                             const char* sent_filter,                             authn_ldap_config_t *sec){    char *p, *q, *filtbuf_end;    char *user, *filter;    apr_xlate_t *convset = NULL;    apr_size_t inbytes;    apr_size_t outbytes;    char *outbuf;    if (sent_user != NULL) {        user = apr_pstrdup (r->pool, sent_user);    }    else        return;    if (sent_filter != NULL) {        filter = apr_pstrdup (r->pool, sent_filter);    }    else        filter = sec->filter;    if (charset_conversions) {        convset = get_conv_set(r);    }    if (convset) {        inbytes = strlen(user);        outbytes = (inbytes+1)*3;        outbuf = apr_pcalloc(r->pool, outbytes);        /* Convert the user name to UTF-8.  This is only valid for LDAP v3 */        if (apr_xlate_conv_buffer(convset, user, &inbytes, outbuf, &outbytes) == APR_SUCCESS) {            user = apr_pstrdup(r->pool, outbuf);        }    }    /*     * Create the first part of the filter, which consists of the     * config-supplied portions.     */    apr_snprintf(filtbuf, FILTER_LENGTH, "(&(%s)(%s=", filter, sec->attribute);    /*     * Now add the client-supplied username to the filter, ensuring that any     * LDAP filter metachars are escaped.     */    filtbuf_end = filtbuf + FILTER_LENGTH - 1;#if APR_HAS_MICROSOFT_LDAPSDK    for (p = user, q=filtbuf + strlen(filtbuf);         *p && q < filtbuf_end; ) {        if (strchr("*()\\", *p) != NULL) {            if ( q + 3 >= filtbuf_end)              break;  /* Don't write part of escape sequence if we can't write all of it */            *q++ = '\\';            switch ( *p++ )            {              case '*':                *q++ = '2';                *q++ = 'a';                break;              case '(':                *q++ = '2';                *q++ = '8';                break;              case ')':                *q++ = '2';                *q++ = '9';                break;              case '\\':                *q++ = '5';                *q++ = 'c';                break;                        }        }        else            *q++ = *p++;    }#else    for (p = user, q=filtbuf + strlen(filtbuf);         *p && q < filtbuf_end; *q++ = *p++) {        if (strchr("*()\\", *p) != NULL) {            *q++ = '\\';            if (q >= filtbuf_end) {              break;            }        }    }#endif    *q = '\0';    /*     * Append the closing parens of the filter, unless doing so would     * overrun the buffer.     */    if (q + 2 <= filtbuf_end)        strcat(filtbuf, "))");}static void *create_authnz_ldap_dir_config(apr_pool_t *p, char *d){    authn_ldap_config_t *sec =        (authn_ldap_config_t *)apr_pcalloc(p, sizeof(authn_ldap_config_t));    sec->pool = p;#if APR_HAS_THREADS    apr_thread_mutex_create(&sec->lock, APR_THREAD_MUTEX_DEFAULT, p);#endif/*    sec->authz_enabled = 1;*/    sec->groupattr = apr_array_make(p, GROUPATTR_MAX_ELTS,                                    sizeof(struct mod_auth_ldap_groupattr_entry_t));    sec->have_ldap_url = 0;    sec->url = "";    sec->host = NULL;    sec->binddn = NULL;    sec->bindpw = NULL;    sec->deref = always;    sec->group_attrib_is_dn = 1;    sec->auth_authoritative = 1;/*    sec->frontpage_hack = 0;*/    sec->secure = -1;   /*Initialize to unset*/    sec->user_is_dn = 0;    sec->remote_user_attribute = NULL;    sec->compare_dn_on_server = 0;

⌨️ 快捷键说明

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