Main Page | Modules | Namespace List | Class List | Directories | File List | Class Members | File Members | Related Pages | Examples

mod_authn_dbm.c

Go to the documentation of this file.
00001 /* Licensed to the Apache Software Foundation (ASF) under one or more
00002  * contributor license agreements.  See the NOTICE file distributed with
00003  * this work for additional information regarding copyright ownership.
00004  * The ASF licenses this file to You under the Apache License, Version 2.0
00005  * (the "License"); you may not use this file except in compliance with
00006  * the License.  You may obtain a copy of the License at
00007  *
00008  *     http://www.apache.org/licenses/LICENSE-2.0
00009  *
00010  * Unless required by applicable law or agreed to in writing, software
00011  * distributed under the License is distributed on an "AS IS" BASIS,
00012  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00013  * See the License for the specific language governing permissions and
00014  * limitations under the License.
00015  */
00016 
00017 /*
00018  * http_auth: authentication
00019  *
00020  * Rob McCool & Brian Behlendorf.
00021  *
00022  * Adapted to Apache by rst.
00023  *
00024  */
00025 
00026 #define APR_WANT_STRFUNC
00027 #include "apr_want.h"
00028 #include "apr_strings.h"
00029 #include "apr_dbm.h"
00030 #include "apr_md5.h"        /* for apr_password_validate */
00031 
00032 #include "ap_provider.h"
00033 #include "httpd.h"
00034 #include "http_config.h"
00035 #include "http_core.h"
00036 #include "http_log.h"
00037 #include "http_protocol.h"
00038 #include "http_request.h"   /* for ap_hook_(check_user_id | auth_checker)*/
00039 
00040 #include "mod_auth.h"
00041 
00042 typedef struct {
00043     char *pwfile;
00044     char *dbmtype;
00045 } authn_dbm_config_rec;
00046 
00047 static void *create_authn_dbm_dir_config(apr_pool_t *p, char *d)
00048 {
00049     authn_dbm_config_rec *conf = apr_palloc(p, sizeof(*conf));
00050 
00051     conf->pwfile = NULL;
00052     conf->dbmtype = "default";
00053 
00054     return conf;
00055 }
00056 
00057 static const char *set_dbm_type(cmd_parms *cmd,
00058                                 void *dir_config,
00059                                 const char *arg)
00060 {
00061     authn_dbm_config_rec *conf = dir_config;
00062 
00063     conf->dbmtype = apr_pstrdup(cmd->pool, arg);
00064     return NULL;
00065 }
00066 
00067 static const command_rec authn_dbm_cmds[] =
00068 {
00069     AP_INIT_TAKE1("AuthDBMUserFile", ap_set_file_slot,
00070      (void *)APR_OFFSETOF(authn_dbm_config_rec, pwfile),
00071      OR_AUTHCFG, "dbm database file containing user IDs and passwords"),
00072     AP_INIT_TAKE1("AuthDBMType", set_dbm_type,
00073      NULL,
00074      OR_AUTHCFG, "what type of DBM file the user file is"),
00075     {NULL}
00076 };
00077 
00078 module AP_MODULE_DECLARE_DATA authn_dbm_module;
00079 
00080 static apr_status_t fetch_dbm_value(const char *dbmtype, const char *dbmfile,
00081                                     const char *user, char **value,
00082                                     apr_pool_t *pool)
00083 {
00084     apr_dbm_t *f;
00085     apr_datum_t key, val;
00086     apr_status_t rv;
00087 
00088     rv = apr_dbm_open_ex(&f, dbmtype, dbmfile, APR_DBM_READONLY,
00089                          APR_OS_DEFAULT, pool);
00090 
00091     if (rv != APR_SUCCESS) {
00092         return rv;
00093     }
00094 
00095     key.dptr = (char*)user;
00096 #ifndef NETSCAPE_DBM_COMPAT
00097     key.dsize = strlen(key.dptr);
00098 #else
00099     key.dsize = strlen(key.dptr) + 1;
00100 #endif
00101 
00102     *value = NULL;
00103 
00104     if (apr_dbm_fetch(f, key, &val) == APR_SUCCESS && val.dptr) {
00105         *value = apr_pstrmemdup(pool, val.dptr, val.dsize);
00106     }
00107 
00108     apr_dbm_close(f);
00109 
00110     return rv;
00111 }
00112 
00113 static authn_status check_dbm_pw(request_rec *r, const char *user,
00114                                  const char *password)
00115 {
00116     authn_dbm_config_rec *conf = ap_get_module_config(r->per_dir_config,
00117                                                       &authn_dbm_module);
00118     apr_status_t rv;
00119     char *dbm_password;
00120     char *colon_pw;
00121 
00122     rv = fetch_dbm_value(conf->dbmtype, conf->pwfile, user, &dbm_password,
00123                          r->pool);
00124 
00125     if (rv != APR_SUCCESS) {
00126         ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r,
00127                       "could not open dbm (type %s) auth file: %s",
00128                       conf->dbmtype, conf->pwfile);
00129         return AUTH_GENERAL_ERROR;
00130     }
00131 
00132     if (!dbm_password) {
00133         return AUTH_USER_NOT_FOUND;
00134     }
00135 
00136     colon_pw = ap_strchr(dbm_password, ':');
00137     if (colon_pw) {
00138         *colon_pw = '\0';
00139     }
00140 
00141     rv = apr_password_validate(password, dbm_password);
00142 
00143     if (rv != APR_SUCCESS) {
00144         return AUTH_DENIED;
00145     }
00146 
00147     return AUTH_GRANTED;
00148 }
00149 
00150 static authn_status get_dbm_realm_hash(request_rec *r, const char *user,
00151                                        const char *realm, char **rethash)
00152 {
00153     authn_dbm_config_rec *conf = ap_get_module_config(r->per_dir_config,
00154                                                       &authn_dbm_module);
00155     apr_status_t rv;
00156     char *dbm_hash;
00157     char *colon_hash;
00158 
00159     rv = fetch_dbm_value(conf->dbmtype, conf->pwfile,
00160                          apr_pstrcat(r->pool, user, ":", realm, NULL),
00161                          &dbm_hash, r->pool);
00162 
00163     if (rv != APR_SUCCESS) {
00164         ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r,
00165                       "Could not open dbm (type %s) hash file: %s",
00166                       conf->dbmtype, conf->pwfile);
00167         return AUTH_GENERAL_ERROR;
00168     }
00169 
00170     if (!dbm_hash) {
00171         return AUTH_USER_NOT_FOUND;
00172     }
00173 
00174     colon_hash = ap_strchr(dbm_hash, ':');
00175     if (colon_hash) {
00176         *colon_hash = '\0';
00177     }
00178 
00179     *rethash = dbm_hash;
00180 
00181     return AUTH_USER_FOUND;
00182 }
00183 
00184 static const authn_provider authn_dbm_provider =
00185 {
00186     &check_dbm_pw,
00187     &get_dbm_realm_hash
00188 };
00189 
00190 static void register_hooks(apr_pool_t *p)
00191 {
00192     ap_register_provider(p, AUTHN_PROVIDER_GROUP, "dbm", "0",
00193                          &authn_dbm_provider);
00194 }
00195 
00196 module AP_MODULE_DECLARE_DATA authn_dbm_module =
00197 {
00198     STANDARD20_MODULE_STUFF,
00199     create_authn_dbm_dir_config, /* dir config creater */
00200     NULL,                        /* dir merger --- default is to override */
00201     NULL,                        /* server config */
00202     NULL,                        /* merge server config */
00203     authn_dbm_cmds,              /* command apr_table_t */
00204     register_hooks               /* register hooks */
00205 };

© sourcejam.com 2005-2008