]> asedeno.scripts.mit.edu Git - 1ts-debian.git/blob - zephyr/server/access.c
r4281@bucket (orig r271): kcr | 2008-01-21 14:50:52 -0500
[1ts-debian.git] / zephyr / server / access.c
1 /* This file is part of the Project Athena Zephyr Notification System.
2  * It contains functions for dealing with acl's.
3  *
4  *      Created by:     John T. Kohl
5  *
6  *      $Id$
7  *
8  *      Copyright (c) 1987 by the Massachusetts Institute of Technology.
9  *      For copying and distribution information, see the file
10  *      "mit-copyright.h". 
11  */
12
13 #include <zephyr/mit-copyright.h>
14 #include "zserver.h"
15 #include <com_err.h>
16
17 #if !defined (lint) && !defined (SABER)
18 static const char rcsid_access_c[] =
19     "$Id$";
20 #endif
21
22 /*
23  *
24  * External routines:
25  *
26  * int access_check(notice, acl, accesstype)
27  *    ZNotice_t *notice;
28  *    Acl *acl;
29  *    Access accesstype;
30  *
31  * void access_init();
32  *
33  * void access_reinit();
34  */
35
36 /*
37  * Each restricted class has four ACL's associated with it,
38  * governing subscriptions, transmission, and instance restrictions.
39  * This module provides the 'glue' between the standard Athena ACL
40  * routines and the support needed by the Zephyr server.
41  */
42
43 /*
44  * Our private types for the acl_types field in the Acl structure.
45  *      -TYT 8/14/90
46  */
47 #define ACL_XMT         1
48 #define ACL_SUB         2
49 #define ACL_IWS         4
50 #define ACL_IUI         8
51
52 static void check_acl __P((Acl *acl));
53 static void check_acl_type __P((Acl *acl, Access accesstype, int typeflag));
54 static void access_setup __P((int first));
55
56 /*
57  * check access.  return 1 if ok, 0 if not ok.
58  */
59
60 int
61 access_check(char *sender,
62              Acl *acl,
63              Access accesstype)
64 {
65     char buf[MAXPATHLEN];       /* holds the real acl name */
66     char *prefix;
67     int flag;
68     int retval;
69
70     switch (accesstype) {
71       case TRANSMIT:
72         prefix = "xmt";
73         flag = ACL_XMT;
74         break;
75       case SUBSCRIBE:
76         prefix = "sub";
77         flag = ACL_SUB;
78         break;
79       case INSTWILD:
80         prefix = "iws";
81         flag = ACL_IWS;
82         break;
83       case INSTUID:
84         prefix = "iui";
85         flag = ACL_IUI;
86         break;
87       default:
88         syslog(LOG_ERR, "unknown access type %d", (int) accesstype);
89         return 0;
90     }
91     if (!(acl->acl_types & flag)) /* no acl ==> no restriction */
92         return 1;
93     sprintf(buf, "%s/%s-%s.acl", acl_dir, prefix, acl->acl_filename);
94     /*
95      * If we can't load it (because it probably doesn't exist),
96      * we deny access.
97      */
98     retval = acl_load(buf);
99     if (retval < 0) {
100         syslog(LOG_DEBUG, "Error in acl_load of %s for %s", buf, sender);
101         return 0;
102     }
103     return acl_check(buf, sender);
104 }
105
106 static void
107 check_acl(Acl *acl)
108 {
109     acl->acl_types = 0;
110     check_acl_type(acl, TRANSMIT, ACL_XMT);
111     check_acl_type(acl, SUBSCRIBE, ACL_SUB);
112     check_acl_type(acl, INSTWILD, ACL_IWS);
113     check_acl_type(acl, INSTUID, ACL_IUI);
114 }
115
116 static void
117 check_acl_type(Acl *acl,
118                Access accesstype,
119                int typeflag)
120 {
121     char        buf[MAXPATHLEN]; /* holds the real acl name */
122     char        *prefix;
123
124     switch (accesstype) {
125       case TRANSMIT:
126         prefix = "xmt";
127         break;
128       case SUBSCRIBE:
129         prefix = "sub";
130         break;
131       case INSTWILD:
132         prefix = "iws";
133         break;
134       case INSTUID:
135         prefix = "iui";
136         break;
137       default:
138         syslog(LOG_ERR, "unknown access type %d", (int) accesstype);
139         return;
140     }
141     sprintf(buf, "%s/%s-%s.acl", acl_dir, prefix, acl->acl_filename);
142     if (!access(buf, F_OK))
143         acl->acl_types |= typeflag;
144 }
145
146
147 /*
148  * Re-init code written by TYT, 8/14/90.
149  *
150  * General plan of action; we reread the registry list, and add any
151  * new restricted classes.  If any restricted classes disappear (this
152  * should be rarely) the Acl structure is not deallocated; rather,
153  * the acl_types field will be left at zero, since there will be no
154  * acl files for the (non-)restricted class.
155  */
156 static void
157 access_setup(int first)
158 {
159     char buf[MAXPATHLEN];
160     char class_name[512];       /* assume class names <= 511 bytes */
161     FILE *registry;
162     Acl *acl;
163     int len;
164     char *colon_idx;
165     Code_t retval = 0;
166
167     sprintf(buf, "%s/%s", acl_dir, ZEPHYR_CLASS_REGISTRY);
168     registry = fopen(buf, "r");
169     if (!registry) {
170         syslog(LOG_ERR, "no registry available, all classes are free");
171         return;
172     }
173     while (fgets(class_name, 512, registry)) {
174         colon_idx = strchr(class_name, ':');
175         if (colon_idx != NULL)
176             *colon_idx = '\0';
177         else if ((len = strlen(class_name)) != 0)
178             class_name[len - 1] = '\0';
179         acl = 0;
180         if (!first) {
181             String *z;
182
183             z = make_string(class_name,1);
184             acl = class_get_acl(z);
185             free_string(z);
186         }
187         if (!acl) {
188             acl = (Acl *) malloc(sizeof(Acl));
189             if (!acl) {
190                 syslog(LOG_ERR, "no mem acl alloc");
191                 abort();
192             }
193             acl->acl_filename = strsave(class_name);
194             check_acl(acl);
195                     
196             if (!first) {
197                 /* Try to restrict already existing class */
198                 retval = class_restrict(class_name, acl);
199                 if (retval == ZSRV_NOCLASS)
200                     retval = class_setup_restricted(class_name, acl);
201             } else {
202                 retval = class_setup_restricted(class_name, acl);
203             }
204         }
205         if (retval) {
206             syslog(LOG_ERR, "can't restrict %s: %s",
207                    class_name, error_message(retval));
208             continue;
209         }
210         zdbug((LOG_DEBUG, "restricted %s", class_name));
211     }
212     fclose(registry);
213 }
214
215 void
216 access_init(void)
217 {
218     access_setup(1);
219 }
220
221 void
222 access_reinit(void)
223 {
224     acl_cache_reset();
225     access_setup(0);
226 }