Bug 31352 - RFE, Bind to LDAP server with browser supplier user/pass
Summary: RFE, Bind to LDAP server with browser supplier user/pass
Status: ASSIGNED
Alias: None
Product: Apache httpd-2
Classification: Unclassified
Component: mod_auth_ldap (show other bugs)
Version: 2.0.51
Hardware: Sun Solaris
: P3 enhancement (vote)
Target Milestone: ---
Assignee: Apache HTTPD Bugs Mailing List
URL:
Keywords:
: 23548 31428 35805 (view as bug list)
Depends on:
Blocks:
 
Reported: 2004-09-21 23:59 UTC by Simon Klyne
Modified: 2005-10-04 09:52 UTC (History)
3 users (show)



Attachments
Patch, user browser supplied user/pass for binddn/bindpw (4.10 KB, patch)
2004-09-22 00:18 UTC, Simon Klyne
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Simon Klyne 2004-09-21 23:59:41 UTC
In environments where the Access Control to the LDAP DIT is protected from 
anonymous binds and bound users are only able to read their user entries 
possible binding options for mod_auth_ldap will either fail to authenticate a 
user, or there are security implications if the <Directory/> sections contain a 
suitably powerful binddn/bindpw.

The browser supplies a username and password for the auth check.  

This patch extends the AuthLDAPBindDN and AuthLDAPBindPasswd directives to 
accept $USER and $PASSWORD respectively and substitute for user/pass
eg:
  AuthLDAPBindDN	uid=$USER,ou=people,ou=common,l=lon,c=gb,o=dis
  AuthLDAPBindPassword	$PASSWORD
for user/pass of 'klyne'/'password' becomes:
  AuthLDAPBindDN	uid=klyne,ou=people,ou=common,l=lon,c=gb,o=dis
  AuthLDAPBindPassword	password

The rest of mod_auth_ldap continues as before.



--- httpd-2.0.51/modules/experimental/mod_auth_ldap.c-dist	2004-05-22 01:39:
41.000000000 +0200
+++ httpd-2.0.51/modules/experimental/mod_auth_ldap.c	2004-09-21 23:40:53.
728681000 +0200
@@ -161,6 +161,83 @@
 
 
 /*
+ * 
+ * Read per directory module config, and substitute for variables in binddn and 
bindpw
+ * This is just a wrapper around the call to 
+ *   ap_get_module_config(r->per_dir_config, &auth_ldap_module);
+ *
+ * If the binddn and bindpw set by the AuthLDAPBindDN and AuthLDAPBindPassword 
directives
+ * contain $USER and $PASSWORD then substitute these with the browser supplied 
user/pass, 
+ * otherwise just return the mod_auth_ldap_config_t.
+ *
+ */
+#define	BIND_USER	"$USER"
+#define	BIND_PASSWD	"$PASSWORD"
+static mod_auth_ldap_config_t *auth_ldap_get_per_dir_module_config(request_rec 
*r)
+{
+    const char *sent_pw;
+    int bad_sent_pw = 0;
+
+	char *bind_user; 	/* set to start of BIND_USER if binddn requires 
username subst */
+
+	int doSubst = 0;	/* set to true if we have values to substitute */
+
+    mod_auth_ldap_config_t *s =
+        (mod_auth_ldap_config_t *)ap_get_module_config(r->per_dir_config, 
&auth_ldap_module);
+
+	/* check client sent a username and a password */
+	if ( ! r->user ) {
+	    ap_log_rerror(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r,
+					  "[%d] auth_ldap authenticate: 
auth_ldap_get_per_dir_module_config()"
+					  " : Client sent no username",
+					  getpid());
+		/* Substitute for client supplied USER in binddn if directory 
configured for BIND_USER 
+		 * eg. if "AuthLDAPBindDN	uid=$USER,ou=people,l=lon,c=gb,o=dis"
+		 * send binddn to "uid=<user>,ou=people,l=lon,c=gb,o=dis"
+		 */
+	} else {
+		if ((s->binddn) && ((bind_user = strstr(s->binddn, BIND_USER)) !=NULL)) 
{ 
+			char *attr;
+			ap_log_rerror(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r,
+						  "[%d] auth_ldap authenticate: 
auth_ldap_get_per_dir_module_config()"
+						  ": binddn %s",
+						  getpid(), s->binddn);
+			attr = apr_pstrndup(r->pool, s->binddn, bind_user - s->binddn);
+			s->binddn = apr_pstrcat(r->pool, attr, r->user, bind_user + 
strlen(BIND_USER), NULL );
+			doSubst++;
+		}
+	}
+
+	if ((bad_sent_pw = ap_get_basic_auth_pw(r, &sent_pw))) {
+		ap_log_rerror(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r,
+			  "[%d] auth_ldap_get_per_dir_module_config() auth_ldap authenticate: 
"
+			  "ap_get_basic_auth_pw() returns %d", getpid(), bad_sent_pw);
+
+		/* set bindpw to client suppled password if directory configured for 
bindpw
+		   to BIND_PASSWD */
+	} else {
+		if ( s->bindpw && strcmp(s->bindpw, BIND_PASSWD) ==0) { 
+			ap_log_rerror(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r,
+						  "[%d] auth_ldap authenticate: 
auth_ldap_get_per_dir_module_config()"
+						  ": bindpw USER SUPPLIED",
+						  getpid());
+			s->bindpw = (char *)sent_pw;
+			doSubst++;
+		}
+	}
+	
+	if (doSubst) {
+		ap_log_rerror(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r,
+					  "[%d] auth_ldap_get_per_dir_module_config() : SUBST",
+					  getpid());
+
+		ap_set_module_config(r->per_dir_config, &auth_ldap_module, s);
+	}
+
+	return s;
+}
+
+/*
  * 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
@@ -269,7 +346,7 @@
     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);
+        (mod_auth_ldap_config_t *)auth_ldap_get_per_dir_module_config(r);
 
     util_ldap_connection_t *ldc = NULL;
     const char *sent_pw;
@@ -409,8 +486,7 @@
         (mod_auth_ldap_request_t *)ap_get_module_config(r->request_config,
         &auth_ldap_module);
     mod_auth_ldap_config_t *sec =
-        (mod_auth_ldap_config_t *)ap_get_module_config(r->per_dir_config, 
-        &auth_ldap_module);
+        (mod_auth_ldap_config_t *)auth_ldap_get_per_dir_module_config(r);
 
     util_ldap_connection_t *ldc = NULL;
     int m = r->method_number;
Comment 1 Simon Klyne 2004-09-22 00:18:52 UTC
Created attachment 12826 [details]
Patch, user browser supplied user/pass for binddn/bindpw
Comment 2 Graham Leggett 2004-10-17 17:56:44 UTC
Access to the LDAP directory is governed by the AuthLDAPBindDN and
AuthLDAPBindPassword directives, these should be set to an LDAP object that is
allowed to search for users amongst the user objects, and compare for group
membership amongst the group objects. This object would be granted neither read
nor write access to your directory.

Binding as the end user means that end users can both search for other users,
and query group memberships. This is less secure than one account specified in
the httpd config file for this specific purpose.
Comment 3 steve smith 2004-10-18 10:09:08 UTC
I haven't checked the code, but I'm not sure this is entirely correct.  The end 
user only needs read access to 'self' in order to return the required success 
code for the search part of the auth operation, preventing search on the rest 
of the user accounts.  Search access to the groups is a different question 
though; one could create an ACI for each group entry, providing access only by 
its own group members, but I'm guessing that's a little too clunky.  Either 
way, the security issues are surmountable, and worth it for the gain.
Comment 4 Graham Leggett 2005-01-21 23:14:47 UTC
Is it possible to organise a patch to the httpd v2.1 mod_authnz_ldap module?

Most of the problems in the LDAP module for httpd v2.0 have been fixed in an
overhaul of the module in httpd v2.1, and the module is no longer considered
experimental.
Comment 5 Graham Leggett 2005-01-21 23:22:59 UTC
*** Bug 23548 has been marked as a duplicate of this bug. ***
Comment 6 Gael Mauleon 2005-09-20 10:19:36 UTC
*** Bug 35805 has been marked as a duplicate of this bug. ***
Comment 7 Gael Mauleon 2005-09-20 10:21:17 UTC
(In reply to comment #6)
> *** Bug 35805 has been marked as a duplicate of this bug. ***

Had the same purpose by making this quick patch in bug 35805, so I marked it
duplicate.
Comment 8 Gael Mauleon 2005-09-27 10:38:59 UTC
(In reply to comment #7)
> (In reply to comment #6)
> > *** Bug 35805 has been marked as a duplicate of this bug. ***
> 
> Had the same purpose by making this quick patch in bug 35805, so I marked it
> duplicate.

Oups in fact I was a bit in a hurry in my explanation, what I wanted to explain
is  that with the same system (a $DIRECTORY here) we can make my enhancement
explained in the Bug 38805 :)
Comment 9 Joe Orton 2005-10-04 17:52:37 UTC
*** Bug 31428 has been marked as a duplicate of this bug. ***