]> granicus.if.org Git - apache/blob - modules/aaa/mod_authn_dbm.c
9221752fa2148c624cbbeb9eb5848c6d3c47c988
[apache] / modules / aaa / mod_authn_dbm.c
1 /* Licensed to the Apache Software Foundation (ASF) under one or more
2  * contributor license agreements.  See the NOTICE file distributed with
3  * this work for additional information regarding copyright ownership.
4  * The ASF licenses this file to You under the Apache License, Version 2.0
5  * (the "License"); you may not use this file except in compliance with
6  * the License.  You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 /*
18  * http_auth: authentication
19  *
20  * Rob McCool & Brian Behlendorf.
21  *
22  * Adapted to Apache by rst.
23  *
24  */
25
26 #define APR_WANT_STRFUNC
27 #include "apr_want.h"
28 #include "apr_strings.h"
29 #include "apr_dbm.h"
30 #include "apr_md5.h"        /* for apr_password_validate */
31
32 #include "ap_provider.h"
33 #include "httpd.h"
34 #include "http_config.h"
35 #include "http_core.h"
36 #include "http_log.h"
37 #include "http_protocol.h"
38 #include "http_request.h"   /* for ap_hook_(check_user_id | auth_checker)*/
39
40 #include "mod_auth.h"
41
42 typedef struct {
43     char *pwfile;
44     char *dbmtype;
45 } authn_dbm_config_rec;
46
47 static void *create_authn_dbm_dir_config(apr_pool_t *p, char *d)
48 {
49     authn_dbm_config_rec *conf = apr_palloc(p, sizeof(*conf));
50
51     conf->pwfile = NULL;
52     conf->dbmtype = "default";
53
54     return conf;
55 }
56
57 static const char *set_dbm_type(cmd_parms *cmd,
58                                 void *dir_config,
59                                 const char *arg)
60 {
61     authn_dbm_config_rec *conf = dir_config;
62
63     conf->dbmtype = apr_pstrdup(cmd->pool, arg);
64     return NULL;
65 }
66
67 static const command_rec authn_dbm_cmds[] =
68 {
69     AP_INIT_TAKE1("AuthDBMUserFile", ap_set_file_slot,
70      (void *)APR_OFFSETOF(authn_dbm_config_rec, pwfile),
71      OR_AUTHCFG, "dbm database file containing user IDs and passwords"),
72     AP_INIT_TAKE1("AuthDBMType", set_dbm_type,
73      NULL,
74      OR_AUTHCFG, "what type of DBM file the user file is"),
75     {NULL}
76 };
77
78 module AP_MODULE_DECLARE_DATA authn_dbm_module;
79
80 static apr_status_t fetch_dbm_value(const char *dbmtype, const char *dbmfile,
81                                     const char *user, char **value,
82                                     apr_pool_t *pool)
83 {
84     apr_dbm_t *f;
85     apr_datum_t key, val;
86     apr_status_t rv;
87
88     rv = apr_dbm_open_ex(&f, dbmtype, dbmfile, APR_DBM_READONLY,
89                          APR_OS_DEFAULT, pool);
90
91     if (rv != APR_SUCCESS) {
92         return rv;
93     }
94
95     key.dptr = (char*)user;
96 #ifndef NETSCAPE_DBM_COMPAT
97     key.dsize = strlen(key.dptr);
98 #else
99     key.dsize = strlen(key.dptr) + 1;
100 #endif
101
102     *value = NULL;
103
104     if (apr_dbm_fetch(f, key, &val) == APR_SUCCESS && val.dptr) {
105         *value = apr_pstrmemdup(pool, val.dptr, val.dsize);
106     }
107
108     apr_dbm_close(f);
109
110     return rv;
111 }
112
113 static authn_status check_dbm_pw(request_rec *r, const char *user,
114                                  const char *password)
115 {
116     authn_dbm_config_rec *conf = ap_get_module_config(r->per_dir_config,
117                                                       &authn_dbm_module);
118     apr_status_t rv;
119     char *dbm_password;
120     char *colon_pw;
121
122     rv = fetch_dbm_value(conf->dbmtype, conf->pwfile, user, &dbm_password,
123                          r->pool);
124
125     if (rv != APR_SUCCESS) {
126         ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r,
127                       "could not open dbm (type %s) auth file: %s",
128                       conf->dbmtype, conf->pwfile);
129         return AUTH_GENERAL_ERROR;
130     }
131
132     if (!dbm_password) {
133         return AUTH_USER_NOT_FOUND;
134     }
135
136     colon_pw = ap_strchr(dbm_password, ':');
137     if (colon_pw) {
138         *colon_pw = '\0';
139     }
140
141     rv = apr_password_validate(password, dbm_password);
142
143     if (rv != APR_SUCCESS) {
144         return AUTH_DENIED;
145     }
146
147     return AUTH_GRANTED;
148 }
149
150 static authn_status get_dbm_realm_hash(request_rec *r, const char *user,
151                                        const char *realm, char **rethash)
152 {
153     authn_dbm_config_rec *conf = ap_get_module_config(r->per_dir_config,
154                                                       &authn_dbm_module);
155     apr_status_t rv;
156     char *dbm_hash;
157     char *colon_hash;
158
159     rv = fetch_dbm_value(conf->dbmtype, conf->pwfile,
160                          apr_pstrcat(r->pool, user, ":", realm, NULL),
161                          &dbm_hash, r->pool);
162
163     if (rv != APR_SUCCESS) {
164         ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r,
165                       "Could not open dbm (type %s) hash file: %s",
166                       conf->dbmtype, conf->pwfile);
167         return AUTH_GENERAL_ERROR;
168     }
169
170     if (!dbm_hash) {
171         return AUTH_USER_NOT_FOUND;
172     }
173
174     colon_hash = ap_strchr(dbm_hash, ':');
175     if (colon_hash) {
176         *colon_hash = '\0';
177     }
178
179     *rethash = dbm_hash;
180
181     return AUTH_USER_FOUND;
182 }
183
184 static const authn_provider authn_dbm_provider =
185 {
186     &check_dbm_pw,
187     &get_dbm_realm_hash
188 };
189
190 static void register_hooks(apr_pool_t *p)
191 {
192     ap_register_provider(p, AUTHN_PROVIDER_GROUP, "dbm", "0",
193                          &authn_dbm_provider);
194 }
195
196 module AP_MODULE_DECLARE_DATA authn_dbm_module =
197 {
198     STANDARD20_MODULE_STUFF,
199     create_authn_dbm_dir_config, /* dir config creater */
200     NULL,                        /* dir merger --- default is to override */
201     NULL,                        /* server config */
202     NULL,                        /* merge server config */
203     authn_dbm_cmds,              /* command apr_table_t */
204     register_hooks               /* register hooks */
205 };