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

📄 mod_auth_ldap.c

📁 Apache HTTP Server 是一个功能强大的灵活的与HTTP/1.1相兼容的web服务器.这里给出的是Apache HTTP服务器的源码。
💻 C
📖 第 1 页 / 共 3 页
字号:
/* 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. *//* * mod_auth_ldap.c: LDAP authentication module *  * 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 <apr_xlate.h>#define APR_WANT_STRFUNC#include <apr_want.h>#include "ap_config.h"#if APR_HAVE_UNISTD_H/* for getpid() */#include <unistd.h>#endif#include <ctype.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"#ifndef APU_HAS_LDAP#error mod_auth_ldap requires APR-util to have LDAP support built in#endif/* per directory configuration */typedef 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 enabled;			/* Is auth_ldap 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 frontpage_hack;			/* Hack for frontpage support */    int user_is_dn;			/* If true, connection->user is DN 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 */} mod_auth_ldap_config_t;typedef struct mod_auth_ldap_request_t {    char *dn;				/* The saved dn from a successful search */    char *user;				/* The username provided by the client */} mod_auth_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 auth_ldap_module;/* function prototypes */void mod_auth_ldap_build_filter(char *filtbuf,                                 request_rec *r,                                 mod_auth_ldap_config_t *sec);int mod_auth_ldap_check_user_id(request_rec *r);int mod_auth_ldap_auth_checker(request_rec *r);void *mod_auth_ldap_create_dir_config(apr_pool_t *p, char *d);/* ---------------------------------------- */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;    int check_short = 0;    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_LENvoid mod_auth_ldap_build_filter(char *filtbuf,                                 request_rec *r,                                 mod_auth_ldap_config_t *sec){    char *p, *q, *filtbuf_end;    char *user;    apr_xlate_t *convset = NULL;    apr_size_t inbytes;    apr_size_t outbytes;    char *outbuf;    if (r->user != NULL) {        user = apr_pstrdup (r->pool, r->user);    }    else        return;    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=", sec->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 apr_status_t mod_auth_ldap_cleanup_connection_close(void *param){    util_ldap_connection_t *ldc = param;    util_ldap_connection_close(ldc);    return APR_SUCCESS;}/* * Authentication Phase * -------------------- * * This phase authenticates the credentials the user has sent with * the request (ie the username and password are checked). This is done * by making an attempt to bind to the LDAP server using this user's * DN and the supplied password. * */int mod_auth_ldap_check_user_id(request_rec *r){    int failures = 0;    const char **vals = NULL;    char filtbuf[FILTER_LENGTH];    mod_auth_ldap_config_t *sec =        (mod_auth_ldap_config_t *)ap_get_module_config(r->per_dir_config, &auth_ldap_module);    util_ldap_connection_t *ldc = NULL;    const char *sent_pw;    int result = 0;    const char *dn = NULL;    mod_auth_ldap_request_t *req =        (mod_auth_ldap_request_t *)apr_pcalloc(r->pool, sizeof(mod_auth_ldap_request_t));    ap_set_module_config(r->request_config, &auth_ldap_module, req);    if (!sec->enabled) {        return DECLINED;    }    /*      * Basic sanity checks before any LDAP operations even happen.     */    if (!sec->have_ldap_url) {        return DECLINED;    }start_over:    /* There is a good AuthLDAPURL, right? */    if (sec->host) {        ldc = util_ldap_connection_find(r, sec->host, sec->port,                                       sec->binddn, sec->bindpw, sec->deref,                                       sec->secure);    }    else {        ap_log_rerror(APLOG_MARK, APLOG_WARNING|APLOG_NOERRNO, 0, r,                       "[%d] auth_ldap authenticate: no sec->host - weird...?", getpid());        return sec->auth_authoritative? HTTP_UNAUTHORIZED : DECLINED;    }    ap_log_rerror(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r,		  "[%d] auth_ldap authenticate: using URL %s", getpid(), sec->url);    /* Get the password that the client sent */    if ((result = ap_get_basic_auth_pw(r, &sent_pw))) {        ap_log_rerror(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r,		      "[%d] auth_ldap authenticate: "		      "ap_get_basic_auth_pw() returns %d", getpid(), result);        util_ldap_connection_close(ldc);        return result;    }    if (r->user == NULL) {        ap_log_rerror(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r,		      "[%d] auth_ldap authenticate: no user specified", getpid());        util_ldap_connection_close(ldc);        return sec->auth_authoritative? HTTP_UNAUTHORIZED : DECLINED;    }    /* build the username filter */    mod_auth_ldap_build_filter(filtbuf, r, sec);    /* do the user search */    result = util_ldap_cache_checkuserid(r, ldc, sec->url, sec->basedn, sec->scope,                                         sec->attributes, filtbuf, sent_pw, &dn, &vals);    util_ldap_connection_close(ldc);    /* sanity check - if server is down, retry it up to 5 times */

⌨️ 快捷键说明

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