--- mod_auth_ldap.c.orig 2007-11-04 08:03:08.000000000 +0200 +++ mod_auth_ldap.c 2007-11-04 08:46:12.000000000 +0200 @@ -20,6 +20,15 @@ * Original code from auth_ldap module for Apache v1.3: * Copyright 1998, 1999 Enbridge Pipelines Inc. * Copyright 1999-2001 Dave Carrigan + * + * Patched: Sun Nov 4 08:44:55 EET 2007 + * Added 2x more configuration directives: + * + * # controls whether to use the user supplied auth data when doing the initial bind + * AuthLDAPBindUserSuppliedAuth On + * # an optional domain used to suffix the supplied user-id + * AuthLDAPBindSuffixDN xxx.com + * */ #include @@ -67,8 +76,11 @@ 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 binduseinputauth; /* Whether to use the user supplied input for performing the first bind */ + char *bindsuffixdomain; /* The domain used to append the user, when doing the initial bind */ int frontpage_hack; /* Hack for frontpage support */ int user_is_dn; /* If true, connection->user is DN instead of userid */ @@ -322,11 +334,39 @@ start_over: + // check whether to use the user supplied auth data for the initial bind + // get the password first, and re-use the status further below + result = ap_get_basic_auth_pw(r, &sent_pw); + /* There is a good AuthLDAPURL, right? */ if (sec->host) { - ldc = util_ldap_connection_find(r, sec->host, sec->port, + // + if ( sec->binduseinputauth ) { + ap_log_rerror(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r, + "[%d] auth_ldap authorise: " + "fallback to user supplied tokens for initial bind.", + getpid()); + // if we have a domain suffix, prepare it here + char *tmpuid = r->user; + if ( sec->bindsuffixdomain != NULL ) { + ap_log_rerror(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r, + "[%d] auth_ldap authorise: " + "Suffix the user id with the default domain: %s.", + getpid(), sec->bindsuffixdomain); + char *suffix = apr_palloc(r->pool, strlen(r->user) + strlen(sec->bindsuffixdomain) + 2); + strcpy(suffix, r->user); + strcat(suffix, "@"); + strcat(suffix, sec->bindsuffixdomain); + tmpuid = suffix; + } + ldc = util_ldap_connection_find(r, sec->host, sec->port, + tmpuid, sent_pw, sec->deref, + sec->secure); + } else { + 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, @@ -338,7 +378,7 @@ "[%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))) { + if (result) { ap_log_rerror(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r, "[%d] auth_ldap authenticate: " "ap_get_basic_auth_pw() returns %d", getpid(), result); @@ -460,6 +500,14 @@ return DECLINED; } + // check whether to use the user supplied auth data for the initial bind + // get the password first, and re-use the status further below + const char *sent_pw; + int result2 = 0; + + result2 = ap_get_basic_auth_pw(r, &sent_pw); + + /* * It is possible that we've skipped mod_auth_ldap's * check_user_id hook, but still get here. In that @@ -481,9 +529,32 @@ } if (sec->host) { - ldc = util_ldap_connection_find(r, sec->host, sec->port, + if ( result2 && sec->binduseinputauth ) { + ap_log_rerror(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r, + "[%d] auth_ldap authorise: " + "fallback to user supplied tokens for initial bind.", + getpid()); + // if we have a domain suffix, prepare it here + char *tmpuid = r->user; + if ( sec->bindsuffixdomain != NULL ) { + ap_log_rerror(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r, + "[%d] auth_ldap authorise: " + "Suffix the user id with the default domain: %s.", + getpid(), sec->bindsuffixdomain); + char *suffix = apr_palloc(r->pool, strlen(r->user) + strlen(sec->bindsuffixdomain) + 2); + strcpy(suffix, r->user); + strcat(suffix, "@"); + strcat(suffix, sec->bindsuffixdomain); + tmpuid = suffix; + } + ldc = util_ldap_connection_find(r, sec->host, sec->port, + tmpuid, sent_pw, sec->deref, + sec->secure); + } else { + ldc = util_ldap_connection_find(r, sec->host, sec->port, sec->binddn, sec->bindpw, sec->deref, sec->secure); + } apr_pool_cleanup_register(r->pool, ldc, mod_auth_ldap_cleanup_connection_close, apr_pool_cleanup_null); @@ -757,6 +828,8 @@ sec->host = NULL; sec->binddn = NULL; sec->bindpw = NULL; + sec->binduseinputauth = 0; + sec->bindsuffixdomain = NULL; sec->deref = always; sec->group_attrib_is_dn = 1; @@ -968,6 +1041,14 @@ (void *)APR_OFFSETOF(mod_auth_ldap_config_t, bindpw), OR_AUTHCFG, "Password to use to bind to LDAP server. If not provided, will do an anonymous bind."), + AP_INIT_FLAG("AuthLDAPBindUserSuppliedAuth", ap_set_flag_slot, + (void *)APR_OFFSETOF(mod_auth_ldap_config_t, binduseinputauth), OR_AUTHCFG, + "Set to 'on' to use the user supplied data when performing the inital bind."), + + AP_INIT_TAKE1("AuthLDAPBindSuffixDN", ap_set_string_slot, + (void *)APR_OFFSETOF(mod_auth_ldap_config_t, bindsuffixdomain), OR_AUTHCFG, + "The domain used to suffix the supplied user id when doing the initial bind."), + AP_INIT_FLAG("AuthLDAPRemoteUserIsDN", ap_set_flag_slot, (void *)APR_OFFSETOF(mod_auth_ldap_config_t, user_is_dn), OR_AUTHCFG, "Set to 'on' to set the REMOTE_USER environment variable to be the full "