]> andersk Git - moira.git/blob - server/qaccess.pc
Code style cleanup. (No functional changes)
[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(struct query *q, char *argv[], client *cl)
42 {
43   if (cl->users_id != *(int *)argv[0])
44     return MR_PERM;
45   else
46     return MR_SUCCESS;
47 }
48
49
50
51 /* access_login - verify that client name equals specified login name
52  *
53  *   argv[0...n] contain search info.  q->
54  */
55
56 int access_login(struct query *q, char *argv[], client *cl)
57 {
58   EXEC SQL BEGIN DECLARE SECTION;
59   int id;
60   EXEC SQL END DECLARE SECTION;
61
62   if (q->argc != 1)
63     return MR_ARGS;
64
65   if (!strcmp(q->shortname, "gual"))
66     {
67       EXEC SQL SELECT users_id INTO :id FROM users
68         WHERE login LIKE :argv[0] AND users_id != 0;
69     }
70   else if (!strcmp(q->shortname, "gubl"))
71     {
72       EXEC SQL SELECT users_id INTO :id FROM users u
73         WHERE u.login LIKE :argv[0] AND u.users_id != 0;
74     }
75   else if (!strcmp(q->shortname, "guau"))
76     {
77       EXEC SQL SELECT users_id INTO :id FROM users
78         WHERE unix_uid = :argv[0] AND users_id != 0;
79     }
80   else if (!strcmp(q->shortname, "gubu"))
81     {
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(struct query *q, char *argv[], client *cl)
111 {
112   EXEC SQL BEGIN DECLARE SECTION;
113   int list_id, acl_id, flags, gid, users_id;
114   char acl_type[9], *newname;
115   EXEC SQL END DECLARE SECTION;
116   int status;
117
118   list_id = *(int *)argv[0];
119   EXEC SQL SELECT acl_id, acl_type, gid, publicflg
120     INTO :acl_id, :acl_type, :gid, :flags
121     FROM list
122     WHERE list_id = :list_id;
123
124   if (sqlca.sqlerrd[2] != 1)
125     return MR_INTERNAL;
126
127   /* if amtl or dmfl and list is public allow client to add or delete self */
128   if (((!strcmp("amtl", q->shortname) && flags) ||
129        (!strcmp("dmfl", q->shortname))))
130     {
131       if (!strcmp("USER", argv[1]) && *(int *)argv[2] == cl->users_id)
132         return MR_SUCCESS;
133       if (!strcmp("KERBEROS", argv[1]) && *(int *)argv[2] == -cl->client_id)
134         return MR_SUCCESS;
135     } /* if update_list, don't allow them to change the GID or rename to
136          a username other than their own */
137   else if (!strcmp("ulis", q->shortname))
138     {
139       if (!strcmp(argv[7], UNIQUE_GID))
140         {
141           if (gid != -1)
142             return MR_PERM;
143         }
144       else
145         {
146           if (gid != atoi(argv[7]))
147             return MR_PERM;
148         }
149       newname = argv[1];
150       EXEC SQL SELECT users_id INTO :users_id FROM users
151         WHERE login = :newname;
152       if ((sqlca.sqlcode != SQL_NO_MATCH) && (users_id != cl->users_id))
153         return MR_PERM;
154     }
155
156   /* check for client in access control list */
157   status = find_member(acl_type, acl_id, cl);
158   if (!status)
159     return MR_PERM;
160
161   return MR_SUCCESS;
162 }
163
164
165 /* access_visible_list - allow access to list only if it is not hidden,
166  *      or if the client is on the ACL
167  *
168  * Inputs: argv[0] - list_id
169  *         cl - client identifier
170  */
171
172 int access_visible_list(struct query *q, char *argv[], client *cl)
173 {
174   EXEC SQL BEGIN DECLARE SECTION;
175   int list_id, acl_id, flags ;
176   char acl_type[9];
177   EXEC SQL END DECLARE SECTION;
178   int status;
179
180   list_id = *(int *)argv[0];
181   EXEC SQL SELECT hidden, acl_id, acl_type
182     INTO :flags, :acl_id, :acl_type
183     FROM list
184     WHERE list_id = :list_id;
185   if (sqlca.sqlerrd[2] != 1)
186     return MR_INTERNAL;
187   if (!flags)
188     return MR_SUCCESS;
189
190   /* check for client in access control list */
191   status = find_member(acl_type, acl_id, cl);
192   if (!status)
193     return MR_PERM;
194
195   return MR_SUCCESS;
196 }
197
198
199 /* access_vis_list_by_name - allow access to list only if it is not hidden,
200  *      or if the client is on the ACL
201  *
202  * Inputs: argv[0] - list name
203  *         cl - client identifier
204  */
205
206 int access_vis_list_by_name(struct query *q, char *argv[], client *cl)
207 {
208   EXEC SQL BEGIN DECLARE SECTION;
209   int acl_id, flags, rowcount;
210   char acl_type[9], *listname;
211   EXEC SQL END DECLARE SECTION;
212   int status;
213
214   listname = argv[0];
215   EXEC SQL SELECT hidden, acl_id, acl_type INTO :flags, :acl_id, :acl_type
216     FROM list WHERE name = :listname;
217
218   rowcount = sqlca.sqlerrd[2];
219   if (rowcount > 1)
220     return MR_WILDCARD;
221   if (rowcount == 0)
222     return MR_NO_MATCH;
223   if (!flags)
224     return MR_SUCCESS;
225
226   /* check for client in access control list */
227   status = find_member(acl_type, acl_id, cl);
228   if (!status)
229     return MR_PERM;
230
231   return MR_SUCCESS;
232 }
233
234
235 /* access_member - allow user to access member of type "USER" and name matches
236  * username, or to access member of type "KERBEROS" and the principal matches
237  * the user, or to access member of type "LIST" and list is one that user is
238  * on the acl of, or the list is visible.
239  */
240
241 int access_member(struct query *q, char *argv[], client *cl)
242 {
243   if (!strcmp(argv[0], "LIST") || !strcmp(argv[0], "RLIST"))
244     return access_visible_list(q, &argv[1], cl);
245
246   if (!strcmp(argv[0], "USER") || !strcmp(argv[0], "RUSER"))
247     {
248       if (cl->users_id == *(int *)argv[1])
249         return MR_SUCCESS;
250     }
251
252   if (!strcmp(argv[0], "KERBEROS") || !strcmp(argv[0], "RKERBEROS"))
253     {
254       if (cl->client_id == -*(int *)argv[1])
255         return MR_SUCCESS;
256     }
257
258   return MR_PERM;
259 }
260
261
262 /* access_qgli - special access routine for Qualified_get_lists.  Allows
263  * access iff argv[0] == "TRUE" and argv[2] == "FALSE".
264  */
265
266 int access_qgli(struct query *q, char *argv[], client *cl)
267 {
268   if (!strcmp(argv[0], "TRUE") && !strcmp(argv[2], "FALSE"))
269     return MR_SUCCESS;
270   return MR_PERM;
271 }
272
273
274 /* access_service - allow access if user is on ACL of service.  Don't
275  * allow access if a wildcard is used.
276  */
277
278 int access_service(struct query *q, char *argv[], client *cl)
279 {
280   EXEC SQL BEGIN DECLARE SECTION;
281   int acl_id;
282   char *name, acl_type[9];
283   EXEC SQL END DECLARE SECTION;
284   int status;
285   char *c;
286
287   name = argv[0];
288   for (c = name; *c; c++)
289     {
290       if (islower(*c))
291         *c = toupper(*c);
292     }
293   EXEC SQL SELECT acl_id, acl_type INTO :acl_id, :acl_type FROM servers
294     WHERE name = :name;
295   if (sqlca.sqlerrd[2] > 1)
296     return MR_PERM;
297
298   /* check for client in access control list */
299   status = find_member(acl_type, acl_id, cl);
300   if (!status)
301     return MR_PERM;
302
303   return MR_SUCCESS;
304 }
305
306
307 /* access_filesys - verify that client is owner or on owners list of filesystem
308  *      named by argv[0]
309  */
310
311 int access_filesys(struct query *q, char *argv[], client *cl)
312 {
313   EXEC SQL BEGIN DECLARE SECTION;
314   int users_id, list_id;
315   char *name;
316   EXEC SQL END DECLARE SECTION;
317   int status;
318
319   name = argv[0];
320   EXEC SQL SELECT owner, owners INTO :users_id, :list_id FROM filesys
321     WHERE label = :name;
322
323   if (sqlca.sqlerrd[2] != 1)
324     return MR_PERM;
325   if (users_id == cl->users_id)
326     return MR_SUCCESS;
327   status = find_member("LIST", list_id, cl);
328   if (status)
329     return MR_SUCCESS;
330   else
331     return MR_PERM;
332 }
333
334
335 /* access_host - successful if owner of host, or subnet containing host
336  */
337
338 int host_access_level = 0;              /* 1 for network, 2 for host */
339
340 int access_host(struct query *q, char *argv[], client *cl)
341 {
342   EXEC SQL BEGIN DECLARE SECTION;
343   int mid, sid, id;
344   char mtype[9], stype[9];
345   EXEC SQL END DECLARE SECTION;
346   int status;
347
348   if (q->type == APPEND)
349     {
350       id = *(int *)argv[8];
351       EXEC SQL SELECT s.owner_type, s.owner_id
352         INTO :stype, :sid FROM subnet s
353         WHERE s.snet_id = :id;
354       mid = 0;
355     }
356   else if (q->type == RETRIEVE)
357     {
358       if (strcmp(argv[0], "*") || strcmp(argv[1], "*") ||
359           strcmp(argv[2], "*") || strcmp(argv[3], "*"))
360         return MR_SUCCESS;
361       else
362         return MR_PERM;
363     }
364   else
365     {
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     {
377       host_access_level = 1;
378       return MR_SUCCESS;
379     }
380   status = find_member(mtype, mid, cl);
381   if (status)
382     {
383       host_access_level = 2;
384       return MR_SUCCESS;
385     }
386   else
387     return MR_PERM;
388 }
389
390
391 /* access_ahal - check for adding a host alias.
392  * successful if host has less then 2 aliases and (client is owner of
393  * host or subnet).
394  * If deleting an alias, any owner will do.
395  */
396
397 int access_ahal(struct query *q, char *argv[], 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)
412     return mr_errcode;
413   /* if the type is APPEND, this is ahal and we need to make sure there
414    * will be no more than 2 aliases.  If it's not, it must be dhal and
415    * any owner will do.
416    */
417   if (q->type == APPEND && cnt >= 2)
418     return MR_PERM;
419   EXEC SQL SELECT m.owner_type, m.owner_id, s.owner_type, s.owner_id
420     INTO :mtype, :mid, :stype, :sid FROM machine m, subnet s
421     WHERE m.mach_id = :id and s.snet_id = m.snet_id;
422   status = find_member(mtype, mid, cl);
423   if (status)
424     return MR_SUCCESS;
425   status = find_member(stype, sid, cl);
426   if (status)
427     return MR_SUCCESS;
428   else
429     return MR_PERM;
430 }
431
432
433
434 /* access_snt - check for retrieving network structure
435  */
436
437 int access_snt(struct query *q, char *argv[], client *cl)
438 {
439   if (q->type == RETRIEVE)
440     return MR_SUCCESS;
441
442   return MR_PERM;
443 }
This page took 0.069186 seconds and 5 git commands to generate.