2 * ITKACL module, (C) 2004-2011 Steinar H. Gunderson
5 #define MODAUTHITKACL_VERSION "0.4"
7 #include "apr_strings.h"
11 #include "http_config.h"
12 #include "http_core.h"
14 #include "http_protocol.h"
15 #include "http_request.h"
17 module AP_MODULE_DECLARE_DATA authz_itkacl_module;
19 extern int itkacl_check(const char * const realm, const char * const user,
20 char *errmsg, size_t errmsg_size);
24 } authz_itkacl_config_rec;
26 static void *authz_itkacl_dir_create_config(apr_pool_t *p, char *d)
28 authz_itkacl_config_rec *conf = apr_palloc(p, sizeof(*conf));
30 conf->authoritative = 1; /* keep the fortress secure by default */
34 static const command_rec authz_itkacl_cmds[] =
36 AP_INIT_FLAG("AuthzITKACLAuthoritative", ap_set_flag_slot,
37 (void *)APR_OFFSETOF(authz_itkacl_config_rec, authoritative),
39 "Set to 'Off' to allow access control to be passed along to "
40 "lower modules if the 'require user' or 'require valid-user' "
41 "statement is not met. (default: On)."),
45 static int fail(request_rec *r, authz_itkacl_config_rec *conf)
47 if (conf->authoritative) {
48 ap_note_auth_failure(r);
49 return HTTP_UNAUTHORIZED;
55 static int handle_require(request_rec *r, authz_itkacl_config_rec *conf, const char *username, const char *acl_path)
60 ret = itkacl_check(acl_path, username, errmsg, 1024);
66 ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
67 "error during itkacl check for %s on %s: %s",
68 username, acl_path, errmsg);
71 return HTTP_UNAUTHORIZED;
74 static int authz_itkacl_authorize_user(request_rec *r)
77 const apr_array_header_t *reqs_arr = ap_requires(r);
80 authz_itkacl_config_rec *conf = (authz_itkacl_config_rec *)
81 ap_get_module_config(r->per_dir_config, &authz_itkacl_module);
86 /* strip the domain part (FIXME: use the alias module instead?) */
87 username = strdup(r->user);
88 ptr = strchr(username, '@');
92 reqs = (require_line *)reqs_arr->elts;
93 for (i = 0; i < reqs_arr->nelts; ++i) {
96 if (!(reqs[i].method_mask & (AP_METHOD_BIT << (r->method_number))))
99 t = reqs[i].requirement;
100 w = ap_getword_white(r->pool, &t);
102 if (strcasecmp(w, "valid-user") == 0) {
107 if (strcasecmp(w, "itkacl") == 0) {
108 const char *acl_path;
110 acl_path = ap_getword_conf(r->pool, &t);
111 if (acl_path == NULL || strcmp(acl_path, "") == 0) {
112 ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
113 "'Require itkacl' needs an argument");
114 return fail(r, conf);
117 if (strcasecmp(acl_path, "anyof") == 0) {
118 int num_seen = 0, ret;
119 while ((acl_path = ap_getword_conf(r->pool, &t)) != NULL &&
120 strcmp(acl_path, "") != 0) {
121 ret = handle_require(r, conf, username, acl_path);
129 ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
130 "Missing arguments after 'Require itkacl anyof'");
131 } else if (ret == HTTP_UNAUTHORIZED) {
132 ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
133 "%s failed itkacl check for (multiple paths)",
140 /* check that there are no more arguments */
141 w = ap_getword_conf(r->pool, &t);
142 if (w != NULL && strcmp(w, "") != 0) {
143 ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
144 "Excess arguments ('%s') after Require itkacl %s; "
145 "did you mean 'Require itkacl anyof ...'?",
147 return fail(r, conf);
150 int ret = handle_require(r, conf, username, acl_path);
151 if (ret == HTTP_UNAUTHORIZED) {
152 ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
153 "%s failed itkacl check for %s",
167 static int authz_itkacl_init_handler(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp, server_rec *s)
169 ap_add_version_component(p, "mod_auth_itkacl/" MODAUTHITKACL_VERSION);
173 void authz_itkacl_register_hooks(apr_pool_t *p)
175 ap_hook_post_config(authz_itkacl_init_handler, NULL, NULL, APR_HOOK_MIDDLE);
176 ap_hook_auth_checker(authz_itkacl_authorize_user, NULL, NULL, APR_HOOK_MIDDLE);
179 module AP_MODULE_DECLARE_DATA authz_itkacl_module =
181 STANDARD20_MODULE_STUFF,
182 authz_itkacl_dir_create_config,
187 authz_itkacl_register_hooks