/* 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.
*/
#include"apr_strings.h" #include"apr_md5.h"/* for apr_password_validate */
if (!configured) { return OK; /* don't waste the overhead of creating mutex & cache */
} if (socache_provider == NULL) {
ap_log_perror(APLOG_MARK, APLOG_CRIT, 0, plog, APLOGNO(01674) "Please select a socache provider with AuthnCacheSOCache " "(no default found on this platform). Maybe you need to " "load mod_socache_shmcb or another socache module first"); return 500; /* An HTTP status would be a misnomer! */
}
/* We have socache_provider, but do not have socache_instance. This should * happen only when using "default" socache_provider, so create default
* socache_instance in this case. */ if (socache_instance == NULL) {
errmsg = socache_provider->create(&socache_instance, NULL,
ptmp, pconf); if (errmsg) {
ap_log_perror(APLOG_MARK, APLOG_CRIT, 0, plog, APLOGNO(02612) "failed to create mod_socache_shmcb socache " "instance: %s", errmsg); return 500;
}
}
rv = ap_global_mutex_create(&authn_cache_mutex, NULL,
authn_cache_id, NULL, s, pconf, 0); if (rv != APR_SUCCESS) {
ap_log_perror(APLOG_MARK, APLOG_CRIT, rv, plog, APLOGNO(01675) "failed to create %s mutex", authn_cache_id); return 500; /* An HTTP status would be a misnomer! */
}
apr_pool_cleanup_register(pconf, NULL, remove_lock, apr_pool_cleanup_null);
rv = socache_provider->init(socache_instance, authn_cache_id,
&authn_cache_hints, s, pconf); if (rv != APR_SUCCESS) {
ap_log_perror(APLOG_MARK, APLOG_CRIT, rv, plog, APLOGNO(01677) "failed to initialise %s cache", authn_cache_id); return 500; /* An HTTP status would be a misnomer! */
}
apr_pool_cleanup_register(pconf, (void*)s, destroy_cache, apr_pool_cleanup_null); return OK;
}
staticvoid authn_cache_child_init(apr_pool_t *p, server_rec *s)
{ constchar *lock;
apr_status_t rv; if (!configured) { return; /* don't waste the overhead of creating mutex & cache */
}
lock = apr_global_mutex_lockfile(authn_cache_mutex);
rv = apr_global_mutex_child_init(&authn_cache_mutex, lock, p); if (rv != APR_SUCCESS) {
ap_log_error(APLOG_MARK, APLOG_CRIT, rv, s, APLOGNO(01678) "failed to initialise mutex in child_init");
}
}
/* Argument is of form 'name:args' or just 'name'. */
sep = ap_strchr_c(arg, ':'); if (sep) {
name = apr_pstrmemdup(cmd->pool, arg, sep - arg);
sep++;
} else {
name = arg;
}
/* first check whether we're caching for this module */
dcfg = ap_get_module_config(r->per_dir_config, &authn_socache_module); if (!configured || !dcfg->providers) { return;
} if (!ap_array_str_contains(dcfg->providers, module)) { return;
}
/* OK, we're on. Grab mutex to do our business */
rv = apr_global_mutex_trylock(authn_cache_mutex); if (APR_STATUS_IS_EBUSY(rv)) { /* don't wait around; just abandon it */
ap_log_rerror(APLOG_MARK, APLOG_DEBUG, rv, r, APLOGNO(01679) "authn credentials for %s not cached (mutex busy)", user); return;
} elseif (rv != APR_SUCCESS) {
ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01680) "Failed to cache authn credentials for %s in %s",
module, dcfg->context); return;
}
/* We have the mutex, so go ahead */ /* first build our key and determine expiry time */
key = construct_key(r, dcfg->context, user, realm);
expiry = apr_time_now() + dcfg->timeout;
/* store it */
rv = socache_provider->store(socache_instance, r->server,
(unsignedchar*)key, strlen(key), expiry,
(unsignedchar*)data, strlen(data), r->pool); if (rv == APR_SUCCESS) {
ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01681) "Cached authn credentials for %s in %s",
user, dcfg->context);
} else {
ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01682) "Failed to cache authn credentials for %s in %s",
module, dcfg->context);
}
/* We're done with the mutex */
rv = apr_global_mutex_unlock(authn_cache_mutex); if (rv != APR_SUCCESS) {
ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01683) "Failed to release mutex!");
}
}
#define MAX_VAL_LEN 256 static authn_status check_password(request_rec *r, constchar *user, constchar *password)
{ /* construct key * look it up * if found, test password * * mutexing here would be a big performance drag. * It's definitely unnecessary with some backends (like ndbm or gdbm) * Is there a risk in the general case? I guess the only risk we * care about is a race condition that gets us a dangling pointer * to no-longer-defined memory. Hmmm ...
*/
apr_status_t rv; constchar *key;
authn_cache_dircfg *dcfg; unsignedchar val[MAX_VAL_LEN]; unsignedint vallen = MAX_VAL_LEN - 1;
dcfg = ap_get_module_config(r->per_dir_config, &authn_socache_module); if (!configured || !dcfg->providers) { return AUTH_USER_NOT_FOUND;
}
key = construct_key(r, dcfg->context, user, NULL);
rv = socache_provider->retrieve(socache_instance, r->server,
(unsignedchar*)key, strlen(key),
val, &vallen, r->pool);
if (APR_STATUS_IS_NOTFOUND(rv)) { /* not found - just return */
ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01684) "Authn cache: no credentials found for %s", user); return AUTH_USER_NOT_FOUND;
} elseif (rv == APR_SUCCESS) { /* OK, we got a value */
ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01685) "Authn cache: found credentials for %s", user);
val[vallen] = 0;
} else { /* error: give up and pass the buck */ /* FIXME: getting this for NOTFOUND - prolly a bug in mod_socache */
ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01686) "Error accessing authentication cache"); return AUTH_USER_NOT_FOUND;
}
if (APR_STATUS_IS_NOTFOUND(rv)) { /* not found - just return */
ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01687) "Authn cache: no credentials found for %s", user); return AUTH_USER_NOT_FOUND;
} elseif (rv == APR_SUCCESS) { /* OK, we got a value */
ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01688) "Authn cache: found credentials for %s", user);
} else { /* error: give up and pass the buck */ /* FIXME: getting this for NOTFOUND - prolly a bug in mod_socache */
ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01689) "Error accessing authentication cache"); return AUTH_USER_NOT_FOUND;
}
*rethash = apr_pstrmemdup(r->pool, (char *)val, vallen);
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.