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