]> andersk Git - moira.git/blame - server/qaccess.pc
Add sponsor_type/sponsor_id column to users table, and client support for manipulatin...
[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
5eaef520 489 if (q->type == APPEND)
490 {
17f090e1 491 /* Non-query owner must set use to zero */
e4ae0190 492 if (atoi(argv[6 + idx]) != 0)
17f090e1 493 return MR_PERM;
494
9e252e6f 495 /* ... and start the hostname with a letter */
496 if (isdigit(argv[0][0]))
497 return MR_BAD_CHAR;
498
e4ae0190 499 id = *(int *)argv[8 + idx];
4f6b1a05 500 EXEC SQL SELECT s.owner_type, s.owner_id, s.status
501 INTO :stype, :sid, :subnet_status FROM subnet s
5eaef520 502 WHERE s.snet_id = :id;
503 mid = 0;
17f090e1 504
4f6b1a05 505 /* Non query owner must provide valid billing information. */
506 if (q->version >= 8)
507 {
508 if (subnet_status == SNET_STATUS_BILLABLE)
509 {
510 account_number = argv[7];
511 EXEC SQL SELECT account_number FROM accountnumbers
512 WHERE account_number = :account_number;
513 if (sqlca.sqlcode == SQL_NO_MATCH)
514 return MR_ACCOUNT_NUMBER;
515 }
516 }
517
17f090e1 518 if (find_member(stype, sid, cl))
5eaef520 519 return MR_SUCCESS;
520 else
521 return MR_PERM;
522 }
17f090e1 523 else /* q-type == UPDATE */
5eaef520 524 {
17f090e1 525 EXEC SQL BEGIN DECLARE SECTION;
526 int status, acomment, use, ocomment, snid;
e688520a 527 char contact[MACHINE_CONTACT_SIZE], address[MACHINE_ADDRESS_SIZE];
9e252e6f 528 char name[MACHINE_NAME_SIZE];
e4ae0190 529 char billing_contact[MACHINE_BILLING_CONTACT_SIZE];
17f090e1 530 EXEC SQL END DECLARE SECTION;
531
5eaef520 532 id = *(int *)argv[0];
e4ae0190 533 EXEC SQL SELECT m.name, m.use, m.contact, m.billing_contact, m.status,
534 m.address, m.owner_type, m.owner_id, m.acomment, m.ocomment, m.snet_id,
4f6b1a05 535 s.owner_type, s.owner_id, s.status INTO :name, :use, :contact,
536 :billing_contact, :status, :address, :mtype, :mid, :acomment,
537 :ocomment, :snid, :stype, :sid, :subnet_status
17f090e1 538 FROM machine m, subnet s
539 WHERE m.mach_id = :id AND s.snet_id = m.snet_id;
540 if (dbms_errno)
541 return mr_errcode;
542
4f6b1a05 543 /* Non query owner must provide valid billing information. */
544 if (q->version >= 8)
545 {
c862fa4e 546 if ((subnet_status == SNET_STATUS_BILLABLE) &&
547 (atoi(argv[10]) != 3))
4f6b1a05 548 {
549 account_number = argv[8];
550 EXEC SQL SELECT account_number FROM accountnumbers
551 WHERE account_number = :account_number;
552 if (sqlca.sqlcode == SQL_NO_MATCH)
553 return MR_ACCOUNT_NUMBER;
554 }
555 }
556
17f090e1 557 /* non-query-owner cannot change use or ocomment */
e4ae0190 558 if ((use != atoi(argv[7 + idx])) || (ocomment != *(int *)argv[14 + idx]))
17f090e1 559 return MR_PERM;
560
9e252e6f 561 /* or rename to start with digit */
562 if (isdigit(argv[1][0]) && strcmp(strtrim(name), argv[1]))
563 return MR_BAD_CHAR;
564
17f090e1 565 if (!find_member(stype, sid, cl))
566 {
567 if (find_member(mtype, mid, cl))
568 {
569 /* host owner also cannot change contact, status, address,
570 owner, or acomment */
7617c632 571 if (strcmp(argv[6], strtrim(contact)) ||
e4ae0190 572 (status != atoi(argv[8 + idx])) ||
573 strcmp(argv[10 + idx], strtrim(address)) ||
574 strcmp(argv[11 + idx], strtrim(mtype)) ||
575 (mid != *(int *)argv[12 + idx]) ||
576 (acomment != *(int *)argv[13 + idx]))
17f090e1 577 return MR_PERM;
e4ae0190 578 /* Billing contact field didn't appear until version 6 */
579 if (q->version >= 6)
7617c632 580 if (strcmp(argv[7], strtrim(billing_contact)))
e4ae0190 581 return MR_PERM;
17f090e1 582 }
583 else
584 return MR_PERM;
585 }
586
587 /* If moving to a new subnet, make sure user is on acl there */
e4ae0190 588 id = *(int *)argv[9 + idx];
17f090e1 589 if (id != snid)
590 {
591 EXEC SQL SELECT owner_type, owner_id INTO :stype, :sid
592 FROM subnet WHERE snet_id=:id;
593 if (!find_member(stype, sid, cl))
594 return MR_PERM;
595 }
5eaef520 596
5eaef520 597 return MR_SUCCESS;
1beb5e23 598 }
1beb5e23 599}
600
601
602/* access_ahal - check for adding a host alias.
603 * successful if host has less then 2 aliases and (client is owner of
604 * host or subnet).
605 * If deleting an alias, any owner will do.
606 */
607
5eaef520 608int access_ahal(struct query *q, char *argv[], client *cl)
1beb5e23 609{
5eaef520 610 EXEC SQL BEGIN DECLARE SECTION;
611 int cnt, id, mid, sid;
e688520a 612 char mtype[MACHINE_OWNER_TYPE_SIZE], stype[SUBNET_OWNER_TYPE_SIZE];
5eaef520 613 EXEC SQL END DECLARE SECTION;
614 int status;
615
616 if (q->type == RETRIEVE)
617 return MR_SUCCESS;
618
619 id = *(int *)argv[1];
620
9e252e6f 621 if (q->type == APPEND && isdigit(argv[0][0]))
622 return MR_BAD_CHAR;
623
5eaef520 624 EXEC SQL SELECT count(name) INTO :cnt from hostalias WHERE mach_id = :id;
625 if (dbms_errno)
626 return mr_errcode;
627 /* if the type is APPEND, this is ahal and we need to make sure there
628 * will be no more than 2 aliases. If it's not, it must be dhal and
629 * any owner will do.
630 */
631 if (q->type == APPEND && cnt >= 2)
632 return MR_PERM;
633 EXEC SQL SELECT m.owner_type, m.owner_id, s.owner_type, s.owner_id
634 INTO :mtype, :mid, :stype, :sid FROM machine m, subnet s
635 WHERE m.mach_id = :id and s.snet_id = m.snet_id;
636 status = find_member(mtype, mid, cl);
637 if (status)
638 return MR_SUCCESS;
639 status = find_member(stype, sid, cl);
640 if (status)
641 return MR_SUCCESS;
642 else
643 return MR_PERM;
1beb5e23 644}
7cf83f0f 645
646
7cf83f0f 647/* access_snt - check for retrieving network structure
648 */
649
5eaef520 650int access_snt(struct query *q, char *argv[], client *cl)
7cf83f0f 651{
5eaef520 652 if (q->type == RETRIEVE)
653 return MR_SUCCESS;
7cf83f0f 654
5eaef520 655 return MR_PERM;
7cf83f0f 656}
1a9a0a59 657
658
659/* access_printer */
660int access_printer(struct query *q, char *argv[], client *cl)
661{
662 EXEC SQL BEGIN DECLARE SECTION;
663 char type[PRINTSERVERS_OWNER_TYPE_SIZE];
664 int id, mach_id;
665 EXEC SQL END DECLARE SECTION;
666 int status;
667
668 mach_id = *(int *)argv[PRN_RM];
669 EXEC SQL SELECT owner_type, owner_id INTO :type, :id
670 FROM printservers WHERE mach_id = :mach_id;
671 if (sqlca.sqlcode)
672 return MR_PERM;
673
674 status = find_member(type, id, cl);
675 if (status)
676 return MR_SUCCESS;
677 else
678 return MR_PERM;
679}
d7ddc011 680
681/* access_zephyr */
682int access_zephyr(struct query *q, char *argv[], client *cl)
683{
684 EXEC SQL BEGIN DECLARE SECTION;
685 char type[ZEPHYR_OWNER_TYPE_SIZE];
686 char *class;
687 int id;
688 EXEC SQL END DECLARE SECTION;
689 int status;
690
691 class = argv[ZA_CLASS];
692 EXEC SQL SELECT owner_type, owner_id INTO :type, :id
693 FROM zephyr WHERE class = :class;
694 if (sqlca.sqlcode)
695 return MR_PERM;
696
697 status = find_member(type, id, cl);
698 if (status)
699 return MR_SUCCESS;
700 else
701 return MR_PERM;
702}
703
2fb668b0 704/* access_container - check access for most container operations
705 *
706 * Inputs: argv[0] - cnt_id
707 * q - query name
708 * cl - client name
709 *
710 * - check if that client is a member of the access control list
711 * - OR, if the query is add_machine_to_container or delete_machine_from_container
712 * check if the client is a memeber of the mem_acl list
713 * - if the query is update_container and the container is to be renamed and
714 * it is a top-level container, only priviledged users can do it
715 */
716
717int access_container(struct query *q, char *argv[], client *cl)
718{
719 EXEC SQL BEGIN DECLARE SECTION;
73155abd 720 int cnt_id, acl_id, memacl_id, mach_id, machine_owner_id, flag;
2fb668b0 721 char acl_type[CONTAINERS_ACL_TYPE_SIZE], memacl_type[CONTAINERS_ACL_TYPE_SIZE];
722 char name[CONTAINERS_NAME_SIZE], *newname;
73155abd 723 char machine_owner_type[MACHINE_OWNER_TYPE_SIZE];
2fb668b0 724 EXEC SQL END DECLARE SECTION;
725 int status;
726
727 cnt_id = *(int *)argv[0];
728
729 /* if amcn or dmcn, container id is the second argument */
730 if (strcmp(q->shortname, "amcn") == 0 || strcmp(q->shortname, "dmcn") == 0)
73155abd 731 {
732 mach_id = *(int *)argv[0];
2fb668b0 733 cnt_id = *(int *)argv[1];
73155abd 734 }
2fb668b0 735
73155abd 736 EXEC SQL SELECT acl_id, acl_type, memacl_id, memacl_type, name, publicflg
737 INTO :acl_id, :acl_type, :memacl_id, :memacl_type, :name, :flag
2fb668b0 738 FROM containers
739 WHERE cnt_id = :cnt_id;
740
741 if (sqlca.sqlerrd[2] != 1)
742 return MR_INTERNAL;
743
744 /* trim off the trailing spaces */
745 strcpy(name, strtrim(name));
746
747 /* if the query is update_container and the containers is to be renamed
748 * and it is a top-level container, only dbadmin can do it */
749 if (!strcmp(q->shortname, "ucon"))
750 {
751 newname = argv[1];
752 if (strcmp(name, newname) && strchr(name, '/') == NULL)
753 return MR_PERM;
754 }
755
756 /* check for client in access control list and return success right
757 * away if it's there. */
758 if (find_member(acl_type, acl_id, cl))
759 return MR_SUCCESS;
760
761 /* If not amcn, dmcn, we lose. */
762 if (strcmp(q->shortname, "amcn") && strcmp(q->shortname, "dmcn"))
763 return MR_PERM;
764
765 if (find_member(memacl_type, memacl_id, cl))
766 return MR_SUCCESS;
767
73155abd 768 /* if the container is public or the query is delete, grant access if client
769 * is on owner list */
770 if (flag || q->type == DELETE)
771 {
772 EXEC SQL SELECT owner_type, owner_id INTO :machine_owner_type,
773 :machine_owner_id
774 FROM machine
775 WHERE mach_id = :mach_id;
776
777 if (sqlca.sqlerrd[2] == 1 && strcmp("NONE", machine_owner_type) &&
778 find_member(machine_owner_type, machine_owner_id, cl))
779 return MR_SUCCESS;
780 }
2fb668b0 781 /* Otherwise fail. */
782 return MR_PERM;
783}
This page took 4.73776 seconds and 5 git commands to generate.