Commit 922d03e2 authored by Graham Leggett's avatar Graham Leggett
Browse files

Add specified user attributes to the environment when using

mod_auth_ldap. This allows you to use mod_include to embed specified
user attributes in a page like so:
Hello <!--#echo var="AUTHENTICATE_CN"-->, how are you?
PR:
Obtained from:
Submitted by:
Reviewed by:


git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@90775 13f79535-47bb-0310-9956-ffa450edef68
parent 5a4ded79
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
Changes with Apache 2.0.25-dev

  *) Add specified user attributes to the environment when using
     mod_auth_ldap. This allows you to use mod_include to embed specified
     user attributes in a page like so:
     Hello <!--#echo var="AUTHENTICATE_CN"-->, how are you?
     [Graham Leggett]

  *) Fix a performance problem with the worker MPM.  We now create
     transaction pools once, and re-use them for each connection.
     [Aaron Bannert <aaron@clove.org>]
+6 −4
Original line number Diff line number Diff line
@@ -232,19 +232,21 @@ int util_ldap_cache_compare(request_rec *r, util_ldap_connection_t *ldc,
 * @param url The URL of the LDAP connection - used for deciding which cache to use.
 * @param basedn The Base DN to search for the user in.
 * @param scope LDAP scope of the search.
 * @param attrs LDAP attributes to return in search.
 * @param filter The user to search for in the form of an LDAP filter. This filter must return
 *               exactly one user for the check to be successful.
 * @param bindpw The user password to bind as.
 * @param binddn The DN of the user will be returned in this variable.
 * @param retvals The values corresponding to the attributes requested in the attrs array.
 * @tip The filter supplied will be searched for. If a single entry is returned, an attempt
 *      is made to bind as that user. If this bind succeeds, the user is not validated.
 * @deffunc int util_ldap_cache_checkuserid(request_rec *r, util_ldap_connection_t *ldc,
 *                                          char *url, const char *basedn, int scope,
 *                                          char *filter, char *bindpw, char **binddn)
 *                                          char *url, const char *basedn, int scope, char **attrs,
 *                                          char *filter, char *bindpw, char **binddn, char ***retvals)
 */
int util_ldap_cache_checkuserid(request_rec *r, util_ldap_connection_t *ldc,
                                const char *url, const char *basedn, int scope, 
                                const char *filter, const char *bindpw, const char **binddn);
                              const char *url, const char *basedn, int scope, char **attrs,
                              const char *filter, const char *bindpw, const char **binddn, const char ***retvals);

/* from apr_ldap_cache.c */

+35 −2
Original line number Diff line number Diff line
@@ -68,6 +68,8 @@
/* for getpid() */
#include <unistd.h>
#endif
#include <ctype.h>

#include "httpd.h"
#include "http_config.h"
#include "http_core.h"
@@ -90,6 +92,7 @@ typedef struct {
    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 */
@@ -202,6 +205,7 @@ void mod_auth_ldap_build_filter(char *filtbuf,
 */
int mod_auth_ldap_check_user_id(request_rec *r)
{
    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);
@@ -254,7 +258,8 @@ int mod_auth_ldap_check_user_id(request_rec *r)
    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, filtbuf, sent_pw, &dn);
    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);

    if (result != LDAP_SUCCESS) {
@@ -278,6 +283,24 @@ int mod_auth_ldap_check_user_id(request_rec *r)
        r->user = req->dn;
    }

    /* add environment variables */
    if (sec->attributes && vals) {
        apr_table_t *e = r->subprocess_env;
        int i = 0;
        while (sec->attributes[i]) {
            char *str = apr_pstrcat(r->pool, "AUTHENTICATE_", sec->attributes[i], NULL);
            int j = 13;
            while (str[j]) {
                if (str[j] >= 'a' && str[j] <= 'z') {
                    str[j] = str[j] - ('a' - 'A');
                }
                j++;
            }
            apr_table_setn(e, str, vals[i]);
            i++;
        }
    }

    ap_log_rerror(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r, 
		  "[%d] auth_ldap authenticate: accepting %s", getpid(), r->user);

@@ -639,7 +662,17 @@ static const char *mod_auth_ldap_parse_url(cmd_parms *cmd,
    }
    sec->basedn = urld->lud_dn? apr_pstrdup(cmd->pool, urld->lud_dn) : "";
    if (urld->lud_attrs && urld->lud_attrs[0]) {
        sec->attribute = apr_pstrdup(cmd->pool, urld->lud_attrs[0]);
        int i = 1;
        while (urld->lud_attrs[i]) {
            i++;
        }
        sec->attributes = apr_pcalloc(cmd->pool, sizeof(char *) * (i+1));
        i = 0;
        while (urld->lud_attrs[i]) {
            sec->attributes[i] = apr_pstrdup(cmd->pool, urld->lud_attrs[i]);
            i++;
        }
        sec->attribute = sec->attributes[0];
    }
    else {
        sec->attribute = "uid";
+31 −5
Original line number Diff line number Diff line
@@ -720,9 +720,11 @@ start_over:
}

int util_ldap_cache_checkuserid(request_rec *r, util_ldap_connection_t *ldc,
                              const char *url, const char *basedn, int scope, 
                              const char *filter, const char *bindpw, const char **binddn)
                              const char *url, const char *basedn, int scope, char **attrs,
                              const char *filter, const char *bindpw, const char **binddn,
                              const char ***retvals)
{
    const char **vals = NULL;
    int result = 0;
    LDAPMessage *res, *entry;
    char *dn;
@@ -738,7 +740,6 @@ int util_ldap_cache_checkuserid(request_rec *r, util_ldap_connection_t *ldc,
        (util_ldap_state_t *)ap_get_module_config(r->server->module_config,
        &ldap_module);


    /* read lock this function */
    if (!util_ldap_cache_lock) {
        apr_lock_create(&util_ldap_cache_lock, APR_READWRITE, APR_INTRAPROCESS, NULL, st->pool);
@@ -776,6 +777,7 @@ int util_ldap_cache_checkuserid(request_rec *r, util_ldap_connection_t *ldc,
        else {
            /* ...and entry is valid */
            *binddn = search_nodep->dn;
            *retvals = search_nodep->vals;
            apr_lock_release(util_ldap_cache_lock);
            ldc->reason = "Authentication successful (cached)";
            return LDAP_SUCCESS;
@@ -803,7 +805,7 @@ start_over:
    /* try do the search */
    if ((result = ldap_search_ext_s(ldc->ldap,
				    basedn, scope, 
				    filter, NULL, 1, 
				    filter, attrs, 0, 
				    NULL, NULL, NULL, -1, &res)) == LDAP_SERVER_DOWN) {
        ldc->reason = "ldap_search_ext_s() for user failed with server down";
        goto start_over;
@@ -864,7 +866,29 @@ start_over:
        return result;
    }

    ldap_msgfree(res);
    /*
     * Get values for the provided attributes.
     */
    if (attrs) {
        int k = 0;
        int i = 0;
        while (attrs[k++]);
        vals = apr_pcalloc(r->pool, sizeof(char *) * (k+1));
        while (attrs[i]) {
            char **values;
            int j = 0;
            char *str = NULL;
            /* get values */
            values = ldap_get_values(ldc->ldap, entry, attrs[i]);
            while (values && values[j]) {
                str = str ? apr_pstrcat(r->pool, str, "; ", values[j], NULL) : apr_pstrdup(r->pool, values[j]);
                j++;
            }
            vals[i] = str;
            i++;
        }
        *retvals = vals;
    }

    /* 		
     * Add the new username to the search cache.
@@ -874,7 +898,9 @@ start_over:
    the_search_node.dn = *binddn;
    the_search_node.bindpw = bindpw;
    the_search_node.lastbind = apr_time_now();
    the_search_node.vals = vals;
    util_ald_cache_insert(curl->search_cache, &the_search_node);
    ldap_msgfree(res);
    apr_lock_release(util_ldap_cache_lock);

    ldc->reason = "Authentication successful";
+40 −4
Original line number Diff line number Diff line
@@ -127,16 +127,52 @@ void *util_ldap_search_node_copy(void *c)
{
    util_search_node_t *node = (util_search_node_t *)c;
    util_search_node_t *newnode = util_ald_alloc(sizeof(util_search_node_t));
    newnode->username = util_ald_strdup(node->username);
    newnode->dn = util_ald_strdup(node->dn);
    newnode->bindpw = util_ald_strdup(node->bindpw);

    /* safety check */
    if (newnode) {

        /* copy vals */
        if (node->vals) {
            int k = 0;
            int i = 0;
            while (node->vals[k++]);
            if (!(newnode->vals = util_ald_alloc(sizeof(char *) * (k+1)))) {
                util_ldap_search_node_free(newnode);
                return NULL;
            }
            while (node->vals[i]) {
                if (!(newnode->vals[i] = util_ald_strdup(node->vals[i]))) {
                    util_ldap_search_node_free(newnode);
                    return NULL;
                }
                i++;
            }
        }
        else {
            newnode->vals = NULL;
        }
        if (!(newnode->username = util_ald_strdup(node->username)) ||
            !(newnode->dn = util_ald_strdup(node->dn)) ||
            !(newnode->bindpw = util_ald_strdup(node->bindpw)) ) {
            util_ldap_search_node_free(newnode);
            return NULL;
        }
        newnode->lastbind = node->lastbind;

    }
    return (void *)newnode;
}

void util_ldap_search_node_free(void *n)
{
    int i = 0;
    util_search_node_t *node = (util_search_node_t *)n;
    if (node->vals) {
        while (node->vals[i]) {
            util_ald_free(node->vals[i++]);
        }
        util_ald_free(node->vals);
    }
    util_ald_free(node->username);
    util_ald_free(node->dn);
    util_ald_free(node->bindpw);
Loading