source: server/common/oursrc/httpdmods/mod_authz_afsgroup.c @ 56

Last change on this file since 56 was 56, checked in by jbarnold, 16 years ago
created package for apache modules
File size: 4.3 KB
Line 
1/* mod_authz_afsgroup
2 * version 1.0, released 2006-01-04
3 * Anders Kaseorg <anders@kaseorg.com>
4 *
5 * This module does authorization based on AFS groups:
6 *   Require afsgroup system:administrators
7 *
8 * It currently works by parsing the output of `pts membership
9 * <group>`.
10 */
11
12#include "apr_strings.h"
13
14#include "ap_config.h"
15#include "httpd.h"
16#include "http_config.h"
17#include "http_core.h"
18#include "http_log.h"
19#include "http_protocol.h"
20#include "http_request.h"
21
22#include <unistd.h>
23#include <stdio.h>
24
25typedef struct {
26    int authoritative;
27} authz_afsgroup_config_rec;
28
29static void *create_authz_afsgroup_dir_config(apr_pool_t *p, char *d)
30{
31    authz_afsgroup_config_rec *conf = apr_palloc(p, sizeof(*conf));
32
33    conf->authoritative = 1;
34    return conf;
35}
36
37static const command_rec authz_afsgroup_cmds[] =
38{
39    AP_INIT_FLAG("AuthzAFSGroupAuthoritative", ap_set_flag_slot,
40                 (void *)APR_OFFSETOF(authz_afsgroup_config_rec, authoritative),
41                 OR_AUTHCFG,
42                 "Set to 'Off' to allow access control to be passed along to "
43                 "lower modules if the 'require afsgroup' statement is not "
44                 "met. (default: On)."),
45    {NULL}
46};
47
48module AP_MODULE_DECLARE_DATA authz_afsgroup_module;
49
50static int check_afsgroup_access(request_rec *r)
51{
52    authz_afsgroup_config_rec *conf = ap_get_module_config(r->per_dir_config,
53                                                           &authz_afsgroup_module);
54    char *user = r->user;
55    int m = r->method_number;
56    int required_afsgroup = 0;
57    register int x;
58    const char *t, *w;
59    const apr_array_header_t *reqs_arr = ap_requires(r);
60    require_line *reqs;
61
62    if (!reqs_arr) {
63        return DECLINED;
64    }
65    reqs = (require_line *)reqs_arr->elts;
66
67    for (x = 0; x < reqs_arr->nelts; x++) {
68
69        if (!(reqs[x].method_mask & (AP_METHOD_BIT << m))) {
70            continue;
71        }
72
73        t = reqs[x].requirement;
74        w = ap_getword_white(r->pool, &t);
75        if (!strcasecmp(w, "afsgroup")) {
76            required_afsgroup = 1;
77            while (t[0]) {
78                int pfd[2];
79                pid_t cpid;
80                FILE *fp;
81                char *line = NULL;
82                char buf[256];
83                size_t len = 0;
84                ssize_t read;
85                w = ap_getword_conf(r->pool, &t);
86                if (pipe(pfd) == -1) {
87                    ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
88                                  "pipe() failed!");
89                    return HTTP_INTERNAL_SERVER_ERROR;
90                }
91                cpid = fork();
92                if (cpid == -1) {
93                    ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
94                                  "fork() failed!");
95                    return HTTP_INTERNAL_SERVER_ERROR;
96                }
97                if (cpid == 0) {
98                    close(pfd[0]);
99                    dup2(pfd[1], STDOUT_FILENO);
100                    execve("/usr/bin/pts",
101                           (char *const[]) {
102                               "pts", "membership", "-nameorid", w, NULL
103                           },
104                           NULL);
105                    _exit(1);
106                }
107                close(pfd[1]);
108                fp = fdopen(pfd[0], "r");
109                if (fp == NULL) {
110                    close(pfd[0]);
111                    ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
112                                  "fdopen() failed!");
113                    return HTTP_INTERNAL_SERVER_ERROR;
114                }
115                if (snprintf(buf, sizeof(buf), "  %s\n", user) >= sizeof(buf)) {
116                    ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
117                                  "access to %s failed, reason: username '%s' "
118                                  "is too long!",
119                                  r->uri, user);
120                    continue;
121                }
122                while ((read = getline(&line, &len, fp)) != -1) {
123                    if (strcmp(line, buf) == 0) {
124                        return OK;
125                    }
126                }
127                if (line)
128                    free(line);
129                fclose(fp);
130            }
131        }
132    }
133
134    if (!required_afsgroup) {
135        return DECLINED;
136    }
137
138    if (!conf->authoritative) {
139        return DECLINED;
140    }
141
142    ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
143                  "access to %s failed, reason: user '%s' does not meet "
144                  "'require'ments for afsgroup to be allowed access",
145                  r->uri, user);
146
147    ap_note_auth_failure(r);
148    return HTTP_FORBIDDEN;
149}
150
151static void register_hooks(apr_pool_t *p)
152{
153    ap_hook_auth_checker(check_afsgroup_access, NULL, NULL, APR_HOOK_MIDDLE);
154}
155
156module AP_MODULE_DECLARE_DATA authz_afsgroup_module =
157{
158    STANDARD20_MODULE_STUFF,
159    create_authz_afsgroup_dir_config, /* dir config creater */
160    NULL,                             /* dir merger --- default is to override */
161    NULL,                             /* server config */
162    NULL,                             /* merge server config */
163    authz_afsgroup_cmds,              /* command apr_table_t */
164    register_hooks                    /* register hooks */
165};
Note: See TracBrowser for help on using the repository browser.