]> andersk Git - moira.git/blob - server/qaccess.pc
036643119e312e94ea2ab57ce8320c4fc89f64c3
[moira.git] / server / qaccess.pc
1 /*
2  *      $Source$
3  *      $Author$
4  *      $Header$
5  *
6  *      Copyright (C) 1987 by the Massachusetts Institute of Technology
7  *      For copying and distribution information, please see the file
8  *      <mit-copyright.h>.
9  *
10  */
11
12 #ifndef lint
13 static char *rcsid_qsupport_dc = "$Header$";
14 #endif lint
15
16 #include <mit-copyright.h>
17 #include "mr_server.h"
18 #include "query.h"
19 #include <ctype.h>
20 EXEC SQL INCLUDE sqlca;
21 #include "qrtn.h"
22
23 extern char *whoami;
24 extern int dbms_errno, mr_errcode;
25
26 EXEC SQL BEGIN DECLARE SECTION;
27 extern char stmt_buf[];
28 EXEC SQL END DECLARE SECTION;
29
30 EXEC SQL WHENEVER SQLERROR DO dbmserr();
31
32
33 /* Specialized Access Routines */
34
35 /* access_user - verify that client name equals specified login name
36  *
37  *  - since field validation routines are called first, a users_id is
38  *    now in argv[0] instead of the login name.
39  */
40
41 int access_user(q, argv, cl)
42      struct query *q;
43      char *argv[];
44      client *cl;
45 {
46     if (cl->users_id != *(int *)argv[0])
47         return(MR_PERM);
48     else
49         return(MR_SUCCESS);
50 }
51
52
53
54 /* access_login - verify that client name equals specified login name
55  *
56  *   argv[0...n] contain search info.  q->
57  */
58
59 int access_login(q, argv, cl)
60      struct query *q;
61      char *argv[];
62      client *cl;
63 {
64     EXEC SQL BEGIN DECLARE SECTION;
65     int id;
66     EXEC SQL END DECLARE SECTION;
67
68     if(q->argc != 1) return MR_ARGS;
69
70     if(!strcmp(q->shortname, "gual")) {
71       EXEC SQL SELECT users_id INTO :id FROM users u, strings str
72         WHERE u.login LIKE :argv[0] AND u.users_id != 0
73         AND u.comments = str.string_id;
74     } else if (!strcmp(q->shortname, "gubl")) {
75       EXEC SQL SELECT users_id INTO :id FROM users u
76         WHERE u.login LIKE :argv[0] AND u.users_id != 0;
77     } else if (!strcmp(q->shortname, "guau")) {
78       EXEC SQL SELECT users_id INTO :id FROM users u, strings str
79         WHERE u.unix_uid = :argv[0] AND u.users_id != 0
80         AND u.comments = str.string_id;
81     } else if(!strcmp(q->shortname, "gubu")) {
82       EXEC SQL SELECT users_id INTO :id FROM users u
83         WHERE u.unix_uid = :argv[0] AND u.users_id != 0;
84     }
85
86     if (sqlca.sqlcode == SQL_NO_MATCH)
87         return(MR_NO_MATCH); /* ought to be MR_USER, but this is what
88                                 gual returns, so we have to be consistent */
89     else if (sqlca.sqlerrd[2] != 1 || id != cl->users_id)
90         return(MR_PERM);
91     else
92         return(MR_SUCCESS);
93 }
94
95
96
97 /* access_list - check access for most list operations
98  *
99  * Inputs: argv[0] - list_id
100  *          q - query name
101  *          argv[2] - member ID (only for queries "amtl" and  "dmfl")
102  *          argv[7] - group IID (only for query "ulis")
103  *          cl - client name
104  *
105  * - check that client is a member of the access control list
106  * - OR, if the query is add_member_to_list or delete_member_from_list
107  *      and the list is public, allow access if client = member
108  */
109
110 int access_list(q, argv, cl)
111      struct query *q;
112      char *argv[];
113      client *cl;
114 {
115     EXEC SQL BEGIN DECLARE SECTION;
116     int list_id, acl_id, flags, gid, users_id;
117     char acl_type[9], *newname;
118     EXEC SQL END DECLARE SECTION;
119     int status;
120
121     list_id = *(int *)argv[0];
122     EXEC SQL SELECT acl_id, acl_type, gid, publicflg
123       INTO :acl_id, :acl_type, :gid, :flags
124       FROM list
125       WHERE list_id = :list_id;
126
127     if (sqlca.sqlerrd[2] != 1)
128       return(MR_INTERNAL);
129
130     /* if amtl or dmfl and list is public allow client to add or delete self */
131     if (((!strcmp("amtl", q->shortname) && flags) ||
132          (!strcmp("dmfl", q->shortname)))) {
133         if (!strcmp("USER", argv[1]) && *(int *)argv[2] == cl->users_id)
134             return(MR_SUCCESS);
135         if (!strcmp("KERBEROS", argv[1]) && *(int *)argv[2] == -cl->client_id)
136             return(MR_SUCCESS);
137     /* if update_list, don't allow them to change the GID or rename to
138        a username other than their own */
139     } else if (!strcmp("ulis", q->shortname)) {
140       if (!strcmp(argv[7], UNIQUE_GID)) {
141         if(gid != -1) return MR_PERM;
142       } else {
143         if(gid != atoi(argv[7])) return MR_PERM;
144       }
145       newname = argv[1];
146       EXEC SQL SELECT users_id INTO :users_id FROM users
147           WHERE login=:newname;
148       if ((sqlca.sqlcode != SQL_NO_MATCH) && (users_id != cl->users_id))
149           return MR_PERM;
150     }
151
152     /* check for client in access control list */
153     status = find_member(acl_type, acl_id, cl);
154     if (!status) return(MR_PERM);
155
156     return(MR_SUCCESS);
157 }
158
159
160 /* access_visible_list - allow access to list only if it is not hidden,
161  *      or if the client is on the ACL
162  *
163  * Inputs: argv[0] - list_id
164  *         cl - client identifier
165  */
166
167 int access_visible_list(q, argv, cl)
168      struct query *q;
169      char *argv[];
170      client *cl;
171 {
172     EXEC SQL BEGIN DECLARE SECTION;
173     int list_id, acl_id, flags ;
174     char acl_type[9];
175     EXEC SQL END DECLARE SECTION;
176     int status;
177
178     list_id = *(int *)argv[0];
179     EXEC SQL SELECT hidden, acl_id, acl_type
180       INTO :flags, :acl_id, :acl_type
181       FROM list
182       WHERE list_id = :list_id;
183     if (sqlca.sqlerrd[2] != 1)
184       return(MR_INTERNAL);
185     if (!flags)
186         return(MR_SUCCESS);
187
188     /* check for client in access control list */
189     status = find_member(acl_type, acl_id, cl);
190     if (!status)
191         return(MR_PERM);
192
193     return(MR_SUCCESS);
194 }
195
196
197 /* access_vis_list_by_name - allow access to list only if it is not hidden,
198  *      or if the client is on the ACL
199  *
200  * Inputs: argv[0] - list name
201  *         cl - client identifier
202  */
203
204 int access_vis_list_by_name(q, argv, cl)
205      struct query *q;
206      char *argv[];
207      client *cl;
208 {
209     EXEC SQL BEGIN DECLARE SECTION;
210     int acl_id, flags, rowcount;
211     char acl_type[9], *listname;
212     EXEC SQL END DECLARE SECTION;
213     int status;
214
215     listname = argv[0];
216     EXEC SQL SELECT hidden, acl_id, acl_type INTO :flags, :acl_id, :acl_type
217       FROM list WHERE name = :listname;
218
219     rowcount=sqlca.sqlerrd[2];
220     if (rowcount > 1)
221       return(MR_WILDCARD);
222     if (rowcount == 0)
223       return(MR_NO_MATCH);
224     if (!flags)
225         return(MR_SUCCESS);
226
227     /* check for client in access control list */
228     status = find_member(acl_type, acl_id, cl);
229     if (!status)
230         return(MR_PERM);
231
232     return(MR_SUCCESS);
233 }
234
235
236 /* access_member - allow user to access member of type "USER" and name matches
237  * username, or to access member of type "KERBEROS" and the principal matches
238  * the user, or to access member of type "LIST" and list is one that user is
239  * on the acl of, or the list is visible.
240  */
241
242 int access_member(q, argv, cl)
243      struct query *q;
244      char *argv[];
245      client *cl;
246 {
247     if (!strcmp(argv[0], "LIST") || !strcmp(argv[0], "RLIST"))
248       return(access_visible_list(q, &argv[1], cl));
249
250     if (!strcmp(argv[0], "USER") || !strcmp(argv[0], "RUSER")) {
251         if (cl->users_id == *(int *)argv[1])
252           return(MR_SUCCESS);
253     }
254
255     if (!strcmp(argv[0], "KERBEROS") || !strcmp(argv[0], "RKERBEROS")) {
256         if (cl->client_id == -*(int *)argv[1])
257           return(MR_SUCCESS);
258     }
259
260     return(MR_PERM);
261 }
262
263
264 /* access_qgli - special access routine for Qualified_get_lists.  Allows
265  * access iff argv[0] == "TRUE" and argv[2] == "FALSE".
266  */
267
268 int access_qgli(q, argv, cl)
269      struct query *q;
270      char *argv[];
271      client *cl;
272 {
273     if (!strcmp(argv[0], "TRUE") && !strcmp(argv[2], "FALSE"))
274       return(MR_SUCCESS);
275     return(MR_PERM);
276 }
277
278
279 /* access_service - allow access if user is on ACL of service.  Don't
280  * allow access if a wildcard is used.
281  */
282
283 int access_service(q, argv, cl)
284      struct query *q;
285      char *argv[];
286      client *cl;
287 {
288     EXEC SQL BEGIN DECLARE SECTION;
289     int acl_id;
290     char *name, acl_type[9];
291     EXEC SQL END DECLARE SECTION;
292     int status;
293     char *c;
294
295     name = argv[0];
296     for(c=name;*c;c++) if(islower(*c)) *c = toupper(*c);  /* uppercasify */
297     EXEC SQL SELECT acl_id, acl_type INTO :acl_id, :acl_type FROM servers
298       WHERE name = :name;
299     if (sqlca.sqlerrd[2] > 1)
300       return(MR_PERM);
301
302     /* check for client in access control list */
303     status = find_member(acl_type, acl_id, cl);
304     if (!status) return(MR_PERM);
305
306     return(MR_SUCCESS);
307 }
308
309
310 /* access_filesys - verify that client is owner or on owners list of filesystem
311  *      named by argv[0]
312  */
313
314 int access_filesys(q, argv, cl)
315      struct query *q;
316      char *argv[];
317      client *cl;
318 {
319     EXEC SQL BEGIN DECLARE SECTION;
320     int users_id, list_id;
321     char *name;
322     EXEC SQL END DECLARE SECTION;
323     int status;
324
325     name = argv[0];
326     EXEC SQL SELECT owner, owners INTO :users_id, :list_id FROM filesys
327       WHERE label = :name;
328
329     if (sqlca.sqlerrd[2] != 1)
330       return(MR_PERM);
331     if (users_id == cl->users_id)
332       return(MR_SUCCESS);
333     status = find_member("LIST", list_id, cl);
334     if (status)
335       return(MR_SUCCESS);
336     else
337       return(MR_PERM);
338 }
339
340
341 /* access_host - successful if owner of host, or subnet containing host
342  */
343
344 int host_access_level = 0;              /* 1 for network, 2 for host */
345
346 int access_host(q, argv, cl)
347      struct query *q;
348      char *argv[];
349      client *cl;
350 {
351     EXEC SQL BEGIN DECLARE SECTION;
352     int mid, sid, id;
353     char mtype[9], stype[9];
354     EXEC SQL END DECLARE SECTION;
355     int status;
356
357     if (q->type == APPEND) {
358         id = *(int *)argv[8];
359         EXEC SQL SELECT s.owner_type, s.owner_id
360           INTO :stype, :sid FROM subnet s
361           WHERE s.snet_id=:id;
362         mid =0;
363     } else if (q->type == RETRIEVE) {
364         return(MR_SUCCESS);
365     } else {
366         id = *(int *)argv[0];
367         EXEC SQL SELECT m.owner_type, m.owner_id, s.owner_type, s.owner_id
368           INTO :mtype, :mid, :stype, :sid FROM machine m, subnet s
369           WHERE m.mach_id=:id and s.snet_id=m.snet_id;
370     }
371     if (sqlca.sqlerrd[2] != 1)
372       return(MR_PERM);
373
374     status = find_member(stype, sid, cl);
375     if (status) {
376         host_access_level = 1;
377         return(MR_SUCCESS);
378     }
379     status = find_member(mtype, mid, cl);
380     if (status) {
381         host_access_level = 2;
382         return(MR_SUCCESS);
383     } else
384       return(MR_PERM);
385 }
386
387
388 /* access_ahal - check for adding a host alias.
389  * successful if host has less then 2 aliases and (client is owner of
390  * host or subnet).
391  * If deleting an alias, any owner will do.
392  */
393
394 int access_ahal(q, argv, cl)
395      struct query *q;
396      char *argv[];
397      client *cl;
398 {
399     EXEC SQL BEGIN DECLARE SECTION;
400     int cnt, id, mid, sid;
401     char mtype[256], stype[256];
402     EXEC SQL END DECLARE SECTION;
403     int status;
404
405     if (q->type == RETRIEVE)
406       return(MR_SUCCESS);
407
408     id = *(int *)argv[1];
409
410     EXEC SQL SELECT count(name) INTO :cnt from hostalias WHERE mach_id = :id;
411     if (dbms_errno) return(mr_errcode);
412     /* if the type is APPEND, this is ahal and we need to make sure there
413      * will be no more than 2 aliases.  If it's not, it must be dhal and
414      * any owner will do.
415      */
416     if (q->type == APPEND && cnt >= 2)
417       return(MR_PERM);
418     EXEC SQL SELECT m.owner_type, m.owner_id, s.owner_type, s.owner_id
419       INTO :mtype, :mid, :stype, :sid FROM machine m, subnet s
420       WHERE m.mach_id=:id and s.snet_id=m.snet_id;
421     status = find_member(mtype, mid, cl);
422     if (status)
423       return(MR_SUCCESS);
424     status = find_member(stype, sid, cl);
425     if (status)
426       return(MR_SUCCESS);
427     else
428       return(MR_PERM);
429 }
430
431
432
433 /* access_snt - check for retrieving network structure
434  */
435
436 int access_snt(q, argv, cl)
437      struct query *q;
438      char *argv[];
439      client *cl;
440 {
441     if(q->type == RETRIEVE)
442        return(MR_SUCCESS);
443
444     return(MR_PERM);
445 }
This page took 0.057989 seconds and 3 git commands to generate.