]> andersk Git - moira.git/blame - server/qaccess.pc
Don't require a valid account number if we're setting a host to be deleted.
[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
f659afb2 91/* access_spob - check access for set_pobox */
92
93int access_spob(struct query *q, char *argv[], client *cl)
94{
51e578b6 95 EXEC SQL BEGIN DECLARE SECTION;
96 int id;
97 EXEC SQL END DECLARE SECTION;
98
99 if (!strcmp(argv[1], "IMAP"))
100 {
101 EXEC SQL SELECT owner INTO :id FROM filesys f
102 WHERE f.label = :argv[2] AND f.type = 'IMAP' AND
103 f.lockertype = 'USER';
104 if (cl->users_id != id)
105 return MR_PERM;
106 }
107 if (cl->users_id != *(int *)argv[0])
f659afb2 108 return MR_PERM;
109 else
110 return MR_SUCCESS;
111}
112
73cf66ba 113
114/* access_list - check access for most list operations
115 *
116 * Inputs: argv[0] - list_id
117 * q - query name
118 * argv[2] - member ID (only for queries "amtl" and "dmfl")
e688520a 119 * argv[7] - group ID (only for query "ulis")
73cf66ba 120 * cl - client name
121 *
122 * - check that client is a member of the access control list
123 * - OR, if the query is add_member_to_list or delete_member_from_list
124 * and the list is public, allow access if client = member
125 */
126
5eaef520 127int access_list(struct query *q, char *argv[], client *cl)
73cf66ba 128{
5eaef520 129 EXEC SQL BEGIN DECLARE SECTION;
40b33762 130 int list_id, acl_id, flags, gid, users_id, member_id, member_acl_id;
59c3208b 131 int memacl_id;
e688520a 132 char acl_type[LIST_ACL_TYPE_SIZE], name[LIST_NAME_SIZE], *newname;
59c3208b 133 char member_acl_type[LIST_ACL_TYPE_SIZE], memacl_type[LIST_ACL_TYPE_SIZE];
5eaef520 134 EXEC SQL END DECLARE SECTION;
135 int status;
136
137 list_id = *(int *)argv[0];
40b33762 138 member_id = *(int *)argv[2];
59c3208b 139 EXEC SQL SELECT acl_id, acl_type, memacl_id, memacl_type,
140 gid, publicflg, name
141 INTO :acl_id, :acl_type, :memacl_id, :memacl_type,
142 :gid, :flags, :name
5eaef520 143 FROM list
144 WHERE list_id = :list_id;
145
146 if (sqlca.sqlerrd[2] != 1)
147 return MR_INTERNAL;
148
59c3208b 149 /* if update_list, don't allow them to change the GID or rename to a
150 username other than their own */
151 if (!strcmp("ulis", q->shortname))
5eaef520 152 {
153 if (!strcmp(argv[7], UNIQUE_GID))
154 {
155 if (gid != -1)
156 return MR_PERM;
157 }
158 else
159 {
160 if (gid != atoi(argv[7]))
161 return MR_PERM;
162 }
5c96d2cd 163
d83ee5a2 164 newname = argv[1];
5c96d2cd 165
166 if (!strcmp("ulis", q->shortname))
167 {
168 /* Check that it doesn't conflict with the Grouper namespace. */
169 if (strlen(newname) > 4 && isdigit(newname[2]) &&
170 isdigit(newname[3]) && newname[4] == '-')
171 {
172 if (!strncasecmp(newname, "fa", 2) ||
173 !strncasecmp(newname, "sp", 2) ||
174 !strncasecmp(newname, "su", 2) ||
175 !strncasecmp(newname, "ja", 2))
176 return MR_RESERVED;
177 }
178
179 /* Don't let anyone take owner-foo list names. They interact
180 * weirdly with the aliases automatically generated by
181 * mailhub.gen.
182 */
183 if (!strncasecmp(newname, "owner-", 6))
184 return MR_RESERVED;
185 }
186
d83ee5a2 187 EXEC SQL SELECT users_id INTO :users_id FROM users
5eaef520 188 WHERE login = :newname;
17f090e1 189 if ((sqlca.sqlcode != SQL_NO_MATCH) && strcmp(strtrim(name), newname) &&
190 (users_id != cl->users_id))
5eaef520 191 return MR_PERM;
73cf66ba 192 }
193
59c3208b 194 /* check for client in access control list and return success right
195 * away if it's there. */
196 if (find_member(acl_type, acl_id, cl))
197 return MR_SUCCESS;
198
199 /* If not amtl, atml, or dmfl, we lose. */
200 if (strcmp(q->shortname, "amtl") && strcmp(q->shortname, "atml") &&
e3fbe284 201 strcmp(q->shortname, "dmfl") && strcmp(q->shortname, "tmol"))
5eaef520 202 return MR_PERM;
73cf66ba 203
59c3208b 204 if (find_member(memacl_type, memacl_id, cl))
205 return MR_SUCCESS;
206
207 if (flags || q->type == DELETE)
208 {
209 if (!strcmp("USER", argv[1]) && *(int *)argv[2] == cl->users_id)
210 return MR_SUCCESS;
211 if (!strcmp("KERBEROS", argv[1]) && *(int *)argv[2] == -cl->client_id)
212 return MR_SUCCESS;
213 if (!strcmp("LIST", argv[1]) && !strcmp("dmfl", q->shortname))
214 {
215 EXEC SQL SELECT acl_id, acl_type INTO :member_acl_id,
216 :member_acl_type
217 FROM list
218 WHERE list_id = :member_id;
219
220 if (find_member(member_acl_type, member_acl_id, cl))
221 return MR_SUCCESS;
222 }
223 }
224
225 /* Otherwise fail. */
226 return MR_PERM;
73cf66ba 227}
228
229
230/* access_visible_list - allow access to list only if it is not hidden,
231 * or if the client is on the ACL
232 *
233 * Inputs: argv[0] - list_id
234 * cl - client identifier
235 */
236
5eaef520 237int access_visible_list(struct query *q, char *argv[], client *cl)
73cf66ba 238{
5eaef520 239 EXEC SQL BEGIN DECLARE SECTION;
59c3208b 240 int list_id, acl_id, memacl_id, flags ;
241 char acl_type[LIST_ACL_TYPE_SIZE], memacl_type[LIST_ACL_TYPE_SIZE];
5eaef520 242 EXEC SQL END DECLARE SECTION;
243 int status;
244
245 list_id = *(int *)argv[0];
59c3208b 246 EXEC SQL SELECT hidden, acl_id, acl_type, memacl_id, memacl_type
247 INTO :flags, :acl_id, :acl_type, :memacl_id, :memacl_type
5eaef520 248 FROM list
249 WHERE list_id = :list_id;
250 if (sqlca.sqlerrd[2] != 1)
251 return MR_INTERNAL;
252 if (!flags)
253 return MR_SUCCESS;
254
255 /* check for client in access control list */
256 status = find_member(acl_type, acl_id, cl);
257 if (!status)
59c3208b 258 {
259 status = find_member(memacl_type, memacl_id, cl);
260 if (!status)
261 return MR_PERM;
262 }
5eaef520 263 return MR_SUCCESS;
73cf66ba 264}
265
266
267/* access_vis_list_by_name - allow access to list only if it is not hidden,
268 * or if the client is on the ACL
269 *
270 * Inputs: argv[0] - list name
271 * cl - client identifier
272 */
273
5eaef520 274int access_vis_list_by_name(struct query *q, char *argv[], client *cl)
73cf66ba 275{
5eaef520 276 EXEC SQL BEGIN DECLARE SECTION;
59c3208b 277 int acl_id, memacl_id, flags, rowcount;
278 char acl_type[LIST_ACL_TYPE_SIZE], memacl_type[LIST_ACL_TYPE_SIZE];
279 char *listname;
5eaef520 280 EXEC SQL END DECLARE SECTION;
281 int status;
282
283 listname = argv[0];
59c3208b 284 EXEC SQL SELECT hidden, acl_id, acl_type, memacl_id, memacl_type
285 INTO :flags, :acl_id, :acl_type, :memacl_id, :memacl_type
286 FROM list
287 WHERE name = :listname;
5eaef520 288
289 rowcount = sqlca.sqlerrd[2];
290 if (rowcount > 1)
291 return MR_WILDCARD;
292 if (rowcount == 0)
293 return MR_NO_MATCH;
294 if (!flags)
295 return MR_SUCCESS;
296
297 /* check for client in access control list */
298 status = find_member(acl_type, acl_id, cl);
299 if (!status)
59c3208b 300 {
301 status = find_member(memacl_type, memacl_id, cl);
302 if (!status)
303 return MR_PERM;
304 }
5eaef520 305 return MR_SUCCESS;
73cf66ba 306}
307
308
309/* access_member - allow user to access member of type "USER" and name matches
f3c08a60 310 * username, or to access member of type "KERBEROS" and the principal matches
311 * the user, or to access member of type "LIST" and list is one that user is
73cf66ba 312 * on the acl of, or the list is visible.
313 */
314
5eaef520 315int access_member(struct query *q, char *argv[], client *cl)
73cf66ba 316{
5eaef520 317 if (!strcmp(argv[0], "LIST") || !strcmp(argv[0], "RLIST"))
318 return access_visible_list(q, &argv[1], cl);
73cf66ba 319
5eaef520 320 if (!strcmp(argv[0], "USER") || !strcmp(argv[0], "RUSER"))
321 {
322 if (cl->users_id == *(int *)argv[1])
323 return MR_SUCCESS;
73cf66ba 324 }
325
5eaef520 326 if (!strcmp(argv[0], "KERBEROS") || !strcmp(argv[0], "RKERBEROS"))
327 {
328 if (cl->client_id == -*(int *)argv[1])
329 return MR_SUCCESS;
73cf66ba 330 }
331
5eaef520 332 return MR_PERM;
73cf66ba 333}
334
335
336/* access_qgli - special access routine for Qualified_get_lists. Allows
337 * access iff argv[0] == "TRUE" and argv[2] == "FALSE".
338 */
339
5eaef520 340int access_qgli(struct query *q, char *argv[], client *cl)
73cf66ba 341{
5eaef520 342 if (!strcmp(argv[0], "TRUE") && !strcmp(argv[2], "FALSE"))
343 return MR_SUCCESS;
344 return MR_PERM;
73cf66ba 345}
346
347
348/* access_service - allow access if user is on ACL of service. Don't
349 * allow access if a wildcard is used.
350 */
351
5eaef520 352int access_service(struct query *q, char *argv[], client *cl)
73cf66ba 353{
5eaef520 354 EXEC SQL BEGIN DECLARE SECTION;
355 int acl_id;
e688520a 356 char *name, acl_type[LIST_ACL_TYPE_SIZE];
5eaef520 357 EXEC SQL END DECLARE SECTION;
358 int status;
359 char *c;
360
361 name = argv[0];
362 for (c = name; *c; c++)
363 {
364 if (islower(*c))
365 *c = toupper(*c);
366 }
367 EXEC SQL SELECT acl_id, acl_type INTO :acl_id, :acl_type FROM servers
368 WHERE name = :name;
369 if (sqlca.sqlerrd[2] > 1)
370 return MR_PERM;
371
372 /* check for client in access control list */
373 status = find_member(acl_type, acl_id, cl);
374 if (!status)
375 return MR_PERM;
376
377 return MR_SUCCESS;
73cf66ba 378}
379
380
381/* access_filesys - verify that client is owner or on owners list of filesystem
382 * named by argv[0]
383 */
384
5eaef520 385int access_filesys(struct query *q, char *argv[], client *cl)
73cf66ba 386{
5eaef520 387 EXEC SQL BEGIN DECLARE SECTION;
388 int users_id, list_id;
389 char *name;
390 EXEC SQL END DECLARE SECTION;
391 int status;
392
393 name = argv[0];
394 EXEC SQL SELECT owner, owners INTO :users_id, :list_id FROM filesys
395 WHERE label = :name;
396
397 if (sqlca.sqlerrd[2] != 1)
398 return MR_PERM;
399 if (users_id == cl->users_id)
400 return MR_SUCCESS;
401 status = find_member("LIST", list_id, cl);
402 if (status)
403 return MR_SUCCESS;
404 else
405 return MR_PERM;
73cf66ba 406}
407
1beb5e23 408
409/* access_host - successful if owner of host, or subnet containing host
410 */
411
5eaef520 412int access_host(struct query *q, char *argv[], client *cl)
1beb5e23 413{
5eaef520 414 EXEC SQL BEGIN DECLARE SECTION;
4f6b1a05 415 int mid, sid, id, subnet_status;
e688520a 416 char mtype[MACHINE_OWNER_TYPE_SIZE], stype[SUBNET_OWNER_TYPE_SIZE];
4f6b1a05 417 char *account_number;
5eaef520 418 EXEC SQL END DECLARE SECTION;
e4ae0190 419 int status, idx;
420
421 if (q->version < 6)
422 idx = 0;
4f6b1a05 423 else if (q->version >= 6 && q->version < 8)
e4ae0190 424 idx = 1;
4f6b1a05 425 else
426 idx = 2;
427
17f090e1 428 if (q->type == RETRIEVE)
429 {
430 if (strcmp(argv[0], "*") || strcmp(argv[1], "*") ||
431 strcmp(argv[2], "*") || strcmp(argv[3], "*"))
432 return MR_SUCCESS;
433 else
434 return MR_PERM;
435 }
9e252e6f 436
5eaef520 437 if (q->type == APPEND)
438 {
17f090e1 439 /* Non-query owner must set use to zero */
e4ae0190 440 if (atoi(argv[6 + idx]) != 0)
17f090e1 441 return MR_PERM;
442
9e252e6f 443 /* ... and start the hostname with a letter */
444 if (isdigit(argv[0][0]))
445 return MR_BAD_CHAR;
446
e4ae0190 447 id = *(int *)argv[8 + idx];
4f6b1a05 448 EXEC SQL SELECT s.owner_type, s.owner_id, s.status
449 INTO :stype, :sid, :subnet_status FROM subnet s
5eaef520 450 WHERE s.snet_id = :id;
451 mid = 0;
17f090e1 452
4f6b1a05 453 /* Non query owner must provide valid billing information. */
454 if (q->version >= 8)
455 {
456 if (subnet_status == SNET_STATUS_BILLABLE)
457 {
458 account_number = argv[7];
459 EXEC SQL SELECT account_number FROM accountnumbers
460 WHERE account_number = :account_number;
461 if (sqlca.sqlcode == SQL_NO_MATCH)
462 return MR_ACCOUNT_NUMBER;
463 }
464 }
465
17f090e1 466 if (find_member(stype, sid, cl))
5eaef520 467 return MR_SUCCESS;
468 else
469 return MR_PERM;
470 }
17f090e1 471 else /* q-type == UPDATE */
5eaef520 472 {
17f090e1 473 EXEC SQL BEGIN DECLARE SECTION;
474 int status, acomment, use, ocomment, snid;
e688520a 475 char contact[MACHINE_CONTACT_SIZE], address[MACHINE_ADDRESS_SIZE];
9e252e6f 476 char name[MACHINE_NAME_SIZE];
e4ae0190 477 char billing_contact[MACHINE_BILLING_CONTACT_SIZE];
17f090e1 478 EXEC SQL END DECLARE SECTION;
479
5eaef520 480 id = *(int *)argv[0];
e4ae0190 481 EXEC SQL SELECT m.name, m.use, m.contact, m.billing_contact, m.status,
482 m.address, m.owner_type, m.owner_id, m.acomment, m.ocomment, m.snet_id,
4f6b1a05 483 s.owner_type, s.owner_id, s.status INTO :name, :use, :contact,
484 :billing_contact, :status, :address, :mtype, :mid, :acomment,
485 :ocomment, :snid, :stype, :sid, :subnet_status
17f090e1 486 FROM machine m, subnet s
487 WHERE m.mach_id = :id AND s.snet_id = m.snet_id;
488 if (dbms_errno)
489 return mr_errcode;
490
4f6b1a05 491 /* Non query owner must provide valid billing information. */
492 if (q->version >= 8)
493 {
c862fa4e 494 if ((subnet_status == SNET_STATUS_BILLABLE) &&
495 (atoi(argv[10]) != 3))
4f6b1a05 496 {
497 account_number = argv[8];
498 EXEC SQL SELECT account_number FROM accountnumbers
499 WHERE account_number = :account_number;
500 if (sqlca.sqlcode == SQL_NO_MATCH)
501 return MR_ACCOUNT_NUMBER;
502 }
503 }
504
17f090e1 505 /* non-query-owner cannot change use or ocomment */
e4ae0190 506 if ((use != atoi(argv[7 + idx])) || (ocomment != *(int *)argv[14 + idx]))
17f090e1 507 return MR_PERM;
508
9e252e6f 509 /* or rename to start with digit */
510 if (isdigit(argv[1][0]) && strcmp(strtrim(name), argv[1]))
511 return MR_BAD_CHAR;
512
17f090e1 513 if (!find_member(stype, sid, cl))
514 {
515 if (find_member(mtype, mid, cl))
516 {
517 /* host owner also cannot change contact, status, address,
518 owner, or acomment */
7617c632 519 if (strcmp(argv[6], strtrim(contact)) ||
e4ae0190 520 (status != atoi(argv[8 + idx])) ||
521 strcmp(argv[10 + idx], strtrim(address)) ||
522 strcmp(argv[11 + idx], strtrim(mtype)) ||
523 (mid != *(int *)argv[12 + idx]) ||
524 (acomment != *(int *)argv[13 + idx]))
17f090e1 525 return MR_PERM;
e4ae0190 526 /* Billing contact field didn't appear until version 6 */
527 if (q->version >= 6)
7617c632 528 if (strcmp(argv[7], strtrim(billing_contact)))
e4ae0190 529 return MR_PERM;
17f090e1 530 }
531 else
532 return MR_PERM;
533 }
534
535 /* If moving to a new subnet, make sure user is on acl there */
e4ae0190 536 id = *(int *)argv[9 + idx];
17f090e1 537 if (id != snid)
538 {
539 EXEC SQL SELECT owner_type, owner_id INTO :stype, :sid
540 FROM subnet WHERE snet_id=:id;
541 if (!find_member(stype, sid, cl))
542 return MR_PERM;
543 }
5eaef520 544
5eaef520 545 return MR_SUCCESS;
1beb5e23 546 }
1beb5e23 547}
548
549
550/* access_ahal - check for adding a host alias.
551 * successful if host has less then 2 aliases and (client is owner of
552 * host or subnet).
553 * If deleting an alias, any owner will do.
554 */
555
5eaef520 556int access_ahal(struct query *q, char *argv[], client *cl)
1beb5e23 557{
5eaef520 558 EXEC SQL BEGIN DECLARE SECTION;
559 int cnt, id, mid, sid;
e688520a 560 char mtype[MACHINE_OWNER_TYPE_SIZE], stype[SUBNET_OWNER_TYPE_SIZE];
5eaef520 561 EXEC SQL END DECLARE SECTION;
562 int status;
563
564 if (q->type == RETRIEVE)
565 return MR_SUCCESS;
566
567 id = *(int *)argv[1];
568
9e252e6f 569 if (q->type == APPEND && isdigit(argv[0][0]))
570 return MR_BAD_CHAR;
571
5eaef520 572 EXEC SQL SELECT count(name) INTO :cnt from hostalias WHERE mach_id = :id;
573 if (dbms_errno)
574 return mr_errcode;
575 /* if the type is APPEND, this is ahal and we need to make sure there
576 * will be no more than 2 aliases. If it's not, it must be dhal and
577 * any owner will do.
578 */
579 if (q->type == APPEND && cnt >= 2)
580 return MR_PERM;
581 EXEC SQL SELECT m.owner_type, m.owner_id, s.owner_type, s.owner_id
582 INTO :mtype, :mid, :stype, :sid FROM machine m, subnet s
583 WHERE m.mach_id = :id and s.snet_id = m.snet_id;
584 status = find_member(mtype, mid, cl);
585 if (status)
586 return MR_SUCCESS;
587 status = find_member(stype, sid, cl);
588 if (status)
589 return MR_SUCCESS;
590 else
591 return MR_PERM;
1beb5e23 592}
7cf83f0f 593
594
7cf83f0f 595/* access_snt - check for retrieving network structure
596 */
597
5eaef520 598int access_snt(struct query *q, char *argv[], client *cl)
7cf83f0f 599{
5eaef520 600 if (q->type == RETRIEVE)
601 return MR_SUCCESS;
7cf83f0f 602
5eaef520 603 return MR_PERM;
7cf83f0f 604}
1a9a0a59 605
606
607/* access_printer */
608int access_printer(struct query *q, char *argv[], client *cl)
609{
610 EXEC SQL BEGIN DECLARE SECTION;
611 char type[PRINTSERVERS_OWNER_TYPE_SIZE];
612 int id, mach_id;
613 EXEC SQL END DECLARE SECTION;
614 int status;
615
616 mach_id = *(int *)argv[PRN_RM];
617 EXEC SQL SELECT owner_type, owner_id INTO :type, :id
618 FROM printservers WHERE mach_id = :mach_id;
619 if (sqlca.sqlcode)
620 return MR_PERM;
621
622 status = find_member(type, id, cl);
623 if (status)
624 return MR_SUCCESS;
625 else
626 return MR_PERM;
627}
d7ddc011 628
629/* access_zephyr */
630int access_zephyr(struct query *q, char *argv[], client *cl)
631{
632 EXEC SQL BEGIN DECLARE SECTION;
633 char type[ZEPHYR_OWNER_TYPE_SIZE];
634 char *class;
635 int id;
636 EXEC SQL END DECLARE SECTION;
637 int status;
638
639 class = argv[ZA_CLASS];
640 EXEC SQL SELECT owner_type, owner_id INTO :type, :id
641 FROM zephyr WHERE class = :class;
642 if (sqlca.sqlcode)
643 return MR_PERM;
644
645 status = find_member(type, id, cl);
646 if (status)
647 return MR_SUCCESS;
648 else
649 return MR_PERM;
650}
651
2fb668b0 652/* access_container - check access for most container operations
653 *
654 * Inputs: argv[0] - cnt_id
655 * q - query name
656 * cl - client name
657 *
658 * - check if that client is a member of the access control list
659 * - OR, if the query is add_machine_to_container or delete_machine_from_container
660 * check if the client is a memeber of the mem_acl list
661 * - if the query is update_container and the container is to be renamed and
662 * it is a top-level container, only priviledged users can do it
663 */
664
665int access_container(struct query *q, char *argv[], client *cl)
666{
667 EXEC SQL BEGIN DECLARE SECTION;
668 int cnt_id, acl_id, memacl_id;
669 char acl_type[CONTAINERS_ACL_TYPE_SIZE], memacl_type[CONTAINERS_ACL_TYPE_SIZE];
670 char name[CONTAINERS_NAME_SIZE], *newname;
671 EXEC SQL END DECLARE SECTION;
672 int status;
673
674 cnt_id = *(int *)argv[0];
675
676 /* if amcn or dmcn, container id is the second argument */
677 if (strcmp(q->shortname, "amcn") == 0 || strcmp(q->shortname, "dmcn") == 0)
678 cnt_id = *(int *)argv[1];
679
680 EXEC SQL SELECT acl_id, acl_type, memacl_id, memacl_type, name
681 INTO :acl_id, :acl_type, :memacl_id, :memacl_type, :name
682 FROM containers
683 WHERE cnt_id = :cnt_id;
684
685 if (sqlca.sqlerrd[2] != 1)
686 return MR_INTERNAL;
687
688 /* trim off the trailing spaces */
689 strcpy(name, strtrim(name));
690
691 /* if the query is update_container and the containers is to be renamed
692 * and it is a top-level container, only dbadmin can do it */
693 if (!strcmp(q->shortname, "ucon"))
694 {
695 newname = argv[1];
696 if (strcmp(name, newname) && strchr(name, '/') == NULL)
697 return MR_PERM;
698 }
699
700 /* check for client in access control list and return success right
701 * away if it's there. */
702 if (find_member(acl_type, acl_id, cl))
703 return MR_SUCCESS;
704
705 /* If not amcn, dmcn, we lose. */
706 if (strcmp(q->shortname, "amcn") && strcmp(q->shortname, "dmcn"))
707 return MR_PERM;
708
709 if (find_member(memacl_type, memacl_id, cl))
710 return MR_SUCCESS;
711
712 /* Otherwise fail. */
713 return MR_PERM;
714}
This page took 0.181213 seconds and 5 git commands to generate.