the username that was passed by the client. It is turned off by
default.</p>
</usage>
-<seealso><directive module="mod_authnz_ldap">AuthLDAPAllowDNAuth</directive></seealso>
-</directivesynopsis>
-
-<directivesynopsis>
-<name>AuthLDAPAllowDNAuth</name>
-<description>Allow the user to authenticate by passing a fully distinguished
-user name.</description>
-<syntax>AuthLDAPAllowDNAuth on|off</syntax>
-<default>AuthLDAPAllowDNAuth off</default>
-<contextlist><context>directory</context><context>.htaccess</context>
-</contextlist>
-<override>AuthConfig</override>
-
-<usage>
- <p>If this directive is set to ON, users are allowed to pass a fully
- distinguished user name as the user ID. Regardless of this setting,
- Auth_LDAP will still allow a contextless login. This directive is
- turned off by default.</p>
-
- <note><title>Note</title>
- <p>If a full user DN is allowed for authentication and the value of
- <directive module="mod_authnz_ldap">AuthLDAPRemoteUserIsDN</directive>
- is set to OFF, the value of the REMOTE_USER environment variable
- will contain the actual user name value passed in the request. If
- this directive is set to ON, the REMOTE_USER environment variable
- will always be set to the user DN retrieved from the LDAP directory.
- If a contextless user ID is required in all cases instead of a
- full DN, it is possible to retrieve the desired attribute value
- from the user object by specifying an attribute list in the
- <directive module="mod_authnz_ldap">AuthLDAPUrl</directive> directive.</p>
- </note>
-</usage>
</directivesynopsis>
<directivesynopsis>
<dt>attribute</dt>
- <dd>The attribute to search for as well as additional attribute
- values to extract from the authenticated user object.
+ <dd>The attribute to search for.
Although RFC 2255 allows a comma-separated list of
attributes, only the first attribute will be used, no
- matter how many are provided. The values of all other listed
- attributes will be extracted from the user object and assigned
- to environment variables (AUTHENTICATE_<Attribute>=value).
- If no attributes are provided, the default is to use <code>uid</code>.
- It's a good idea to choose an attribute that will be unique across
- all entries in the subtree you will be searching.</dd>
+ matter how many are provided. If no attributes are
+ provided, the default is to use <code>uid</code>. It's a good
+ idea to choose an attribute that will be unique across all
+ entries in the subtree you will be using.</dd>
<dt>scope</dt>
it's the exact string passed by the HTTP client */
int secure; /* True if SSL connections are requested */
- int allow_fdn_auth; /* Set to True if user is allowed to authenticate using an FDN */
} authn_ldap_config_t;
typedef struct {
return NULL;
}
-#define FILTER_LENGTH MAX_STRING_LEN
-static char* cat_escape_dn_element(char *filtbuf, char *user)
-{
- char *p, *q, *filtbuf_end;
-
- /*
- * Now add the client-supplied username to the filter, ensuring that any
- * LDAP filter metachars are escaped.
- */
- filtbuf_end = filtbuf + FILTER_LENGTH - 1;
-#if APR_HAS_MICROSOFT_LDAPSDK
- for (p = user, q=filtbuf + strlen(filtbuf);
- *p && q < filtbuf_end; ) {
- if (strchr("*()\\", *p) != NULL) {
- if ( q + 3 >= filtbuf_end)
- break; /* Don't write part of escape sequence if we can't write all of it */
- *q++ = '\\';
- switch ( *p++ )
- {
- case '*':
- *q++ = '2';
- *q++ = 'a';
- break;
- case '(':
- *q++ = '2';
- *q++ = '8';
- break;
- case ')':
- *q++ = '2';
- *q++ = '9';
- break;
- case '\\':
- *q++ = '5';
- *q++ = 'c';
- break;
- }
- }
- else
- *q++ = *p++;
- }
-#else
- for (p = user, q=filtbuf + strlen(filtbuf);
- *p && q < filtbuf_end; *q++ = *p++) {
- if (strchr("*()\\", *p) != NULL) {
- *q++ = '\\';
- if (q >= filtbuf_end) {
- break;
- }
- }
- }
-#endif
- *q = '\0';
-
- return filtbuf;
-}
/*
* Build the search filter, or at least as much of the search filter that
*
* Further, assume that the userid passed by the client was `userj'. The
* search filter will be (&(posixid=*)(uid=userj)).
- *
- * If a full DN is allowed for authentication, the a userid of
- * cn=userj,o=dev will result in the following search filter:
- * (&(objectclass=*)(&(cn:dn:=userj)(o:dn:=dev)))
*/
+#define FILTER_LENGTH MAX_STRING_LEN
static void authn_ldap_build_filter(char *filtbuf,
request_rec *r,
const char* sent_user,
const char* sent_filter,
authn_ldap_config_t *sec)
{
+ char *p, *q, *filtbuf_end;
char *user, *filter;
apr_xlate_t *convset = NULL;
apr_size_t inbytes;
apr_size_t outbytes;
char *outbuf;
- char **dnbuf = NULL;
if (sent_user != NULL) {
user = apr_pstrdup (r->pool, sent_user);
}
}
- apr_snprintf(filtbuf, FILTER_LENGTH, "(&(%s)(&", filter);
+ /*
+ * Create the first part of the filter, which consists of the
+ * config-supplied portions.
+ */
+ apr_snprintf(filtbuf, FILTER_LENGTH, "(&(%s)(%s=", filter, sec->attribute);
- /* If FDN authentication is not allowed then don't attempt to explode
- the user ID. The result is that dnbuf well be NULL which will
- bypass building a FDN unique filter. */
- if (sec->allow_fdn_auth) {
- dnbuf = ldap_explode_dn (user, 0);
+ /*
+ * Now add the client-supplied username to the filter, ensuring that any
+ * LDAP filter metachars are escaped.
+ */
+ filtbuf_end = filtbuf + FILTER_LENGTH - 1;
+#if APR_HAS_MICROSOFT_LDAPSDK
+ for (p = user, q=filtbuf + strlen(filtbuf);
+ *p && q < filtbuf_end; ) {
+ if (strchr("*()\\", *p) != NULL) {
+ if ( q + 3 >= filtbuf_end)
+ break; /* Don't write part of escape sequence if we can't write all of it */
+ *q++ = '\\';
+ switch ( *p++ )
+ {
+ case '*':
+ *q++ = '2';
+ *q++ = 'a';
+ break;
+ case '(':
+ *q++ = '2';
+ *q++ = '8';
+ break;
+ case ')':
+ *q++ = '2';
+ *q++ = '9';
+ break;
+ case '\\':
+ *q++ = '5';
+ *q++ = 'c';
+ break;
+ }
+ }
+ else
+ *q++ = *p++;
}
-
- if (dnbuf && (strchr(*dnbuf, '='))) {
- char **buf;
- char *dnfilter = "&";
- for (buf = dnbuf; *buf; buf++) {
- char *eq = strchr (*buf, '=');
- char *newdn = *buf;
-
- if (eq) {
- newdn = apr_pstrcat (r->pool, apr_pstrndup (r->pool, *buf, eq-(*buf)),
- ":dn:", eq, NULL);
+#else
+ for (p = user, q=filtbuf + strlen(filtbuf);
+ *p && q < filtbuf_end; *q++ = *p++) {
+ if (strchr("*()\\", *p) != NULL) {
+ *q++ = '\\';
+ if (q >= filtbuf_end) {
+ break;
}
-
- apr_snprintf(filtbuf, FILTER_LENGTH, "%s(", filtbuf);
- cat_escape_dn_element(filtbuf, newdn);
- apr_snprintf(filtbuf, FILTER_LENGTH, "%s)", filtbuf);
- }
- }
- else {
- /*
- * Create the first part of the filter, which consists of the
- * config-supplied portions.
- */
- apr_snprintf(filtbuf, FILTER_LENGTH, "(&(%s)(%s=", filter, sec->attribute);
- cat_escape_dn_element(filtbuf, user);
+ }
}
- ldap_value_free (dnbuf);
+#endif
+ *q = '\0';
/*
* Append the closing parens of the filter, unless doing so would
* overrun the buffer.
*/
- apr_snprintf(filtbuf, FILTER_LENGTH, "%s))", filtbuf);
-
- ap_log_rerror(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r,
- "[%d] auth_ldap authenticate: using filter %s", getpid(), filtbuf);
+ if (q + 2 <= filtbuf_end)
+ strcat(filtbuf, "))");
}
static void *create_authnz_ldap_dir_config(apr_pool_t *p, char *d)
sec->deref = always;
sec->group_attrib_is_dn = 1;
sec->auth_authoritative = 1;
- sec->allow_fdn_auth = 0;
/*
sec->frontpage_hack = 0;
"Character set conversion configuration file. If omitted, character set"
"conversion is disabled."),
- AP_INIT_FLAG("AuthLDAPAllowDNAuth", ap_set_flag_slot,
- (void *)APR_OFFSETOF(authn_ldap_config_t, allow_fdn_auth), OR_AUTHCFG,
- "If set to 'on', auth_ldap allows the user to authenicate using a fully"
- "distinguished user name. Defaults to 'off'."),
-
{NULL}
};