/* Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License.
*/
typedefstruct {
apr_pool_t *pool; /* Pool that this config is allocated from */ #if APR_HAS_THREADS
apr_thread_mutex_t *lock; /* Lock for this config */ #endif
/* These parameters are all derived from the AuthLDAPURL directive */ char *url; /* String representation of the URL */
char *host; /* Name of the LDAP server (or space separated list) */ int port; /* Port of the LDAP server */ char *basedn; /* Base DN to do all searches from */ char *attribute; /* Attribute to search for */ char **attributes; /* Array of all the attributes to return */ 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 bind_authoritative; /* If true, will return errors when bind fails */
int user_is_dn; /* If true, r->user is replaced by DN during authn */ char *remote_user_attribute; /* If set, r->user is replaced by this attribute during authn */ int compare_dn_on_server; /* If true, will use server to do DN compare */
int have_ldap_url; /* Set if we have found an LDAP url */
apr_array_header_t *groupattr; /* List of Group attributes identifying user members. Default:"member uniqueMember" */ int group_attrib_is_dn; /* If true, the group attribute is the DN, otherwise,
it's the exact string passed by the HTTP client */ char **sgAttributes; /* Array of strings constructed (post-config) from subgroupattrs. Last entry is NULL. */
apr_array_header_t *subgroupclasses; /* List of object classes of sub-groups. Default:"groupOfNames groupOfUniqueNames" */ int maxNestingDepth; /* Maximum recursive nesting depth permitted during subgroup processing. Default: 10 */
int secure; /* True if SSL connections are requested */ char *authz_prefix; /* Prefix for environment variables added during authz */ int initial_bind_as_user; /* true if we should try to bind (to lookup DN) directly with the basic auth username */
ap_regex_t *bind_regex; /* basic auth -> bind'able username regex */ constchar *bind_subst; /* basic auth -> bind'able username substitution */ int search_as_user; /* true if authz searches should be done with the users credentials (when we did authn) */ int compare_as_user; /* true if authz compares should be done with the users credentials (when we did authn) */
} authn_ldap_config_t;
typedefstruct { constchar *dn; /* The saved dn from a successful search */ constchar *user; /* The username provided by the client */ constchar **vals; /* The additional values pulled during the DN search*/ constchar *password; /* if this module successfully authenticates, the basic auth password, else null */
} authn_ldap_request_t;
/* * Test if language values like 'en-US' return a match from the charset * conversion map when shortened to 'en'.
*/ if (!charset && strlen(language) > 3 && language[2] == '-') { char *language_short = apr_pstrndup(p, language, 2);
charset = (char*) apr_hash_get(charset_conversions, language_short, APR_HASH_KEY_STRING);
}
if (charset) {
charset = apr_pstrdup(p, charset);
}
/* Convert the password to UTF-8. */ if (apr_xlate_conv_buffer(convset, sent_password, &inbytes, outbuf,
&outbytes) == APR_SUCCESS) return outbuf;
}
return sent_password;
}
/* * Build the search filter, or at least as much of the search filter that * will fit in the buffer, and return APR_EGENERAL if it won't fit, otherwise * APR_SUCCESS. * * The search filter consists of the filter provided with the URL, * combined with a filter made up of the attribute provided with the URL, * and the actual username passed by the HTTP client. For example, assume * that the LDAP URL is * * ldap://ldap.airius.com/ou=People, o=Airius?uid??(posixid=*) * * Further, assume that the userid passed by the client was `userj'. The * search filter will be (&(posixid=*)(uid=userj)).
*/ #define FILTER_LENGTH MAX_STRING_LEN static apr_status_t authn_ldap_build_filter(char filtbuf[FILTER_LENGTH],
request_rec *r, constchar *user, constchar *filter,
authn_ldap_config_t *sec)
{ char *q; constchar *p, *filtbuf_end;
apr_xlate_t *convset = NULL;
apr_size_t inbytes;
apr_size_t outbytes; char *outbuf; int nofilter = 0, len;
apr_status_t rv = APR_SUCCESS;
if (!filter) {
filter = sec->filter;
}
if (charset_conversions) {
convset = get_conv_set(r);
}
/* Convert the user name to UTF-8. This is only valid for LDAP v3 */ if (apr_xlate_conv_buffer(convset, user, &inbytes, outbuf, &outbytes) == APR_SUCCESS) {
user = outbuf;
}
}
/* * Create the first part of the filter, which consists of the * config-supplied portions.
*/
if ((nofilter = (!filter || !*filter || !strcasecmp(filter, "none")))) {
len = apr_snprintf(filtbuf, FILTER_LENGTH, "(%s=", sec->attribute);
} else {
len = apr_snprintf(filtbuf, FILTER_LENGTH, "(&(%s)(%s=", filter, sec->attribute);
}
/* * Now add the client-supplied username to the filter, ensuring that any * LDAP filter metachars are escaped.
*/
filtbuf_end = filtbuf + FILTER_LENGTH - 1; for (p = user, q = filtbuf + len; *p; ) { if (strchr("*()\\", *p) != NULL) { #if APR_HAS_MICROSOFT_LDAPSDK if (q + 3 >= filtbuf_end) { /* accounts for final \0 */
rv = APR_EGENERAL; goto out;
}
*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 if (q + 2 >= filtbuf_end) { /* accounts for final \0 */
rv = APR_EGENERAL; goto out;
}
*q++ = '\\';
*q++ = *p++; #endif
} else { if (q + 1 >= filtbuf_end) { /* accounts for final \0 */
rv = APR_EGENERAL; goto out;
}
*q++ = *p++;
}
}
/* * Append the closing parens of the filter, unless doing so would * overrun the buffer.
*/
if (nofilter) { if (q + 1 >= filtbuf_end) { /* accounts for final \0 */
rv = APR_EGENERAL; goto out;
}
*q++ = ')';
} else { if (q + 2 >= filtbuf_end) { /* accounts for final \0 */
rv = APR_EGENERAL; goto out;
}
*q++ = ')';
*q++ = ')';
}
/* Some LDAP servers restrict who can search or compare, and the hard-coded ID * might be good for the DN lookup but not for later operations.
*/ static util_ldap_connection_t *get_connection_for_authz(request_rec *r, enum auth_ldap_optype type) {
authn_ldap_request_t *req =
(authn_ldap_request_t *)ap_get_module_config(r->request_config, &authnz_ldap_module);
authn_ldap_config_t *sec =
(authn_ldap_config_t *)ap_get_module_config(r->per_dir_config, &authnz_ldap_module);
/* If the per-request config isn't set, we didn't authenticate this user, and leave the default credentials */ if (req && req->password &&
((type == LDAP_SEARCH && sec->search_as_user) ||
(type == LDAP_COMPARE && sec->compare_as_user) ||
(type == LDAP_COMPARE_AND_SEARCH && sec->compare_as_user && sec->search_as_user))){
binddn = req->dn;
bindpw = req->password;
}
return util_ldap_connection_find(r, sec->host, sec->port,
binddn, bindpw,
sec->deref, sec->secure);
} /* * Authentication Phase * -------------------- * * This phase authenticates the credentials the user has sent with * the request (ie the username and password are checked). This is done * by making an attempt to bind to the LDAP server using this user's * DN and the supplied password. *
*/ static authn_status authn_ldap_check_password(request_rec *r, constchar *user, constchar *password)
{ char filtbuf[FILTER_LENGTH];
authn_ldap_config_t *sec =
(authn_ldap_config_t *)ap_get_module_config(r->per_dir_config, &authnz_ldap_module);
util_ldap_connection_t *ldc = NULL; int result = 0; int remote_user_attribute_set = 0; constchar *dn = NULL; constchar *utfpassword;
/* if (!sec->enabled) { return AUTH_USER_NOT_FOUND; }
*/
/* * Basic sanity checks before any LDAP operations even happen.
*/ if (!sec->have_ldap_url) {
ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(02558) "no AuthLDAPURL");
return AUTH_GENERAL_ERROR;
}
/* Get the password that the client sent */ if (password == NULL) {
ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01692) "auth_ldap authenticate: no password specified"); return AUTH_GENERAL_ERROR;
}
if (user == NULL) {
ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01693) "auth_ldap authenticate: no user specified"); return AUTH_GENERAL_ERROR;
}
/* * A bind to the server with an empty password always succeeds, so * we check to ensure that the password is not empty. This implies * that users who actually do have empty passwords will never be * able to authenticate with this module. I don't see this as a big * problem.
*/ if (!(*password)) {
ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(10263) "auth_ldap authenticate: empty password specified"); return AUTH_DENIED;
}
/* There is a good AuthLDAPURL, right? */ if (sec->host) { constchar *binddn = sec->binddn; constchar *bindpw = sec->bindpw; if (sec->initial_bind_as_user) {
bindpw = password;
binddn = ldap_determine_binddn(r, user);
}
/* build the username filter */ if (APR_SUCCESS != authn_ldap_build_filter(filtbuf, r, user, NULL, sec)) {
ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02622) "auth_ldap authenticate: ldap filter too long (>%d): %s",
FILTER_LENGTH, filtbuf);
util_ldap_connection_close(ldc); return AUTH_GENERAL_ERROR;
}
ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r, "auth_ldap authenticate: final authn filter is %s", filtbuf);
/* convert password to utf-8 */
utfpassword = authn_ldap_xlate_password(r, password);
/* do the user search */
result = util_ldap_cache_checkuserid(r, ldc, sec->url, sec->basedn, sec->scope,
sec->attributes, filtbuf, utfpassword,
&dn, &(req->vals));
util_ldap_connection_close(ldc);
/* talking to a primitive LDAP server (like RACF-over-LDAP) that doesn't return specific errors */ if (!strcasecmp(sec->filter, "none") && LDAP_OTHER == result) { return AUTH_USER_NOT_FOUND;
}
return (LDAP_NO_SUCH_OBJECT == result) ? AUTH_USER_NOT_FOUND #ifdef LDAP_SECURITY_ERROR
: (LDAP_SECURITY_ERROR(result)) ? AUTH_DENIED #else
: (LDAP_INAPPROPRIATE_AUTH == result) ? AUTH_DENIED
: (LDAP_INVALID_CREDENTIALS == result) ? AUTH_DENIED #ifdef LDAP_INSUFFICIENT_ACCESS
: (LDAP_INSUFFICIENT_ACCESS == result) ? AUTH_DENIED #endif #ifdef LDAP_INSUFFICIENT_RIGHTS
: (LDAP_INSUFFICIENT_RIGHTS == result) ? AUTH_DENIED #endif #endif #ifdef LDAP_CONSTRAINT_VIOLATION /* At least Sun Directory Server sends this if a user is * locked. This is not covered by LDAP_SECURITY_ERROR.
*/
: (LDAP_CONSTRAINT_VIOLATION == result) ? AUTH_DENIED #endif
: AUTH_GENERAL_ERROR;
}
/* mark the user and DN */
req->dn = dn;
req->user = user;
req->password = password; if (sec->user_is_dn) {
r->user = (char *)req->dn;
}
/* sanity check */ if (sec->remote_user_attribute && !remote_user_attribute_set) {
ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(01696) "auth_ldap authenticate: " "REMOTE_USER was to be set with attribute '%s', " "but this attribute was not requested for in the " "LDAP query for the user. REMOTE_USER will fall " "back to username or DN as appropriate.",
sec->remote_user_attribute);
}
/* * If we have been authenticated by some other module than mod_authnz_ldap, * the req structure needed for authorization needs to be created * and populated with the userid and DN of the account in LDAP
*/
if (!strlen(r->user)) {
ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(01699) "ldap authorize: Userid is blank, AuthType=%s",
r->ap_auth_type);
}
/* Build the username filter */ if (APR_SUCCESS != authn_ldap_build_filter(filtbuf, r, r->user, NULL, sec)) {
ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02623) "auth_ldap authorize: ldap filter too long (>%d): %s",
FILTER_LENGTH, filtbuf); return AUTHZ_DENIED;
}
/* Search for the user DN */
result = util_ldap_cache_getuserdn(r, ldc, sec->url, sec->basedn,
sec->scope, sec->attributes, filtbuf, &dn, &(req->vals));
/* Search failed, log error and return failure */ if(result != LDAP_SUCCESS) {
ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01701) "auth_ldap authorise: User DN not found, %s", ldc->reason); return AUTHZ_DENIED;
}
if (sec->host) {
ldc = get_connection_for_authz(r, LDAP_COMPARE); /* for the top-level group only */
apr_pool_cleanup_register(r->pool, ldc,
authnz_ldap_cleanup_connection_close,
apr_pool_cleanup_null);
} else {
ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(01708) "auth_ldap authorize: no sec->host - weird...?"); return AUTHZ_DENIED;
}
/* * If there are no elements in the group attribute array, the default should be * member and uniquemember; populate the array now.
*/ if (sec->groupattr->nelts == 0) { struct mod_auth_ldap_groupattr_entry_t *grp; #if APR_HAS_THREADS
apr_thread_mutex_lock(sec->lock); #endif
grp = apr_array_push(sec->groupattr);
grp->name = "member";
grp = apr_array_push(sec->groupattr);
grp->name = "uniqueMember"; #if APR_HAS_THREADS
apr_thread_mutex_unlock(sec->lock); #endif
}
/* * If there are no elements in the sub group classes array, the default * should be groupOfNames and groupOfUniqueNames; populate the array now.
*/ if (sec->subgroupclasses->nelts == 0) { struct mod_auth_ldap_groupattr_entry_t *grp; #if APR_HAS_THREADS
apr_thread_mutex_lock(sec->lock); #endif
grp = apr_array_push(sec->subgroupclasses);
grp->name = "groupOfNames";
grp = apr_array_push(sec->subgroupclasses);
grp->name = "groupOfUniqueNames"; #if APR_HAS_THREADS
apr_thread_mutex_unlock(sec->lock); #endif
}
/* * If we have been authenticated by some other module than mod_auth_ldap, * the req structure needed for authorization needs to be created * and populated with the userid and DN of the account in LDAP
*/
if (!strlen(r->user)) {
ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(01709) "ldap authorize: Userid is blank, AuthType=%s",
r->ap_auth_type);
}
req = (authn_ldap_request_t *)apr_pcalloc(r->pool, sizeof(authn_ldap_request_t)); /* Build the username filter */ if (APR_SUCCESS != authn_ldap_build_filter(filtbuf, r, r->user, NULL, sec)) {
ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02624) "auth_ldap authorize: ldap filter too long (>%d): %s",
FILTER_LENGTH, filtbuf); return AUTHZ_DENIED;
}
/* Search for the user DN */
result = util_ldap_cache_getuserdn(r, ldc, sec->url, sec->basedn,
sec->scope, sec->attributes, filtbuf, &dn, &(req->vals));
/* Search failed, log error and return failure */ if(result != LDAP_SUCCESS) {
ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01711) "auth_ldap authorise: User DN not found, %s", ldc->reason); return AUTHZ_DENIED;
}
ent = (struct mod_auth_ldap_groupattr_entry_t *) sec->groupattr->elts;
if (sec->group_attrib_is_dn) { if (req->dn == NULL || strlen(req->dn) == 0) {
ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01712) "auth_ldap authorize: require group: user's DN has " "not been defined; failing authorization for user %s",
r->user); return AUTHZ_DENIED;
}
} else { if (req->user == NULL || strlen(req->user) == 0) { /* We weren't called in the authentication phase, so we didn't have a
* chance to set the user field. Do so now. */
req->user = r->user;
}
}
for (i = 0; i < sec->groupattr->nelts; i++) { /* nested groups need searches and compares, so grab a new handle */
authnz_ldap_cleanup_connection_close(ldc);
apr_pool_cleanup_kill(r->pool, ldc,authnz_ldap_cleanup_connection_close);
if (sec->host) {
ldc = get_connection_for_authz(r, LDAP_SEARCH); /* _comparedn is a searche */
apr_pool_cleanup_register(r->pool, ldc,
authnz_ldap_cleanup_connection_close,
apr_pool_cleanup_null);
} else {
ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(01721) "auth_ldap authorize: no sec->host - weird...?"); return AUTHZ_DENIED;
}
/* * If we have been authenticated by some other module than mod_auth_ldap, * the req structure needed for authorization needs to be created * and populated with the userid and DN of the account in LDAP
*/
if (!strlen(r->user)) {
ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(01722) "ldap authorize: Userid is blank, AuthType=%s",
r->ap_auth_type);
}
req = (authn_ldap_request_t *)apr_pcalloc(r->pool, sizeof(authn_ldap_request_t)); /* Build the username filter */ if (APR_SUCCESS != authn_ldap_build_filter(filtbuf, r, r->user, NULL, sec)) {
ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02625) "auth_ldap authorize: ldap filter too long (>%d): %s",
FILTER_LENGTH, filtbuf); return AUTHZ_DENIED;
}
/* Search for the user DN */
result = util_ldap_cache_getuserdn(r, ldc, sec->url, sec->basedn,
sec->scope, sec->attributes, filtbuf, &dn, &(req->vals));
/* Search failed, log error and return failure */ if(result != LDAP_SUCCESS) {
ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01724) "auth_ldap authorise: User DN not found with filter %s: %s", filtbuf, ldc->reason); return AUTHZ_DENIED;
}
/* * If we have been authenticated by some other module than mod_auth_ldap, * the req structure needed for authorization needs to be created * and populated with the userid and DN of the account in LDAP
*/
if (!strlen(r->user)) {
ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(01730) "ldap authorize: Userid is blank, AuthType=%s",
r->ap_auth_type);
}
req = (authn_ldap_request_t *)apr_pcalloc(r->pool, sizeof(authn_ldap_request_t)); /* Build the username filter */ if (APR_SUCCESS != authn_ldap_build_filter(filtbuf, r, r->user, NULL, sec)) {
ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02626) "auth_ldap authorize: ldap filter too long (>%d): %s",
FILTER_LENGTH, filtbuf); return AUTHZ_DENIED;
}
/* Search for the user DN */
result = util_ldap_cache_getuserdn(r, ldc, sec->url, sec->basedn,
sec->scope, sec->attributes, filtbuf, &dn, &(req->vals));
/* Search failed, log error and return failure */ if(result != LDAP_SUCCESS) {
ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01732) "auth_ldap authorise: User DN not found with filter %s: %s", filtbuf, ldc->reason); return AUTHZ_DENIED;
}
/* * If we have been authenticated by some other module than mod_auth_ldap, * the req structure needed for authorization needs to be created * and populated with the userid and DN of the account in LDAP
*/
if (!strlen(r->user)) {
ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(01739) "ldap authorize: Userid is blank, AuthType=%s",
r->ap_auth_type);
}
req = (authn_ldap_request_t *)apr_pcalloc(r->pool, sizeof(authn_ldap_request_t)); /* Build the username filter */ if (APR_SUCCESS != authn_ldap_build_filter(filtbuf, r, r->user, NULL, sec)) {
ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02627) "auth_ldap authorize: ldap filter too long (>%d): %s",
FILTER_LENGTH, filtbuf); return AUTHZ_DENIED;
}
/* Search for the user DN */
result = util_ldap_cache_getuserdn(r, ldc, sec->url, sec->basedn,
sec->scope, sec->attributes, filtbuf, &dn, &(req->vals));
/* Search failed, log error and return failure */ if(result != LDAP_SUCCESS) {
ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01741) "auth_ldap authorise: User DN not found with filter %s: %s", filtbuf, ldc->reason); return AUTHZ_DENIED;
}
/* Build the username filter */ if (APR_SUCCESS != authn_ldap_build_filter(filtbuf, r, req->user, t, sec)) {
ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02628) "auth_ldap authorize: ldap filter too long (>%d): %s",
FILTER_LENGTH, filtbuf); return AUTHZ_DENIED;
}
/* Search for the user DN */
result = util_ldap_cache_getuserdn(r, ldc, sec->url, sec->basedn,
sec->scope, sec->attributes, filtbuf, &dn, &(req->vals));
/* Make sure that the filtered search returned the correct user dn */ if (result == LDAP_SUCCESS) {
ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01744) "auth_ldap authorize: checking dn match %s", dn); if (sec->compare_as_user) { /* ldap-filter is the only authz that requires a search and a compare */
apr_pool_cleanup_kill(r->pool, ldc, authnz_ldap_cleanup_connection_close);
authnz_ldap_cleanup_connection_close(ldc);
ldc = get_connection_for_authz(r, LDAP_COMPARE);
}
result = util_ldap_cache_comparedn(r, ldc, sec->url, req->dn, dn,
sec->compare_dn_on_server);
}
if (expr_err) return apr_pstrcat(cmd->temp_pool, "Cannot parse expression in require line: ",
expr_err, NULL);
*parsed_require_line = expr;
return NULL;
}
/* * Use the ldap url parsing routines to break up the ldap url into * host and port.
*/ staticconstchar *mod_auth_ldap_parse_url(cmd_parms *cmd, void *config, constchar *url, constchar *mode)
{ int rc;
apr_ldap_url_desc_t *urld;
apr_ldap_err_t *result;
if (urld->lud_filter) { if (urld->lud_filter[0] == '(') { /* * Get rid of the surrounding parens; later on when generating the * filter, they'll be put back.
*/
sec->filter = apr_pstrmemdup(cmd->pool, urld->lud_filter+1,
strlen(urld->lud_filter)-2);
} else {
sec->filter = apr_pstrdup(cmd->pool, urld->lud_filter);
}
} else {
sec->filter = "objectclass=*";
}
if (mode) { if (0 == strcasecmp("NONE", mode)) {
sec->secure = APR_LDAP_NONE;
} elseif (0 == strcasecmp("SSL", mode)) {
sec->secure = APR_LDAP_SSL;
} elseif (0 == strcasecmp("TLS", mode) || 0 == strcasecmp("STARTTLS", mode)) {
sec->secure = APR_LDAP_STARTTLS;
} else { return"Invalid LDAP connection mode setting: must be one of NONE, " "SSL, or TLS/STARTTLS";
}
}
if ((arglen > 5) && strncmp(arg, "exec:", 5) == 0) { if (apr_tokenize_to_argv(arg+5, &argv, cmd->temp_pool) != APR_SUCCESS) { return apr_pstrcat(cmd->pool, "Unable to parse exec arguments from ",
arg+5, NULL);
}
argv[0] = ap_server_root_relative(cmd->temp_pool, argv[0]);
if (!argv[0]) { return apr_pstrcat(cmd->pool, "Invalid AuthLDAPBindPassword exec location:",
arg+5, NULL);
}
result = ap_get_exec_line(cmd->pool,
(constchar*)argv[0], (constchar * const *)argv);
if (!result) { return apr_pstrcat(cmd->pool, "Unable to get bind password from exec of ",
arg+5, NULL);
}
sec->bindpw = result;
} else {
sec->bindpw = (char *)arg;
}
if (!(*sec->bindpw)) { return"Empty passwords are invalid for AuthLDAPBindPassword";
}
return NULL;
}
staticconst command_rec authnz_ldap_cmds[] =
{
AP_INIT_TAKE12("AuthLDAPURL", mod_auth_ldap_parse_url, NULL, OR_AUTHCFG, "URL to define LDAP connection. This should be an RFC 2255 compliant\n" "URL of the form ldap://host[:port]/basedn[?attrib[?scope[?filter]]].\n" "
\n"
"
Host is the name of the LDAP server. Use a space separated list of hosts \n"
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.