/* 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.0.14Bemerkung:
(vorverarbeitet)
¤
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.