]> asedeno.scripts.mit.edu Git - 1ts-debian.git/blob - zephyr/server/access.c
r4262@bucket (orig r252): kcr | 2008-01-20 22:11:00 -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 #if 0
99     zdbug ((LOG_DEBUG, "checking %s for %s", buf, sender));
100 #endif
101         
102     retval = acl_load(buf);
103     if (retval < 0) {
104         syslog(LOG_DEBUG, "Error in acl_load of %s for %s", buf, sender);
105         return 0;
106     }
107     return acl_check(buf, sender);
108 }
109
110 static void
111 check_acl(Acl *acl)
112 {
113     acl->acl_types = 0;
114     check_acl_type(acl, TRANSMIT, ACL_XMT);
115     check_acl_type(acl, SUBSCRIBE, ACL_SUB);
116     check_acl_type(acl, INSTWILD, ACL_IWS);
117     check_acl_type(acl, INSTUID, ACL_IUI);
118 }
119
120 static void
121 check_acl_type(Acl *acl,
122                Access accesstype,
123                int typeflag)
124 {
125     char        buf[MAXPATHLEN]; /* holds the real acl name */
126     char        *prefix;
127
128     switch (accesstype) {
129       case TRANSMIT:
130         prefix = "xmt";
131         break;
132       case SUBSCRIBE:
133         prefix = "sub";
134         break;
135       case INSTWILD:
136         prefix = "iws";
137         break;
138       case INSTUID:
139         prefix = "iui";
140         break;
141       default:
142         syslog(LOG_ERR, "unknown access type %d", (int) accesstype);
143         return;
144     }
145     sprintf(buf, "%s/%s-%s.acl", acl_dir, prefix, acl->acl_filename);
146     if (!access(buf, F_OK))
147         acl->acl_types |= typeflag;
148 }
149
150
151 /*
152  * Re-init code written by TYT, 8/14/90.
153  *
154  * General plan of action; we reread the registry list, and add any
155  * new restricted classes.  If any restricted classes disappear (this
156  * should be rarely) the Acl structure is not deallocated; rather,
157  * the acl_types field will be left at zero, since there will be no
158  * acl files for the (non-)restricted class.
159  */
160 static void
161 access_setup(int first)
162 {
163     char buf[MAXPATHLEN];
164     char class_name[512];       /* assume class names <= 511 bytes */
165     FILE *registry;
166     Acl *acl;
167     int len;
168     char *colon_idx;
169     Code_t retval = 0;
170
171     sprintf(buf, "%s/%s", acl_dir, ZEPHYR_CLASS_REGISTRY);
172     registry = fopen(buf, "r");
173     if (!registry) {
174         syslog(LOG_ERR, "no registry available, all classes are free");
175         return;
176     }
177     while (fgets(class_name, 512, registry)) {
178         colon_idx = strchr(class_name, ':');
179         if (colon_idx != NULL)
180             *colon_idx = '\0';
181         else if ((len = strlen(class_name)) != 0)
182             class_name[len - 1] = '\0';
183         acl = 0;
184         if (!first) {
185             String *z;
186
187             z = make_string(class_name,1);
188             acl = class_get_acl(z);
189             free_string(z);
190         }
191         if (!acl) {
192             acl = (Acl *) malloc(sizeof(Acl));
193             if (!acl) {
194                 syslog(LOG_ERR, "no mem acl alloc");
195                 abort();
196             }
197             acl->acl_filename = strsave(class_name);
198             check_acl(acl);
199                     
200             if (!first) {
201                 /* Try to restrict already existing class */
202                 retval = class_restrict(class_name, acl);
203                 if (retval == ZSRV_NOCLASS)
204                     retval = class_setup_restricted(class_name, acl);
205             } else {
206                 retval = class_setup_restricted(class_name, acl);
207             }
208         }
209         if (retval) {
210             syslog(LOG_ERR, "can't restrict %s: %s",
211                    class_name, error_message(retval));
212             continue;
213         }
214         zdbug((LOG_DEBUG, "restricted %s", class_name));
215     }
216     fclose(registry);
217 }
218
219 void
220 access_init(void)
221 {
222     access_setup(1);
223 }
224
225 void
226 access_reinit(void)
227 {
228     acl_cache_reset();
229     access_setup(0);
230 }