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