Apache HTTPD
mod_authz_dbm.c
Go to the documentation of this file.
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#define APR_WANT_STRFUNC
18#include "apr_want.h"
19#include "apr_strings.h"
20#include "apr_dbm.h"
21#include "apr_md5.h"
22
23#include "apr_version.h"
24#if !APR_VERSION_AT_LEAST(2,0,0)
25#include "apu_version.h"
26#endif
27
28#include "httpd.h"
29#include "http_config.h"
30#include "ap_provider.h"
31#include "http_core.h"
32#include "http_log.h"
33#include "http_protocol.h"
34#include "http_request.h" /* for ap_hook_(check_user_id | auth_checker)*/
35
36#include "mod_auth.h"
37#include "mod_authz_owner.h"
38
39typedef struct {
40 const char *grpfile;
41 const char *dbmtype;
43
44
45/* This should go into APR; perhaps with some nice
46 * caching/locking/flocking of the open dbm file.
47 */
49{
50 apr_datum_t d, q;
51 q.dptr = key;
52
53#ifndef NETSCAPE_DBM_COMPAT
54 q.dsize = strlen(q.dptr);
55#else
56 q.dsize = strlen(q.dptr) + 1;
57#endif
58
59 if (apr_dbm_fetch(f, q, &d) == APR_SUCCESS && d.dptr) {
60 return apr_pstrmemdup(pool, d.dptr, d.dsize);
61 }
62
63 return NULL;
64}
65
67{
68 authz_dbm_config_rec *conf = apr_palloc(p, sizeof(*conf));
69
70 conf->grpfile = NULL;
71 conf->dbmtype = "default";
72
73 return conf;
74}
75
77{
78 AP_INIT_TAKE1("AuthDBMGroupFile", ap_set_file_slot,
79 (void *)APR_OFFSETOF(authz_dbm_config_rec, grpfile),
80 OR_AUTHCFG, "database file containing group names and member user IDs"),
81 AP_INIT_TAKE1("AuthzDBMType", ap_set_string_slot,
82 (void *)APR_OFFSETOF(authz_dbm_config_rec, dbmtype),
83 OR_AUTHCFG, "what type of DBM file the group file is"),
84 {NULL}
85};
86
87module AP_MODULE_DECLARE_DATA authz_dbm_module;
88
89/* We do something strange with the group file. If the group file
90 * contains any : we assume the format is
91 * key=username value=":"groupname [":"anything here is ignored]
92 * otherwise we now (0.8.14+) assume that the format is
93 * key=username value=groupname
94 * The first allows the password and group files to be the same
95 * physical DBM file; key=username value=password":"groupname[":"anything]
96 *
97 * [email protected], 22Sep95
98 */
99
101 const char *dbmgrpfile, const char *dbtype,
102 const char ** out)
103{
104#if APU_MAJOR_VERSION > 1 || (APU_MAJOR_VERSION == 1 && APU_MINOR_VERSION >= 7)
106 const apu_err_t *err;
107#endif
108 char *grp_colon, *val;
110 apr_dbm_t *f;
111
112#if APU_MAJOR_VERSION > 1 || (APU_MAJOR_VERSION == 1 && APU_MINOR_VERSION >= 7)
114
115 if (retval != APR_SUCCESS) {
117 "could not load '%s' dbm library: %s",
118 err->reason, err->msg);
119 return retval;
120 }
121
124#else
127#endif
128
129 if (retval != APR_SUCCESS) {
131 "could not open dbm (type %s) group access "
132 "file: %s", dbtype, dbmgrpfile);
133 return retval;
134 }
135
136 /* Try key2 only if key1 failed */
137 if (!(val = get_dbm_entry_as_str(r->pool, f, key1))) {
139 }
140
142
143 if (val && (grp_colon = ap_strchr(val, ':')) != NULL) {
144 char *grp_colon2 = ap_strchr(++grp_colon, ':');
145
146 if (grp_colon2) {
147 *grp_colon2 = '\0';
148 }
149 *out = grp_colon;
150 }
151 else {
152 *out = val;
153 }
154
155 return retval;
156}
157
159 const char *require_args,
160 const void *parsed_require_args)
161{
163 &authz_dbm_module);
164 char *user = r->user;
165
166 const char *err = NULL;
168 const char *require;
169
170 const char *t;
171 char *w;
172 const char *orig_groups = NULL;
173 const char *realm = ap_auth_name(r);
174 const char *groups;
175 char *v;
176
177 if (!user) {
179 }
180
181 if (!conf->grpfile) {
183 "No group file was specified in the configuration");
184 return AUTHZ_DENIED;
185 }
186
187 /* fetch group data from dbm file only once. */
188 if (!orig_groups) {
190
191 status = get_dbm_grp(r, apr_pstrcat(r->pool, user, ":", realm, NULL),
192 user, conf->grpfile, conf->dbmtype, &groups);
193
194 if (status != APR_SUCCESS) {
195 return AUTHZ_GENERAL_ERROR;
196 }
197
198 if (groups == NULL) {
199 /* no groups available, so exit immediately */
201 "Authorization of user %s to access %s failed, reason: "
202 "user doesn't appear in DBM group file (%s).",
203 r->user, r->uri, conf->grpfile);
204 return AUTHZ_DENIED;
205 }
206
208 }
209
210 require = ap_expr_str_exec(r, expr, &err);
211 if (err) {
213 "authz_dbm authorize: require dbm-group: Can't "
214 "evaluate require expression: %s", err);
215 return AUTHZ_DENIED;
216 }
217
218 t = require;
219 while ((w = ap_getword_white(r->pool, &t)) && w[0]) {
221 while (groups[0]) {
222 v = ap_getword(r->pool, &groups, ',');
223 if (!strcmp(v, w)) {
224 return AUTHZ_GRANTED;
225 }
226 }
227 }
228
230 "Authorization of user %s to access %s failed, reason: "
231 "user is not part of the 'require'ed group(s).",
232 r->user, r->uri);
233
234 return AUTHZ_DENIED;
235}
236
238
240 const char *require_args,
241 const void *parsed_require_args)
242{
244 &authz_dbm_module);
245 char *user = r->user;
246 const char *realm = ap_auth_name(r);
247 const char *filegroup = NULL;
249 const char *groups;
250 char *v;
251
252 if (!user) {
254 }
255
256 if (!conf->grpfile) {
258 "No group file was specified in the configuration");
259 return AUTHZ_DENIED;
260 }
261
262 /* fetch group data from dbm file. */
263 status = get_dbm_grp(r, apr_pstrcat(r->pool, user, ":", realm, NULL),
264 user, conf->grpfile, conf->dbmtype, &groups);
265
266 if (status != APR_SUCCESS) {
267 return AUTHZ_DENIED;
268 }
269
270 if (groups == NULL) {
271 /* no groups available, so exit immediately */
273 "Authorization of user %s to access %s failed, reason: "
274 "user doesn't appear in DBM group file (%s).",
275 r->user, r->uri, conf->grpfile);
276 return AUTHZ_DENIED;
277 }
278
280
281 if (filegroup) {
282 while (groups[0]) {
283 v = ap_getword(r->pool, &groups, ',');
284 if (!strcmp(v, filegroup)) {
285 return AUTHZ_GRANTED;
286 }
287 }
288 }
289
291 "Authorization of user %s to access %s failed, reason: "
292 "user is not part of the 'require'ed group(s).",
293 r->user, r->uri);
294
295 return AUTHZ_DENIED;
296}
297
298static const char *dbm_parse_config(cmd_parms *cmd, const char *require_line,
299 const void **parsed_require_line)
300{
301 const char *expr_err = NULL;
302 ap_expr_info_t *expr;
303
305 &expr_err, NULL);
306
307 if (expr_err)
308 return apr_pstrcat(cmd->temp_pool,
309 "Cannot parse expression in require line: ",
310 expr_err, NULL);
311
312 *parsed_require_line = expr;
313
314 return NULL;
315}
316
322
328
333
346
348{
350 create_authz_dbm_dir_config, /* dir config creater */
351 NULL, /* dir merger --- default is to override */
352 NULL, /* server config */
353 NULL, /* merge server config */
354 authz_dbm_cmds, /* command apr_table_t */
355 register_hooks /* register hooks */
356};
Apache Provider API.
APR-UTIL DBM library.
APR MD5 Routines.
apr_size_t const unsigned char unsigned int unsigned int d
Definition apr_siphash.h:72
APR Strings library.
APR Versioning Interface.
APR Standard Headers Support.
APR-util Versioning Interface.
#define AP_INIT_TAKE1(directive, func, mconfig, where, help)
#define ap_get_module_config(v, m)
#define AP_DECLARE_MODULE(foo)
const char * ap_set_string_slot(cmd_parms *cmd, void *struct_ptr, const char *arg)
Definition config.c:1469
request_rec * r
void ap_hook_optional_fn_retrieve(ap_HOOK_optional_fn_retrieve_t *pf, const char *const *aszPre, const char *const *aszSucc, int nOrder)
Definition config.c:195
const char * ap_set_file_slot(cmd_parms *cmd, void *struct_ptr, const char *arg)
Definition config.c:1535
const char * ap_auth_name(request_rec *r)
Definition core.c:807
#define APLOGNO(n)
Definition http_log.h:117
#define ap_log_rerror
Definition http_log.h:454
#define APLOG_ERR
Definition http_log.h:67
#define APLOG_MARK
Definition http_log.h:283
apr_status_t ap_register_auth_provider(apr_pool_t *pool, const char *provider_group, const char *provider_name, const char *provider_version, const void *provider, int type)
Definition request.c:2179
#define AP_AUTH_INTERNAL_PER_CONF
apr_file_t * f
const char const apr_dbd_driver_t ** driver
Definition apr_dbd.h:106
#define APR_DBM_READONLY
Definition apr_dbm.h:56
#define APR_HOOK_MIDDLE
Definition apr_hooks.h:303
#define APR_RETRIEVE_OPTIONAL_FN(name)
#define APR_OPTIONAL_FN_TYPE(name)
#define AP_EXPR_FLAG_STRING_RESULT
Definition ap_expr.h:68
#define ap_expr_parse_cmd(cmd, expr, flags, err, lookup_fn)
Definition ap_expr.h:340
const char * ap_expr_str_exec(request_rec *r, const ap_expr_info_t *expr, const char **err)
#define OR_AUTHCFG
#define STANDARD20_MODULE_STUFF
#define ap_strchr(s, c)
Definition httpd.h:2351
char * ap_getword_white(apr_pool_t *p, const char **line)
Definition util.c:751
char * ap_getword(apr_pool_t *p, const char **line, char stop)
Definition util.c:723
apr_size_t size
apr_uint32_t val
Definition apr_atomic.h:66
const char int apr_pool_t * pool
Definition apr_cstr.h:84
#define APR_SUCCESS
Definition apr_errno.h:225
int apr_status_t
Definition apr_errno.h:44
const char * key
#define APR_OS_DEFAULT
apr_interval_time_t t
apr_int32_t apr_int32_t apr_int32_t err
apr_cmdtype_e cmd
int int status
Apache Configuration.
CORE HTTP Daemon.
Apache Logging library.
HTTP protocol handling.
Apache Request library.
HTTP Daemon routines.
apr_pool_t * p
Definition md_event.c:32
Authentication and Authorization Extension for Apache.
authz_status
Definition mod_auth.h:72
@ AUTHZ_DENIED
Definition mod_auth.h:73
@ AUTHZ_GENERAL_ERROR
Definition mod_auth.h:76
@ AUTHZ_DENIED_NO_USER
Definition mod_auth.h:77
@ AUTHZ_GRANTED
Definition mod_auth.h:74
#define AUTHZ_PROVIDER_VERSION
Definition mod_auth.h:42
#define AUTHZ_PROVIDER_GROUP
Definition mod_auth.h:40
static authz_status dbmgroup_check_authorization(request_rec *r, const char *require_args, const void *parsed_require_args)
static apr_status_t get_dbm_grp(request_rec *r, char *key1, char *key2, const char *dbmgrpfile, const char *dbtype, const char **out)
static apr_OFN_authz_owner_get_file_group_t * authz_owner_get_file_group
static const char * dbm_parse_config(cmd_parms *cmd, const char *require_line, const void **parsed_require_line)
static void authz_dbm_getfns(void)
static char * get_dbm_entry_as_str(apr_pool_t *pool, apr_dbm_t *f, char *key)
static const authz_provider authz_dbmgroup_provider
static void register_hooks(apr_pool_t *p)
static void * create_authz_dbm_dir_config(apr_pool_t *p, char *d)
static const command_rec authz_dbm_cmds[]
static authz_status dbmfilegroup_check_authorization(request_rec *r, const char *require_args, const void *parsed_require_args)
static const authz_provider authz_dbmfilegroup_provider
static apr_file_t * out
Definition mod_info.c:85
return NULL
Definition mod_so.c:359
apr_size_t dsize
Definition apr_dbm.h:52
char * dptr
Definition apr_dbm.h:50
A structure that represents the current request.
Definition httpd.h:845
char * user
Definition httpd.h:1005
char * uri
Definition httpd.h:1016
apr_pool_t * pool
Definition httpd.h:847
struct ap_conf_vector_t * per_dir_config
Definition httpd.h:1047
A structure to keep track of authorization requirements.
Definition http_core.h:316