Bug 31332 - enable environment variables in LDAP require group
Summary: enable environment variables in LDAP require group
Status: RESOLVED FIXED
Alias: None
Product: Apache httpd-2
Classification: Unclassified
Component: mod_auth_ldap (show other bugs)
Version: 2.0.51
Hardware: All All
: P3 enhancement (vote)
Target Milestone: ---
Assignee: Apache HTTPD Bugs Mailing List
URL:
Keywords: PatchAvailable
Depends on:
Blocks:
 
Reported: 2004-09-21 09:51 UTC by Rob Leathley
Modified: 2015-01-16 20:31 UTC (History)
0 users



Attachments
mod_auth_ldap.c 2.0.51 patch to implement env var substitution (3.42 KB, patch)
2004-09-21 09:56 UTC, Rob Leathley
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Rob Leathley 2004-09-21 09:51:20 UTC
Using environment variables in a 'require group' DN substantially increases
flexibility of access control.  %{varName} is substitued for the variable's
value when determining authorisation.

eg. the following can be used to authenticate against different LDAP groups for
different directories, both the directory structure and authorisation being
dynamically updateble:

RewriteRule ^/baseDir/([^/]*)/? - [env=dn1:$1]
Require group ou=%{dn1},cn=groups,dc=ricardo,dc=com

The following is the diff on mod_auth_ldap.c from 2.0.51 required to implement
this [expand_env() is based on do_expand() in mod_rewrite.c]:


--- httpd-2.0.51/modules/experimental/mod_auth_ldap.c   2004-05-22
00:39:41.000000000 +0100
+++ httpd-2.0.51_var/modules/experimental/mod_auth_ldap.c       2004-09-20
16:09:24.000000000 +0100
@@ -103,6 +103,7 @@
 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 void expand_env(request_rec *r, const char *input, char *buffer, int nbuf);

 /* ---------------------------------------- */

@@ -582,6 +583,7 @@
         else if (strcmp(w, "group") == 0) {
             struct mod_auth_ldap_groupattr_entry_t *ent = (struct
mod_auth_ldap_groupattr_entry_t *) sec->groupattr->elts;
             int i;
+            char group[MAX_STRING_LEN];

             if (sec->group_attrib_is_dn) {
                 if (req->dn == NULL || strlen(req->dn) == 0) {
@@ -599,6 +601,9 @@
                 }
             }

+            expand_env(r, t, group, sizeof(group));
+            if (group[0]=='\0') return HTTP_UNAUTHORIZED;
+
             ap_log_rerror(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r,
                           "[%d] auth_ldap authorise: require group: testing for
group membership in \"%s\"",
                          getpid(), t);
@@ -606,9 +611,9 @@
             for (i = 0; i < sec->groupattr->nelts; i++) {
                ap_log_rerror(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r,
                               "[%d] auth_ldap authorise: require group: testing
for %s: %s (%s)", getpid(),
-                              ent[i].name, sec->group_attrib_is_dn ? req->dn :
req->user, t);
+                              ent[i].name, sec->group_attrib_is_dn ? req->dn :
req->user, group);

-                result = util_ldap_cache_compare(r, ldc, sec->url, t, ent[i].name,
+                result = util_ldap_cache_compare(r, ldc, sec->url, group,
ent[i].name,
                                      sec->group_attrib_is_dn ? req->dn :
req->user);
                 switch(result) {
                     case LDAP_COMPARE_TRUE: {
@@ -649,6 +654,54 @@
     return HTTP_UNAUTHORIZED;
 }

+/* ---------------------------------------- */
+/* expand string with Apache environment variables */
+static void expand_env(request_rec *r, const char *input, char *buffer, int nbuf) {
+    const char *inp;
+    char *outp;
+    apr_size_t span, space;
+
+    inp = input;
+    outp = buffer;
+    space = nbuf - 1; /* room for '\0' */
+
+    for (;;) {
+        span = strcspn(inp, "%");
+        if (span > space) {
+            span = space;
+        }
+        memcpy(outp, inp, span);
+        inp += span;
+        outp += span;
+        space -= span;
+        if (space == 0 || *inp == '\0') {
+            break;
+        }
+        if (inp[1] == '{') {
+            char *endp, *var, *val;
+            endp = strchr(inp+2, '}');
+            if (endp == NULL) {
+                goto skip;
+            }
+            var  = apr_pstrndup(r->pool, inp+2, endp-inp-2);
+            val=(char *) apr_table_get(r->subprocess_env, var);
+            if (!val) { /* flag subs failed */
+              buffer='\0';
+              break;
+            }
+            span = apr_cpystrn(outp, val, space) - outp;
+            inp = endp+1;
+            outp += span;
+            space -= span;
+            continue;
+        }
+        skip:
+        *outp++ = *inp++;
+        space--;
+    }
+    *outp++ = '\0';
+}
+

 /* ---------------------------------------- */
 /* config directives */
Comment 1 Rob Leathley 2004-09-21 09:56:06 UTC
Created attachment 12813 [details]
mod_auth_ldap.c 2.0.51 patch to implement env var substitution
Comment 2 Graham Leggett 2005-01-21 23:09:42 UTC
Would it be possible to create a patch for httpd v2.1?

The LDAP support in httpd v2.1 is no longer experiemental, it would be great to
include this feature in the mod_authnz_ldap module.
Comment 3 Eric Covener 2015-01-16 20:31:15 UTC
2.4.x interpolates arguments to Require using the expression parser.