--- mod_auth_ldap.c 2005-03-18 02:45:15.000000000 +0100 +++ mod_auth_ldap.c.oden 2005-08-30 17:16:51.000000000 +0200 @@ -372,7 +372,8 @@ *sub_dn, *uid_attr, *uid_attr_alt, - *group_attr; + *group_attr, + *uid_filter; char filter[512]; @@ -685,6 +686,7 @@ cr->max_bind_tries=10; cr->auth_on_bind=0; cr->uid_attr=ap_pstrdup(p,"uid"); + cr->uid_filter=ap_pstrdup(p,"(uid=%u)"); /* * Note about uid_attr_alt. If this attribute is specified, after @@ -957,6 +959,13 @@ return(NULL); } +/* apache2 */ +static const char *set_uid_filter(cmd_parms *cmd,ldap_auth_config_rec *cr, char *arg) +{ + cr->uid_filter=ap_pstrdup(cmd->pool,arg); + return (NULL); +} + /* apache2*/ static const command_rec mod_auth_ldap_auth_cmds[]= { @@ -1030,7 +1039,6 @@ OR_AUTHCFG, "LAP attribute to search and set to LDAP_USER_ALT after authentication"), - /* apache2*/ AP_INIT_TAKE1("Group_Attr",set_group_attr, NULL, @@ -1038,6 +1046,12 @@ "Group attribute for user DN. iPlanet uses uniqueMember as the attribute"), /* apache2*/ + AP_INIT_TAKE1("UID_Filter",set_uid_filter, + NULL, + OR_AUTHCFG, + "Search Filter. Filter for lookup instead of just a single attribute (uid=\%u)"), + + /* apache2*/ AP_INIT_TAKE1("Bind_DN",set_bind_dn, NULL, OR_AUTHCFG, @@ -1703,6 +1717,46 @@ #endif /* WITH_APACHE_2 */ } +/** +** buildLdapFilter() +** return 0 on error, nonzero on success +** +** Parameters: +** char *szfilter A pointer to a buffer for storing the filter +** size_t *len The size of szfilter +** char *uid_filter LDAP filter to use with userid, e.g. "(|(uid=%u)(mail=%u))" +** char *userid the userid to replace %u with +*/ + +static int buildLdapFilter( char* szfilter, size_t len, + char* uid_filter, char* userid ) +{ + char* p1; + char* p2; + size_t s = 0; + + szfilter[0] = 0; + p1 = uid_filter; + while( (p2=strstr(p1,"%u")) ) { + size_t d = p2-p1; + s += d; + s += strlen(userid); + if( s > len-1 ) { + /* about to overflow, just be safe and abort */ + return 0; + } + strncat( szfilter, p1, d ); + strcat( szfilter, userid ); + p1 = p2+2; + } + if( s+strlen(p1) > len-1 ) { + /* about to overflow, just be safe and abort */ + return 0; + } + strcat( szfilter, p1 ); + return 1; +} + /* ** mod_auth_ldap_find_user_dn() ** return the DN of the user @@ -1754,7 +1808,7 @@ char *base_dn, - *uid_attrib, + *uid_filter, *userid=NULL, *bind_dn, *bind_pass; @@ -1779,16 +1833,27 @@ userid=r->user; #endif /* WITH_APACHE_2 */ - - base_dn=cr->base_dn; - uid_attrib=cr->uid_attr; + uid_filter=cr->uid_filter; bind_dn=cr->bind_dn; bind_pass=cr->bind_pass; - /* prepare filter with UidAttr. */ - ap_snprintf(szfilter,sizeof(szfilter)-1,"(%s=%s)",uid_attrib,userid); + /* prepare filter with UidFilter. */ + if( !buildLdapFilter( szfilter, sizeof(szfilter), uid_filter, userid ) ) { + +#ifdef WITH_APACHE_1 + ap_log_rerror(APLOG_MARK,APLOG_NOERRNO | APLOG_ERR,r, + "[mod_auth_ldap.c] - Error: LDAP filter \"%s\" too long", uid_filter); +#endif /* WITH_APACHE_1 */ + +#ifdef WITH_APACHE_2 + ap_log_rerror(APLOG_MARK,APLOG_NOERRNO | APLOG_ERR,0,r, + "[mod_auth_ldap.c] - Error: LDAP filter \"%s\" too long", uid_filter); +#endif /* WITH_APACHE_2 */ + + return(NULL); + } m_rerr(r,cr->debug,"%s (%d) - Using LDAP filter: %s",MFL,szfilter); @@ -1844,7 +1909,7 @@ ap_log_rerror(APLOG_MARK,APLOG_NOERRNO | APLOG_ERR,0,r,"%s (%d) - ldap_search_s() failed",MFL); #endif /* WITH_APACHE_2 */ - #ifdef WITH_APACHE_1 +#ifdef WITH_APACHE_1 ap_log_rerror(APLOG_MARK,APLOG_NOERRNO | APLOG_ERR,r,"%s (%d) - ldap_search_s() failed",MFL); #endif /* WITH_APACHE_2 */ @@ -1857,6 +1922,8 @@ /* note: ldap_err2string() returns pointer to a static space */ ap_log_rerror(APLOG_MARK,APLOG_NOERRNO | APLOG_ERR,0,r, "[mod_auth_ldap.c] - Error: %s",ldap_err2string(rc)); + ap_log_rerror(APLOG_MARK,APLOG_NOERRNO | APLOG_ERR,0,r, + "[mod_auth_ldap.c] - Error: Filter was \"%s\"",szfilter); #endif /* WITH_APACHE_2 */ #ifdef WITH_APACHE_1 @@ -1913,7 +1980,7 @@ if ((entry =ldap_first_entry(cr->ld,result)) == NULL) { m_rerr(r,cr->debug, - "[mod_auth_ldap.c] - %s=%s Unknown in LDAP server",uid_attrib,userid); + "[mod_auth_ldap.c] - %s Unknown in LDAP server",szfilter); if (result != (LDAPMessage *) NULL) { @@ -3944,8 +4011,16 @@ *attr, **vals; +#ifdef WITH_APACHE_1 + ap_log_rerror(APLOG_MARK,APLOG_NOERRNO | APLOG_ERR,r, + "XXXXXXXX"); +#endif /* WITH_APACHE_1 */ + +#ifdef WITH_APACHE_2 ap_log_rerror(APLOG_MARK,APLOG_NOERRNO | APLOG_ERR,0,r, "XXXXXXXX"); +#endif /* WITH_APACHE_2 */ + for (ent=ldap_first_entry (ld,res); ent != NULL; ent=ldap_next_entry (ld,ent)) @@ -3959,8 +4034,17 @@ { for (i=0; vals[i] != NULL; i++) { + +#ifdef WITH_APACHE_1 + ap_log_rerror(APLOG_MARK,APLOG_NOERRNO | APLOG_ERR,r, + "dump: %s=%s",attr,vals[i]); +#endif /* WITH_APACHE_1 */ + +#ifdef WITH_APACHE_2 ap_log_rerror(APLOG_MARK,APLOG_NOERRNO | APLOG_ERR,0,r, "dump: %s=%s",attr,vals[i]); +#endif /* WITH_APACHE_2 */ + } if (vals) ldap_value_free(vals);