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