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