51ec224c00438326eceb4f6c9e1f062abad6f252
[itkacl] / libapache2-mod-authz-itkacl-0.6 / mod_authz_itkacl.c
1 /*
2  * ITKACL module, (C) 2004-2015 Steinar H. Gunderson
3  */
4
5 #define MODAUTHITKACL_VERSION "0.6"
6
7 #include "apr_strings.h"
8
9 #include "ap_config.h"
10 #include "httpd.h"
11 #include "http_config.h"
12 #include "http_core.h"
13 #include "http_log.h"
14 #include "http_protocol.h"
15 #include "http_request.h"
16 #include "mod_auth.h"
17
18 module AP_MODULE_DECLARE_DATA authz_itkacl_module;
19
20 extern int itkacl_check(const char * const realm, const char * const user,
21                         char *errmsg, size_t errmsg_size);
22
23 static int handle_require(request_rec *r, const char *username, const char *acl_path)
24 {
25         char errmsg[1024];
26         int ret;
27
28         ret = itkacl_check(acl_path, username, errmsg, 1024);
29         if (ret == 0) {
30                 return AUTHZ_GRANTED;
31         }
32
33         if (ret == -1) {
34                 ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
35                         "error during itkacl check for %s on %s: %s",
36                         username, acl_path, errmsg);
37         }
38
39         return AUTHZ_DENIED;
40 }
41
42 static authz_status authz_itkacl_authorize_user(request_rec *r, const char *require_line, const void *parsed_require_line)
43 {
44         char *username, *ptr;
45         const char *t, *acl_path;
46
47         if (r->user == NULL) {
48                 return AUTHZ_DENIED_NO_USER;
49         }
50
51         /* strip the domain part (FIXME: use the alias module instead?) */
52         username = apr_pstrdup(r->pool, r->user);
53         ptr = strchr(username, '@');
54         if (ptr != NULL)
55                 ptr[0] = 0;
56
57         t = require_line;
58         acl_path = ap_getword_conf(r->pool, &t);
59         if (acl_path == NULL || strcmp(acl_path, "") == 0) {
60                 ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "'require itkacl' requires an argument");
61                 return AUTHZ_DENIED;
62         }
63
64         if (strcasecmp(acl_path, "anyof") == 0) {
65                 int num_seen = 0, ret;
66                 while ((acl_path = ap_getword_conf(r->pool, &t)) != NULL &&
67                        strcmp(acl_path, "") != 0) {
68                         ret = handle_require(r, username, acl_path);
69                         if (ret == AUTHZ_GRANTED) {
70                                 return ret;
71                         }
72                         ++num_seen;
73                 }
74                 if (num_seen == 0) {
75                         ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
76                                 "Missing arguments after 'Require itkacl anyof'");
77                         return AUTHZ_DENIED;
78                 } else if (ret == HTTP_UNAUTHORIZED) {
79                         ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
80                                 "%s failed itkacl check for (multiple paths)",
81                                 username);
82                         return AUTHZ_DENIED;
83                 }
84                 return ret;
85         } else {
86                 /* check that there are no more arguments */
87                 const char *w = ap_getword_conf(r->pool, &t);
88                 if (w != NULL && strcmp(w, "") != 0) {
89                         ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
90                                 "Excess arguments ('%s') after Require itkacl %s; "
91                                 "did you mean 'Require itkacl anyof ...'?",
92                                 w, acl_path);
93                         return AUTHZ_DENIED;
94                 }
95
96                 int ret = handle_require(r, username, acl_path);
97                 if (ret == AUTHZ_DENIED) {
98                         ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
99                             "%s failed itkacl check for %s",
100                             username, acl_path);
101                         return AUTHZ_DENIED;
102                 }
103                 return ret;
104         }
105 }
106
107 static int authz_itkacl_init_handler(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp, server_rec *s)
108 {
109         ap_add_version_component(p, "mod_auth_itkacl/" MODAUTHITKACL_VERSION);
110         return OK;
111 }
112
113 static const authz_provider authz_itkacl_provider =
114 {
115         &authz_itkacl_authorize_user,
116         NULL,
117 };
118
119 void authz_itkacl_register_hooks(apr_pool_t *p)
120 {
121         ap_hook_post_config(authz_itkacl_init_handler, NULL, NULL, APR_HOOK_MIDDLE);
122         ap_register_auth_provider(p, AUTHZ_PROVIDER_GROUP, "itkacl", AUTHZ_PROVIDER_VERSION, &authz_itkacl_provider, AP_AUTH_INTERNAL_PER_CONF);
123 }
124
125 module AP_MODULE_DECLARE_DATA authz_itkacl_module =
126 {
127         STANDARD20_MODULE_STUFF,
128         NULL,
129         NULL,
130         NULL,
131         NULL,
132         NULL,
133         authz_itkacl_register_hooks
134 };