]> granicus.if.org Git - apache/commitdiff
Add specified user attributes to the environment when using
authorGraham Leggett <minfrin@apache.org>
Tue, 28 Aug 2001 23:16:12 +0000 (23:16 +0000)
committerGraham Leggett <minfrin@apache.org>
Tue, 28 Aug 2001 23:16:12 +0000 (23:16 +0000)
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

CHANGES
include/util_ldap.h
modules/aaa/mod_auth_ldap.c
modules/ldap/util_ldap.c
modules/ldap/util_ldap_cache.c
modules/ldap/util_ldap_cache.h
modules/ldap/util_ldap_cache_mgr.c

diff --git a/CHANGES b/CHANGES
index 5f5c03732aaa4f2b049ba47d234f6b0a336cce27..651c286bb341bf3cf3a6aca1b680d5e9c7135756 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,5 +1,11 @@
 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>]
index bd9327e26f7a344be90b2f989b6dbc47daebafe5..a0182724cf3f6212f882b3f7f02c4dee388de4c7 100644 (file)
@@ -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 */
 
index c23cffcd9b153b6e89a391f7eb101c139ab10ac2..6be891cf172de13e15b2e06bde187515eff87d71 100644 (file)
@@ -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";
index 433ea097e3670d6c0e0acc373e548fa7bb63bd5d..4e9ca0e501557b4a1dd411f71a746fdbb2995598 100644 (file)
@@ -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";
index cd4888676e5f27627d5654580a0ba27e258bbdee..f8d4a4dc08ba4ea29547e07c4dcf1a09cdcfdf4c 100644 (file)
@@ -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);
-    newnode->lastbind = node->lastbind;
+
+    /* 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);
index 2cedb2f45b27fb34bf7b40a05b74e9aa485f6c8f..ea0709887ac517f6134277f5de6ba0800af3fb51 100644 (file)
@@ -139,9 +139,10 @@ typedef struct util_url_node_t {
 typedef struct util_search_node_t {
     const char *username;              /* Cache key */
     const char *dn;                    /* DN returned from search */
-    const char *bindpw;                /* The most recently used bind password; 
-                                  NULL if the bind failed */
-    apr_time_t lastbind;       /* Time of last successful bind */
+    const char *bindpw;                        /* The most recently used bind password; 
+                                          NULL if the bind failed */
+    apr_time_t lastbind;               /* Time of last successful bind */
+    const char **vals;                 /* Values of queried attributes */
 } util_search_node_t;
 
 /*
index c35c4612e940360ea49e8551490f49543bb631e6..5921f5fd40e18e2a7ccdfe427bdefea486e7ffa8 100644 (file)
@@ -116,12 +116,15 @@ void util_ald_free(const void *ptr)
 {
 #if APR_HAS_SHARED_MEMORY
     if (util_ldap_shm) {
-        apr_shm_free(util_ldap_shm, (void *)ptr);
+        if (ptr)
+            apr_shm_free(util_ldap_shm, (void *)ptr);
     } else {
-        free((void *)ptr);
+        if (ptr)
+            free((void *)ptr);
     }
 #else
-    free((void *)ptr);
+    if (ptr)
+        free((void *)ptr);
 #endif
 }
 
@@ -129,12 +132,12 @@ void *util_ald_alloc(int size)
 {
 #if APR_HAS_SHARED_MEMORY
     if (util_ldap_shm) {
-        return (void *)apr_shm_malloc(util_ldap_shm, size);
+        return (void *)apr_shm_calloc(util_ldap_shm, size);
     } else {
-        return (void *)malloc(size);
+        return (void *)calloc(sizeof(char), size);
     }
 #else
-    return (void *)malloc(size);
+    return (void *)calloc(size);
 #endif
 }