]> granicus.if.org Git - apache/blob - modules/aaa/mod_authn_dbm.c
Fix a comment similar to r1638072
[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
31 #include "ap_provider.h"
32 #include "httpd.h"
33 #include "http_config.h"
34 #include "http_core.h"
35 #include "http_log.h"
36 #include "http_protocol.h"
37 #include "http_request.h"   /* for ap_hook_(check_user_id | auth_checker)*/
38
39 #include "mod_auth.h"
40
41 static APR_OPTIONAL_FN_TYPE(ap_authn_cache_store) *authn_cache_store = NULL;
42 #define AUTHN_CACHE_STORE(r,user,realm,data) \
43     if (authn_cache_store != NULL) \
44         authn_cache_store((r), "dbm", (user), (realm), (data))
45
46 typedef struct {
47     const char *pwfile;
48     const char *dbmtype;
49 } authn_dbm_config_rec;
50
51 static void *create_authn_dbm_dir_config(apr_pool_t *p, char *d)
52 {
53     authn_dbm_config_rec *conf = apr_palloc(p, sizeof(*conf));
54
55     conf->pwfile = NULL;
56     conf->dbmtype = "default";
57
58     return conf;
59 }
60
61 static const command_rec authn_dbm_cmds[] =
62 {
63     AP_INIT_TAKE1("AuthDBMUserFile", ap_set_file_slot,
64      (void *)APR_OFFSETOF(authn_dbm_config_rec, pwfile),
65      OR_AUTHCFG, "dbm database file containing user IDs and passwords"),
66     AP_INIT_TAKE1("AuthDBMType", ap_set_string_slot,
67      (void *)APR_OFFSETOF(authn_dbm_config_rec, dbmtype),
68      OR_AUTHCFG, "what type of DBM file the user file is"),
69     {NULL}
70 };
71
72 module AP_MODULE_DECLARE_DATA authn_dbm_module;
73
74 static apr_status_t fetch_dbm_value(const char *dbmtype, const char *dbmfile,
75                                     const char *user, char **value,
76                                     apr_pool_t *pool)
77 {
78     apr_dbm_t *f;
79     apr_datum_t key, val;
80     apr_status_t rv;
81
82     rv = apr_dbm_open_ex(&f, dbmtype, dbmfile, APR_DBM_READONLY,
83                          APR_OS_DEFAULT, pool);
84
85     if (rv != APR_SUCCESS) {
86         return rv;
87     }
88
89     key.dptr = (char*)user;
90 #ifndef NETSCAPE_DBM_COMPAT
91     key.dsize = strlen(key.dptr);
92 #else
93     key.dsize = strlen(key.dptr) + 1;
94 #endif
95
96     *value = NULL;
97
98     if (apr_dbm_fetch(f, key, &val) == APR_SUCCESS && val.dptr) {
99         *value = apr_pstrmemdup(pool, val.dptr, val.dsize);
100     }
101
102     apr_dbm_close(f);
103
104     return rv;
105 }
106
107 static authn_status check_dbm_pw(request_rec *r, const char *user,
108                                  const char *password)
109 {
110     authn_dbm_config_rec *conf = ap_get_module_config(r->per_dir_config,
111                                                       &authn_dbm_module);
112     apr_status_t rv;
113     char *dbm_password;
114     char *colon_pw;
115
116     rv = fetch_dbm_value(conf->dbmtype, conf->pwfile, user, &dbm_password,
117                          r->pool);
118
119     if (rv != APR_SUCCESS) {
120         ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01754)
121                       "could not open dbm (type %s) auth file: %s",
122                       conf->dbmtype, conf->pwfile);
123         return AUTH_GENERAL_ERROR;
124     }
125
126     if (!dbm_password) {
127         return AUTH_USER_NOT_FOUND;
128     }
129
130     colon_pw = ap_strchr(dbm_password, ':');
131     if (colon_pw) {
132         *colon_pw = '\0';
133     }
134     AUTHN_CACHE_STORE(r, user, NULL, dbm_password);
135
136     rv = ap_password_validate(r, user, password, dbm_password);
137
138     if (rv != APR_SUCCESS) {
139         return AUTH_DENIED;
140     }
141
142     return AUTH_GRANTED;
143 }
144
145 static authn_status get_dbm_realm_hash(request_rec *r, const char *user,
146                                        const char *realm, char **rethash)
147 {
148     authn_dbm_config_rec *conf = ap_get_module_config(r->per_dir_config,
149                                                       &authn_dbm_module);
150     apr_status_t rv;
151     char *dbm_hash;
152     char *colon_hash;
153
154     rv = fetch_dbm_value(conf->dbmtype, conf->pwfile,
155                          apr_pstrcat(r->pool, user, ":", realm, NULL),
156                          &dbm_hash, r->pool);
157
158     if (rv != APR_SUCCESS) {
159         ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01755)
160                       "Could not open dbm (type %s) hash file: %s",
161                       conf->dbmtype, conf->pwfile);
162         return AUTH_GENERAL_ERROR;
163     }
164
165     if (!dbm_hash) {
166         return AUTH_USER_NOT_FOUND;
167     }
168
169     colon_hash = ap_strchr(dbm_hash, ':');
170     if (colon_hash) {
171         *colon_hash = '\0';
172     }
173
174     *rethash = dbm_hash;
175     AUTHN_CACHE_STORE(r, user, realm, dbm_hash);
176
177     return AUTH_USER_FOUND;
178 }
179
180 static const authn_provider authn_dbm_provider =
181 {
182     &check_dbm_pw,
183     &get_dbm_realm_hash,
184 };
185
186 static void opt_retr(void)
187 {
188     authn_cache_store = APR_RETRIEVE_OPTIONAL_FN(ap_authn_cache_store);
189 }
190 static void register_hooks(apr_pool_t *p)
191 {
192     ap_register_auth_provider(p, AUTHN_PROVIDER_GROUP, "dbm",
193                               AUTHN_PROVIDER_VERSION,
194                               &authn_dbm_provider, AP_AUTH_INTERNAL_PER_CONF);
195     ap_hook_optional_fn_retrieve(opt_retr, NULL, NULL, APR_HOOK_MIDDLE);
196 }
197
198 AP_DECLARE_MODULE(authn_dbm) =
199 {
200     STANDARD20_MODULE_STUFF,
201     create_authn_dbm_dir_config, /* dir config creater */
202     NULL,                        /* dir merger --- default is to override */
203     NULL,                        /* server config */
204     NULL,                        /* merge server config */
205     authn_dbm_cmds,              /* command apr_table_t */
206     register_hooks               /* register hooks */
207 };