mod_authn_dbm.c revision 724ddc1dd163506ec738717f761ca3f09f9bb5fe
a78048ccbdb6256da15e6b0e7e95355e480c2301nd/* Copyright 2002-2004 Apache Software Foundation
a78048ccbdb6256da15e6b0e7e95355e480c2301nd *
fd9abdda70912b99b24e3bf1a38f26fde908a74cnd * Licensed under the Apache License, Version 2.0 (the "License");
fd9abdda70912b99b24e3bf1a38f26fde908a74cnd * you may not use this file except in compliance with the License.
fd9abdda70912b99b24e3bf1a38f26fde908a74cnd * You may obtain a copy of the License at
a78048ccbdb6256da15e6b0e7e95355e480c2301nd *
a78048ccbdb6256da15e6b0e7e95355e480c2301nd * http://www.apache.org/licenses/LICENSE-2.0
a78048ccbdb6256da15e6b0e7e95355e480c2301nd *
a78048ccbdb6256da15e6b0e7e95355e480c2301nd * Unless required by applicable law or agreed to in writing, software
96ad5d81ee4a2cc66a4ae19893efc8aa6d06fae7jailletc * distributed under the License is distributed on an "AS IS" BASIS,
a78048ccbdb6256da15e6b0e7e95355e480c2301nd * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
a78048ccbdb6256da15e6b0e7e95355e480c2301nd * See the License for the specific language governing permissions and
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen * limitations under the License.
2e545ce2450a9953665f701bb05350f0d3f26275nd */
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen/*
a78048ccbdb6256da15e6b0e7e95355e480c2301nd * http_auth: authentication
a78048ccbdb6256da15e6b0e7e95355e480c2301nd *
af33a4994ae2ff15bc67d19ff1a7feb906745bf8rbowen * Rob McCool & Brian Behlendorf.
3f08db06526d6901aa08c110b5bc7dde6bc39905nd *
a78048ccbdb6256da15e6b0e7e95355e480c2301nd * Adapted to Apache by rst.
a78048ccbdb6256da15e6b0e7e95355e480c2301nd *
a78048ccbdb6256da15e6b0e7e95355e480c2301nd */
3f08db06526d6901aa08c110b5bc7dde6bc39905nd
a78048ccbdb6256da15e6b0e7e95355e480c2301nd#define APR_WANT_STRFUNC
a78048ccbdb6256da15e6b0e7e95355e480c2301nd#include "apr_want.h"
f086b4b402fa9a2fefc7dda85de2a3cc1cd0a654rjung#include "apr_strings.h"
a78048ccbdb6256da15e6b0e7e95355e480c2301nd#include "apr_dbm.h"
4b575a6b6704b516f22d65a3ad35696d7b9ba372rpluem#include "apr_md5.h" /* for apr_password_validate */
4b575a6b6704b516f22d65a3ad35696d7b9ba372rpluem
a78048ccbdb6256da15e6b0e7e95355e480c2301nd#include "ap_provider.h"
a78048ccbdb6256da15e6b0e7e95355e480c2301nd#include "httpd.h"
4aa603e6448b99f9371397d439795c91a93637eand#include "http_config.h"
a78048ccbdb6256da15e6b0e7e95355e480c2301nd#include "http_core.h"
a78048ccbdb6256da15e6b0e7e95355e480c2301nd#include "http_log.h"
a78048ccbdb6256da15e6b0e7e95355e480c2301nd#include "http_protocol.h"
4aa603e6448b99f9371397d439795c91a93637eand#include "http_request.h" /* for ap_hook_(check_user_id | auth_checker)*/
a78048ccbdb6256da15e6b0e7e95355e480c2301nd
a78048ccbdb6256da15e6b0e7e95355e480c2301nd#include "mod_auth.h"
a78048ccbdb6256da15e6b0e7e95355e480c2301nd
a78048ccbdb6256da15e6b0e7e95355e480c2301ndtypedef struct {
a78048ccbdb6256da15e6b0e7e95355e480c2301nd char *pwfile;
a78048ccbdb6256da15e6b0e7e95355e480c2301nd char *dbmtype;
a78048ccbdb6256da15e6b0e7e95355e480c2301nd} authn_dbm_config_rec;
a78048ccbdb6256da15e6b0e7e95355e480c2301nd
a78048ccbdb6256da15e6b0e7e95355e480c2301ndstatic void *create_authn_dbm_dir_config(apr_pool_t *p, char *d)
a78048ccbdb6256da15e6b0e7e95355e480c2301nd{
a78048ccbdb6256da15e6b0e7e95355e480c2301nd authn_dbm_config_rec *conf = apr_palloc(p, sizeof(*conf));
a78048ccbdb6256da15e6b0e7e95355e480c2301nd
a78048ccbdb6256da15e6b0e7e95355e480c2301nd conf->pwfile = NULL;
a78048ccbdb6256da15e6b0e7e95355e480c2301nd conf->dbmtype = "default";
a78048ccbdb6256da15e6b0e7e95355e480c2301nd
a78048ccbdb6256da15e6b0e7e95355e480c2301nd return conf;
a78048ccbdb6256da15e6b0e7e95355e480c2301nd}
a78048ccbdb6256da15e6b0e7e95355e480c2301nd
a78048ccbdb6256da15e6b0e7e95355e480c2301ndstatic const char *set_dbm_type(cmd_parms *cmd,
a78048ccbdb6256da15e6b0e7e95355e480c2301nd void *dir_config,
a78048ccbdb6256da15e6b0e7e95355e480c2301nd const char *arg)
a78048ccbdb6256da15e6b0e7e95355e480c2301nd{
a78048ccbdb6256da15e6b0e7e95355e480c2301nd authn_dbm_config_rec *conf = dir_config;
a78048ccbdb6256da15e6b0e7e95355e480c2301nd
a78048ccbdb6256da15e6b0e7e95355e480c2301nd conf->dbmtype = apr_pstrdup(cmd->pool, arg);
a78048ccbdb6256da15e6b0e7e95355e480c2301nd return NULL;
a78048ccbdb6256da15e6b0e7e95355e480c2301nd}
a78048ccbdb6256da15e6b0e7e95355e480c2301nd
a78048ccbdb6256da15e6b0e7e95355e480c2301ndstatic const command_rec authn_dbm_cmds[] =
a78048ccbdb6256da15e6b0e7e95355e480c2301nd{
a78048ccbdb6256da15e6b0e7e95355e480c2301nd AP_INIT_TAKE1("AuthDBMUserFile", ap_set_file_slot,
a78048ccbdb6256da15e6b0e7e95355e480c2301nd (void *)APR_OFFSETOF(authn_dbm_config_rec, pwfile),
a78048ccbdb6256da15e6b0e7e95355e480c2301nd OR_AUTHCFG, "dbm database file containing user IDs and passwords"),
a78048ccbdb6256da15e6b0e7e95355e480c2301nd AP_INIT_TAKE1("AuthDBMType", set_dbm_type,
a78048ccbdb6256da15e6b0e7e95355e480c2301nd NULL,
a78048ccbdb6256da15e6b0e7e95355e480c2301nd OR_AUTHCFG, "what type of DBM file the user file is"),
a78048ccbdb6256da15e6b0e7e95355e480c2301nd {NULL}
a78048ccbdb6256da15e6b0e7e95355e480c2301nd};
a78048ccbdb6256da15e6b0e7e95355e480c2301nd
a78048ccbdb6256da15e6b0e7e95355e480c2301ndmodule AP_MODULE_DECLARE_DATA authn_dbm_module;
a78048ccbdb6256da15e6b0e7e95355e480c2301nd
a78048ccbdb6256da15e6b0e7e95355e480c2301ndstatic apr_status_t fetch_dbm_value(const char *dbmtype, const char *dbmfile,
a78048ccbdb6256da15e6b0e7e95355e480c2301nd const char *user, char **value,
a78048ccbdb6256da15e6b0e7e95355e480c2301nd apr_pool_t *pool)
a78048ccbdb6256da15e6b0e7e95355e480c2301nd{
a78048ccbdb6256da15e6b0e7e95355e480c2301nd apr_dbm_t *f;
a78048ccbdb6256da15e6b0e7e95355e480c2301nd apr_datum_t key, val;
a78048ccbdb6256da15e6b0e7e95355e480c2301nd apr_status_t rv;
a78048ccbdb6256da15e6b0e7e95355e480c2301nd
a78048ccbdb6256da15e6b0e7e95355e480c2301nd rv = apr_dbm_open_ex(&f, dbmtype, dbmfile, APR_DBM_READONLY,
a78048ccbdb6256da15e6b0e7e95355e480c2301nd APR_OS_DEFAULT, pool);
a78048ccbdb6256da15e6b0e7e95355e480c2301nd
a78048ccbdb6256da15e6b0e7e95355e480c2301nd if (rv != APR_SUCCESS) {
a78048ccbdb6256da15e6b0e7e95355e480c2301nd return rv;
a78048ccbdb6256da15e6b0e7e95355e480c2301nd }
a78048ccbdb6256da15e6b0e7e95355e480c2301nd
a78048ccbdb6256da15e6b0e7e95355e480c2301nd key.dptr = (char*)user;
a78048ccbdb6256da15e6b0e7e95355e480c2301nd#ifndef NETSCAPE_DBM_COMPAT
a78048ccbdb6256da15e6b0e7e95355e480c2301nd key.dsize = strlen(key.dptr);
a78048ccbdb6256da15e6b0e7e95355e480c2301nd#else
a78048ccbdb6256da15e6b0e7e95355e480c2301nd key.dsize = strlen(key.dptr) + 1;
a78048ccbdb6256da15e6b0e7e95355e480c2301nd#endif
a78048ccbdb6256da15e6b0e7e95355e480c2301nd
f086b4b402fa9a2fefc7dda85de2a3cc1cd0a654rjung *value = NULL;
727872d18412fc021f03969b8641810d8896820bhumbedooh
0d0ba3a410038e179b695446bb149cce6264e0abnd if (apr_dbm_fetch(f, key, &val) == APR_SUCCESS && val.dptr) {
727872d18412fc021f03969b8641810d8896820bhumbedooh *value = apr_pstrmemdup(pool, val.dptr, val.dsize);
cc7e1025de9ac63bd4db6fe7f71c158b2cf09fe4humbedooh }
0d0ba3a410038e179b695446bb149cce6264e0abnd
cc7e1025de9ac63bd4db6fe7f71c158b2cf09fe4humbedooh apr_dbm_close(f);
727872d18412fc021f03969b8641810d8896820bhumbedooh
0d0ba3a410038e179b695446bb149cce6264e0abnd return rv;
0d0ba3a410038e179b695446bb149cce6264e0abnd}
0d0ba3a410038e179b695446bb149cce6264e0abnd
ac082aefa89416cbdc9a1836eaf3bed9698201c8humbedoohstatic authn_status check_dbm_pw(request_rec *r, const char *user,
0d0ba3a410038e179b695446bb149cce6264e0abnd const char *password)
0d0ba3a410038e179b695446bb149cce6264e0abnd{
0d0ba3a410038e179b695446bb149cce6264e0abnd authn_dbm_config_rec *conf = ap_get_module_config(r->per_dir_config,
727872d18412fc021f03969b8641810d8896820bhumbedooh &authn_dbm_module);
0d0ba3a410038e179b695446bb149cce6264e0abnd apr_status_t rv;
0d0ba3a410038e179b695446bb149cce6264e0abnd char *dbm_password;
30471a4650391f57975f60bbb6e4a90be7b284bfhumbedooh char *colon_pw;
205f749042ed530040a4f0080dbcb47ceae8a374rjung
af33a4994ae2ff15bc67d19ff1a7feb906745bf8rbowen rv = fetch_dbm_value(conf->dbmtype, conf->pwfile, user, &dbm_password,
0d0ba3a410038e179b695446bb149cce6264e0abnd r->pool);
7fec19672a491661b2fe4b29f685bc7f4efa64d4nd
7fec19672a491661b2fe4b29f685bc7f4efa64d4nd if (rv != APR_SUCCESS) {
7fec19672a491661b2fe4b29f685bc7f4efa64d4nd ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r,
a78048ccbdb6256da15e6b0e7e95355e480c2301nd "could not open dbm (type %s) auth file: %s",
conf->dbmtype, conf->pwfile);
return AUTH_GENERAL_ERROR;
}
if (!dbm_password) {
return AUTH_USER_NOT_FOUND;
}
colon_pw = ap_strchr(dbm_password, ':');
if (colon_pw) {
*colon_pw = '\0';
}
rv = apr_password_validate(password, dbm_password);
if (rv != APR_SUCCESS) {
return AUTH_DENIED;
}
return AUTH_GRANTED;
}
static authn_status get_dbm_realm_hash(request_rec *r, const char *user,
const char *realm, char **rethash)
{
authn_dbm_config_rec *conf = ap_get_module_config(r->per_dir_config,
&authn_dbm_module);
apr_status_t rv;
char *dbm_hash;
char *colon_hash;
rv = fetch_dbm_value(conf->dbmtype, conf->pwfile,
apr_pstrcat(r->pool, user, ":", realm, NULL),
&dbm_hash, r->pool);
if (rv != APR_SUCCESS) {
ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r,
"Could not open dbm (type %s) hash file: %s",
conf->dbmtype, conf->pwfile);
return AUTH_GENERAL_ERROR;
}
if (!dbm_hash) {
return AUTH_USER_NOT_FOUND;
}
colon_hash = ap_strchr(dbm_hash, ':');
if (colon_hash) {
*colon_hash = '\0';
}
*rethash = dbm_hash;
return AUTH_USER_FOUND;
}
static const authn_provider authn_dbm_provider =
{
&check_dbm_pw,
&get_dbm_realm_hash
};
static void register_hooks(apr_pool_t *p)
{
ap_register_provider(p, AUTHN_PROVIDER_GROUP, "dbm", "0",
&authn_dbm_provider);
}
module AP_MODULE_DECLARE_DATA authn_dbm_module =
{
STANDARD20_MODULE_STUFF,
create_authn_dbm_dir_config, /* dir config creater */
NULL, /* dir merger --- default is to override */
NULL, /* server config */
NULL, /* merge server config */
authn_dbm_cmds, /* command apr_table_t */
register_hooks /* register hooks */
};