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