]> andersk Git - moira.git/blame - server/qsupport.qc
removed lists for caching access control
[moira.git] / server / qsupport.qc
CommitLineData
05cdd922 1/*
2 * $Source$
3 * $Author$
4 * $Header$
5 *
6 * Copyright (C) 1987 by the Massachusetts Institute of Technology
c801de4c 7 * For copying and distribution information, please see the file
8 * <mit-copyright.h>.
05cdd922 9 *
05cdd922 10 */
11
12#ifndef lint
13static char *rcsid_qsupport_qc = "$Header$";
14#endif lint
15
c801de4c 16#include <mit-copyright.h>
05cdd922 17#include "query.h"
18#include "sms_server.h"
19#include <ctype.h>
20
05cdd922 21
822a6eba 22extern char *whoami, *strsave();
e1795ce1 23extern int ingres_errno, sms_errcode;
822a6eba 24
05cdd922 25
26/* Specialized Access Routines */
27
822a6eba 28/* access_user - verify that client name equals specified login name
29 *
30 * - since field validation routines are called first, a users_id is
31 * now in argv[0] instead of the login name.
32 */
05cdd922 33
34access_user(q, argv, cl)
35 struct query *q;
36 char *argv[];
37 client *cl;
822a6eba 38{
39 if (cl->users_id != *(int *)argv[0])
40 return(SMS_PERM);
41 else
42 return(SMS_SUCCESS);
43}
05cdd922 44
05cdd922 45
30967516 46
822a6eba 47/* access_login - verify that client name equals specified login name
48 *
49 * argv[0...n] contain search info. q->
50 */
51
52access_login(q, argv, cl)
30967516 53 struct query *q;
54 char *argv[];
55 client *cl;
56##{
822a6eba 57## int rowcount, id;
58## char qual[256];
59
60 build_qual(q->qual, q->argc, argv, qual);
711660a5 61## range of u is users
822a6eba 62## retrieve (id = u.users_id) where qual
63## inquire_equel(rowcount = "rowcount")
64 if (rowcount != 1 || id != cl->users_id)
65 return(SMS_PERM);
66 else
67 return(SMS_SUCCESS);
30967516 68##}
69
822a6eba 70
71
72/* access_list - check access for most list operations
73 *
74 * Inputs: argv[0] - list_id
75 * q - query name
76 * argv[2] - member ID (only for queries "amtl" and "dmfl")
4179b9ce 77 * argv[7] - group IID (only for query "ulis")
78 * cl - client name
822a6eba 79 *
80 * - check that client is a member of the access control list
81 * - OR, if the query is add_member_to_list or delete_member_from_list
82 * and the list is public, allow access if client = member
83 */
05cdd922 84
85access_list(q, argv, cl)
86 struct query *q;
87 char *argv[];
88 client *cl;
89##{
4179b9ce 90## int list_id, acl_id, flags, rowcount, gid;
822a6eba 91## char acl_type[9];
05cdd922 92 char *client_type;
822a6eba 93 int client_id, status;
05cdd922 94
95 list_id = *(int *)argv[0];
822a6eba 96## repeat retrieve (acl_id = list.#acl_id, acl_type = list.#acl_type,
4179b9ce 97## gid = list.#gid, flags = list.#public)
05cdd922 98## where list.#list_id = @list_id
822a6eba 99## inquire_equel(rowcount = "rowcount")
100 if (rowcount != 1)
101 return(SMS_INTERNAL);
05cdd922 102
103 /* parse client structure */
822a6eba 104 if ((status = get_client(cl, &client_type, &client_id)) != SMS_SUCCESS)
105 return(status);
05cdd922 106
107 /* if amtl or dmfl and list is public allow client to add or delete self */
a6683dad 108 if (((!strcmp("amtl", q->shortname) && flags) ||
109 (!strcmp("dmfl", q->shortname))) &&
110 (!strcmp("USER", argv[1]))) {
822a6eba 111 if (*(int *)argv[2] == client_id) return(SMS_SUCCESS);
4179b9ce 112 /* if update_list, don't allow them to change the GID */
113 } else if (!strcmp("ulis", q->shortname)) {
114 if ((!strcmp(argv[7], UNIQUE_GID) && (gid != -1)) ||
115 (strcmp(argv[7], UNIQUE_GID) && (gid != atoi(argv[7]))))
116 return(SMS_PERM);
05cdd922 117 }
118
711660a5 119 if (!strcmp(strtrim(acl_type), "LIST")) {
120 if (!client_is_member(cl, acl_id))
121 return(SMS_PERM);
122 else
123 return(SMS_SUCCESS);
124 }
125
05cdd922 126 /* check for client in access control list */
822a6eba 127 status = find_member(acl_type, acl_id, client_type, client_id, 0);
128 if (!status) return(SMS_PERM);
05cdd922 129
130 return(SMS_SUCCESS);
131##}
92a943d6 132
a6cb4d4c 133
822a6eba 134/* access_visible_list - allow access to list only if it is not hidden,
135 * or if the client is on the ACL
136 *
137 * Inputs: argv[0] - list_id
138 * cl - client identifier
139 */
140
141access_visible_list(q, argv, cl)
a6cb4d4c 142 struct query *q;
143 char *argv[];
144 client *cl;
145##{
822a6eba 146## int list_id, acl_id, flags, rowcount;
147## char acl_type[9];
148 char *client_type;
149 int client_id, status;
a6cb4d4c 150
151 list_id = *(int *)argv[0];
822a6eba 152## repeat retrieve (flags = list.hidden, acl_id = list.#acl_id,
153## acl_type = list.#acl_type) where list.#list_id = @list_id
154## inquire_equel(rowcount = "rowcount")
155 if (rowcount != 1)
156 return(SMS_INTERNAL);
157 if (!flags)
158 return(SMS_SUCCESS);
159
711660a5 160
161 if (!strcmp(strtrim(acl_type), "LIST")) {
162 if (!client_is_member(cl, acl_id))
163 return(SMS_PERM);
164 else
165 return(SMS_SUCCESS);
166 }
167
822a6eba 168 /* parse client structure */
169 if ((status = get_client(cl, &client_type, &client_id)) != SMS_SUCCESS)
170 return(status);
171
172 /* check for client in access control list */
173 status = find_member(acl_type, acl_id, client_type, client_id, 0);
174 if (!status)
175 return(SMS_PERM);
176
177 return(SMS_SUCCESS);
a6cb4d4c 178##}
179
92a943d6 180
822a6eba 181/* access_vis_list_by_name - allow access to list only if it is not hidden,
182 * or if the client is on the ACL
183 *
184 * Inputs: argv[0] - list name
185 * cl - client identifier
186 */
187
188access_vis_list_by_name(q, argv, cl)
92a943d6 189 struct query *q;
190 char *argv[];
191 client *cl;
92a943d6 192##{
822a6eba 193## int acl_id, flags, rowcount;
194## char acl_type[9], *listname;
195 char *client_type;
196 int client_id, status;
197
198 listname = argv[0];
199## repeat retrieve (flags = list.hidden, acl_id = list.#acl_id,
200## acl_type = list.#acl_type) where list.#name = @listname
201## inquire_equel(rowcount = "rowcount");
202 if (rowcount > 1)
203 return(SMS_WILDCARD);
204 if (rowcount == 0)
205 return(SMS_NO_MATCH);
206 if (!flags)
207 return(SMS_SUCCESS);
92a943d6 208
711660a5 209 if (!strcmp(strtrim(acl_type), "LIST")) {
210 if (!client_is_member(cl, acl_id))
211 return(SMS_PERM);
212 else
213 return(SMS_SUCCESS);
214 }
215
822a6eba 216 /* parse client structure */
217 if ((status = get_client(cl, &client_type, &client_id)) != SMS_SUCCESS)
218 return(status);
219
220 /* check for client in access control list */
221 status = find_member(acl_type, acl_id, client_type, client_id, 0);
222 if (!status)
223 return(SMS_PERM);
224
225 return(SMS_SUCCESS);
92a943d6 226##}
05cdd922 227
822a6eba 228
229/* access_member - allow user to access member of type "USER" and name matches
230 * username, or to access member of type "LIST" and list is one that user is
231 * on the acl of, or the list is visible.
232 */
233
234access_member(q, argv, cl)
05cdd922 235 struct query *q;
822a6eba 236 char *argv[];
05cdd922 237 client *cl;
822a6eba 238{
239 if (!strcmp(argv[0], "LIST") || !strcmp(argv[0], "RLIST"))
240 return(access_visible_list(q, &argv[1], cl));
05cdd922 241
822a6eba 242 if (!strcmp(argv[0], "USER") || !strcmp(argv[0], "RUSER")) {
4179b9ce 243 if (cl->users_id == *(int *)argv[1])
822a6eba 244 return(SMS_SUCCESS);
05cdd922 245 }
246
822a6eba 247 return(SMS_PERM);
248}
05cdd922 249
05cdd922 250
822a6eba 251/* access_qgli - special access routine for Qualified_get_lists. Allows
252 * access iff argv[0] == "TRUE" and argv[2] == "FALSE".
253 */
254
255access_qgli(q, argv, cl)
256 struct query *q;
257 char *argv[];
258 client *cl;
259{
260 if (!strcmp(argv[0], "TRUE") && !strcmp(argv[2], "FALSE"))
261 return(SMS_SUCCESS);
262 return(SMS_PERM);
263}
264
265
266/* access_service - allow access if user is on ACL of service. Don't
267 * allow access if a wildcard is used.
268 */
05cdd922 269
822a6eba 270access_service(q, argv, cl)
05cdd922 271 struct query *q;
272 char *argv[];
822a6eba 273 client *cl;
05cdd922 274##{
822a6eba 275## int acl_id, rowcount;
276## char *name, acl_type[9];
277 int client_id, status;
278 char *client_type;
05cdd922 279
822a6eba 280 name = argv[0];
281## repeat retrieve (acl_id = servers.#acl_id, acl_type = servers.#acl_type)
44bd6f44 282## where servers.#name = uppercase(@name)
822a6eba 283## inquire_equel(rowcount = "rowcount")
284 if (rowcount > 1)
285 return(SMS_PERM);
05cdd922 286
711660a5 287 if (!strcmp(strtrim(acl_type), "LIST")) {
288 if (!client_is_member(cl, acl_id))
289 return(SMS_PERM);
290 else
291 return(SMS_SUCCESS);
292 }
293
822a6eba 294 /* parse client structure */
295 if ((status = get_client(cl, &client_type, &client_id)) != SMS_SUCCESS)
296 return(status);
92a943d6 297
822a6eba 298 /* check for client in access control list */
299 status = find_member(acl_type, acl_id, client_type, client_id, 0);
300 if (!status) return(SMS_PERM);
05cdd922 301
92a943d6 302 return(SMS_SUCCESS);
303##}
304
822a6eba 305
306
307/* access_filesys - verify that client is owner or on owners list of filesystem
308 * named by argv[0]
309 */
310
311access_filesys(q, argv, cl)
92a943d6 312 struct query *q;
313 char *argv[];
822a6eba 314 client *cl;
92a943d6 315##{
822a6eba 316## int rowcount, users_id, list_id;
317## char *name;
318 int status, client_id;
319 char *client_type;
92a943d6 320
822a6eba 321 name = argv[0];
322## repeat retrieve (users_id = filesys.owner, list_id = filesys.owners)
323## where filesys.label = @name
324## inquire_equel(rowcount = "rowcount")
325
326 if (rowcount != 1)
327 return(SMS_PERM);
328 if (users_id == cl->users_id)
329 return(SMS_SUCCESS);
711660a5 330 if (!client_is_member(cl, list_id))
331 return(SMS_PERM);
332 else
822a6eba 333 return(SMS_SUCCESS);
05cdd922 334##}
822a6eba 335
336
05cdd922 337\f
822a6eba 338/* Setup Routines */
339
340/* Setup routine for add_user
341 *
342 * Inputs: argv[0] - login
343 * argv[1] - uid
344 *
345 * Description:
346 *
347 * - if argv[1] == UNIQUE_UID then set argv[1] = next(uid)
348 * - if argv[0] == UNIQUE_LOGIN then set argv[0] = "#<uid>"
349 */
c2408bd5 350
822a6eba 351setup_ausr(q, argv, cl)
c2408bd5 352 struct query *q;
822a6eba 353 register char *argv[];
354 client *cl;
355##{
356## int nuid, rowcount;
357
358 if (!strcmp(argv[1], UNIQUE_UID) || atoi(argv[1]) == -1) {
359 if (set_next_object_id("uid", "users"))
360 return(SMS_INGRES_ERR);
361## repeat retrieve (nuid = values.value) where values.name = "uid"
362## inquire_equel(rowcount = "rowcount")
363 if (rowcount != 1)
364 return(SMS_INTERNAL);
365 sprintf(argv[1], "%d", nuid);
366 }
c2408bd5 367
822a6eba 368 if (!strcmp(argv[0], UNIQUE_LOGIN) || atoi(argv[1]) == -1) {
369 sprintf(argv[0], "#%s", argv[1]);
370 }
c2408bd5 371
822a6eba 372 return(SMS_SUCCESS);
373##}
c2408bd5 374
c2408bd5 375
822a6eba 376/* setup_dusr - verify that the user is no longer being referenced
377 * and may safely be deleted.
378 */
c2408bd5 379
822a6eba 380int setup_dusr(q, argv)
381 struct query *q;
382 char **argv;
383##{
384## int flag, id;
385
386 id = *(int *)argv[0];
331b982e 387
388 /* For now, only allow users to be deleted if their status is 0 */
389## repeat retrieve (flag = u.status) where u.users_id = @id
711660a5 390 if (flag != 0 && flag != 4)
331b982e 391 return(SMS_IN_USE);
392
44bd6f44 393## repeat delete nfsquota where nfsquota.users_id = @id
711660a5 394## repeat delete krbmap where krbmap.users_id = @id
a6683dad 395## repeat retrieve (flag = any(imembers.member_id where imembers.member_id=@id
396## and imembers.member_type = "USER"))
822a6eba 397 if (flag)
398 return(SMS_IN_USE);
399## repeat retrieve (flag = any(filesys.label where filesys.owner=@id))
400 if (flag)
401 return(SMS_IN_USE);
402## repeat retrieve (flag = any(list.name where list.acl_id=@id and
403## list.acl_type = "USER"))
404 if (flag)
405 return(SMS_IN_USE);
406## repeat retrieve (flag = any(servers.name where servers.acl_id=@id and
407## servers.acl_type = "USER"))
408 if (flag)
409 return(SMS_IN_USE);
44bd6f44 410## repeat retrieve (flag=any(hostaccess.acl_id where hostaccess.acl_id=@id and
411## hostaccess.acl_type = "USER"))
412 if (flag)
413 return(SMS_IN_USE);
c2408bd5 414 else
415 return(SMS_SUCCESS);
822a6eba 416##}
c2408bd5 417
822a6eba 418
419/* setup_spop: verify that there is already a valid POP machine_id in the
420 * pop_id field. Also take care of keeping track of the post office usage.
421 */
422int setup_spop(q, argv)
423struct query *q;
424char **argv;
c2408bd5 425##{
e7fa3293 426## int id, mid, flag;
822a6eba 427## char type[9];
428
429 id = *(int *)argv[0];
e7fa3293 430## repeat retrieve (type = u.potype, mid = u.pop_id,
431## flag = any(machine.name where machine.mach_id = u.pop_id
432## and u.pop_id != 0 and u.users_id = @id))
4f16dc86 433## where u.users_id = @id
822a6eba 434 if (!flag)
435 return(SMS_MACHINE);
e7fa3293 436 if (strcmp(strtrim(type), "POP"))
437 set_pop_usage(mid, 1);
822a6eba 438 return(SMS_SUCCESS);
439##}
c2408bd5 440
c2408bd5 441
822a6eba 442/* setup_dpob: Take care of keeping track of the post office usage.
443 */
444int setup_dpob(q, argv)
445struct query *q;
446char **argv;
447##{
448## int id, user;
449## char type[9];
450
451 user = *(int *)argv[0];
452## repeat retrieve (type = u.potype, id = u.pop_id)
453## where u.users_id = @user
c2408bd5 454
e7fa3293 455 if (!strcmp(strtrim(type), "POP"))
822a6eba 456 set_pop_usage(id, -1);
c2408bd5 457 return(SMS_SUCCESS);
458##}
459
c2408bd5 460
822a6eba 461/* setup_dmac - verify that the machine is no longer being referenced
462 * and may safely be deleted.
463 */
c2408bd5 464
822a6eba 465int setup_dmac(q, argv)
05cdd922 466 struct query *q;
822a6eba 467 char **argv;
05cdd922 468##{
822a6eba 469## int flag, id;
470
471 id = *(int *)argv[0];
472## repeat retrieve (flag = any(users.login where users.potype = "POP"
473## and users.pop_id=@id))
474 if (flag)
475 return(SMS_IN_USE);
476## repeat retrieve (flag = any(serverhosts.mach_id
477## where serverhosts.mach_id=@id))
478 if (flag)
479 return(SMS_IN_USE);
480## repeat retrieve (flag = any(nfsphys.mach_id where nfsphys.mach_id=@id))
481 if (flag)
482 return(SMS_IN_USE);
483## repeat retrieve (flag = any(hostaccess.mach_id where hostaccess.mach_id=@id))
484 if (flag)
485 return(SMS_IN_USE);
e7fa3293 486## repeat retrieve (flag = any(printcap.mach_id where printcap.mach_id=@id))
331b982e 487 if (flag)
488 return(SMS_IN_USE);
711660a5 489## repeat retrieve (flag = any(palladium.mach_id where palladium.mach_id=@id))
490 if (flag)
491 return(SMS_IN_USE);
44bd6f44 492
493## repeat delete mcmap where mcmap.mach_id = @id
494 return(SMS_SUCCESS);
05cdd922 495##}
496
05cdd922 497
822a6eba 498/* setup_dclu - verify that the cluster is no longer being referenced
499 * and may safely be deleted.
500 */
05cdd922 501
822a6eba 502int setup_dclu(q, argv)
05cdd922 503 struct query *q;
822a6eba 504 char **argv;
05cdd922 505##{
822a6eba 506## int flag, id;
507
508 id = *(int *)argv[0];
509## repeat retrieve (flag = any(mcmap.mach_id where mcmap.clu_id=@id))
510 if (flag)
511 return(SMS_IN_USE);
512## repeat retrieve (flag = any(svc.clu_id where svc.clu_id=@id))
513 if (flag)
514 return(SMS_IN_USE);
515 else
516 return(SMS_SUCCESS);
05cdd922 517##}
518
05cdd922 519
822a6eba 520/* setup_alis - if argv[5] is non-zero and argv[6] is UNIQUE_ID, then allocate
521 * a new gid and put it in argv[6]. Otherwise if argv[6] is UNIQUE_ID but
522 * argv[5] is not, then remember that UNIQUE_ID is being stored by putting
523 * a -1 there. Remember that this is also used for ulis, with the indexes
524 * at 6 & 7.
525 */
05cdd922 526
822a6eba 527int setup_alis(q, argv)
528struct query *q;
529char **argv;
05cdd922 530##{
822a6eba 531## int ngid;
532 char *malloc();
533 int idx;
534
535 if (!strcmp(q->shortname, "alis"))
536 idx = 6;
537 else if (!strcmp(q->shortname, "ulis"))
538 idx = 7;
539
540 if (!strcmp(argv[idx], UNIQUE_GID) || atoi(argv[idx]) == -1) {
541 if (atoi(argv[idx - 1])) {
542 if (set_next_object_id("gid", "list"))
543 return(SMS_INGRES_ERR);
544## repeat retrieve (ngid = values.value) where values.name = "gid"
545 sprintf(argv[idx], "%d", ngid);
546 } else {
547 strcpy(argv[idx], "-1");
548 }
549 }
05cdd922 550
05cdd922 551 return(SMS_SUCCESS);
552##}
a6cb4d4c 553
822a6eba 554
555/* setup_dlist - verify that the list is no longer being referenced
556 * and may safely be deleted.
557 */
558
559int setup_dlis(q, argv)
a6cb4d4c 560 struct query *q;
822a6eba 561 char **argv;
a6cb4d4c 562##{
822a6eba 563## int flag, id;
564
565 id = *(int *)argv[0];
a6683dad 566## repeat retrieve (flag = any(imembers.member_id where imembers.member_id=@id
567## and imembers.member_type = "LIST"))
822a6eba 568 if (flag)
569 return(SMS_IN_USE);
a6683dad 570## repeat retrieve (flag = any(imembers.member_id where imembers.list_id=@id))
822a6eba 571 if (flag)
572 return(SMS_IN_USE);
573## repeat retrieve (flag = any(filesys.label where filesys.owners=@id))
574 if (flag)
575 return(SMS_IN_USE);
576## repeat retrieve (flag = any(capacls.tag where capacls.list_id=@id))
577 if (flag)
578 return(SMS_IN_USE);
579## repeat retrieve (flag = any(list.name where list.acl_id=@id and
4f16dc86 580## list.acl_type = "LIST" and list.list_id != @id))
822a6eba 581 if (flag)
582 return(SMS_IN_USE);
583## repeat retrieve (flag = any(servers.name where servers.acl_id=@id and
584## servers.acl_type = "LIST"))
585 if (flag)
586 return(SMS_IN_USE);
44bd6f44 587## repeat retrieve (flag=any(hostaccess.acl_id where hostaccess.acl_id=@id and
588## hostaccess.acl_type = "LIST"))
589 if (flag)
590 return(SMS_IN_USE);
822a6eba 591## repeat retrieve (flag = any(zephyr.class
592## where zephyr.xmt_type = "LIST" and zephyr.xmt_id = @id or
593## zephyr.sub_type = "LIST" and zephyr.sub_id = @id or
594## zephyr.iws_type = "LIST" and zephyr.iws_id = @id or
595## zephyr.iui_type = "LIST" and zephyr.iui_id = @id))
596 if (flag)
597 return(SMS_IN_USE);
598 else
599 return(SMS_SUCCESS);
600##}
a6cb4d4c 601
a6cb4d4c 602
822a6eba 603/* setup_dsin - verify that the service is no longer being referenced
604 * and may safely be deleted.
605 */
a6cb4d4c 606
822a6eba 607int setup_dsin(q, argv)
608 struct query *q;
609 char **argv;
610##{
611## int flag;
612## char *name;
613
614 name = argv[0];
44bd6f44 615## repeat retrieve (flag = any(serverhosts.service
616## where serverhosts.service=uppercase(@name)))
822a6eba 617 if (flag)
618 return(SMS_IN_USE);
619## repeat retrieve (flag = servers.inprogress) where servers.#name = @name
620 if (flag)
621 return(SMS_IN_USE);
622 else
a6cb4d4c 623 return(SMS_SUCCESS);
822a6eba 624##}
a6cb4d4c 625
a6cb4d4c 626
822a6eba 627/* setup_dshi - verify that the service-host is no longer being referenced
628 * and may safely be deleted.
629 */
a6cb4d4c 630
822a6eba 631int setup_dshi(q, argv)
632 struct query *q;
633 char **argv;
634##{
635## int flag, id;
636## char *name;
a6cb4d4c 637
822a6eba 638 name = argv[0];
639 id = *(int *)argv[1];
640## repeat retrieve (flag=serverhosts.inprogress)
44bd6f44 641## where serverhosts.service=uppercase(@name) and serverhosts.mach_id=@id
822a6eba 642 if (flag)
643 return(SMS_IN_USE);
644 else
645 return(SMS_SUCCESS);
a6cb4d4c 646##}
822a6eba 647
648
a6cb4d4c 649/**
822a6eba 650 ** setup_add_filesys - verify existance of referenced file systems
651 **
652 ** Inputs: Add
653 ** argv[1] - type
654 ** argv[2] - mach_id
655 ** argv[3] - name
656 ** argv[5] - access
a6cb4d4c 657 **
658 ** Description:
822a6eba 659 ** - for type = RVD:
660 ** * allow anything
661 ** - for type = NFS:
662 ** * extract directory prefix from name
663 ** * verify mach_id/dir in nfsphys
664 ** * verify access in {r, w, R, W}
665 **
666 ** Side effect: sets variable var_phys_id to the ID of the physical
667 ** filesystem (nfsphys_id for NFS, 0 for RVD)
a6cb4d4c 668 **
822a6eba 669 ** Errors:
670 ** SMS_NFS - specified directory not exported
671 ** SMS_FILESYS_ACCESS - invalid filesys access
a6cb4d4c 672 **
673 **/
674
822a6eba 675##static int var_phys_id;
a6cb4d4c 676
822a6eba 677setup_afil(q, argv)
a6cb4d4c 678 struct query *q;
679 char *argv[];
680{
822a6eba 681 char *type;
682 int mach_id;
683 char *name;
684 char *access;
a6cb4d4c 685
a6cb4d4c 686 type = argv[1];
687 mach_id = *(int *)argv[2];
822a6eba 688 name = argv[3];
689 access = argv[5];
690 var_phys_id = 0;
a6cb4d4c 691
822a6eba 692 if (!strcmp(type, "NFS"))
693 return (check_nfs(mach_id, name, access));
694 else
695 return(SMS_SUCCESS);
696}
05cdd922 697
30967516 698
e7fa3293 699/* Verify the arguments, depending on the FStype. Also, if this is an
700 * NFS filesystem, then update any quotas for that filesystem to reflect
701 * the new phys_id.
702 */
703
822a6eba 704setup_ufil(q, argv)
30967516 705 struct query *q;
706 char *argv[];
e7fa3293 707##{
708 int mach_id, status;
709 char *type, *name, *access;
710## int fid;
30967516 711
822a6eba 712 type = argv[2];
713 mach_id = *(int *)argv[3];
714 name = argv[4];
715 access = argv[6];
716 var_phys_id = 0;
a6cb4d4c 717
e7fa3293 718 if (!strcmp(type, "NFS")) {
719 status = check_nfs(mach_id, name, access);
720 fid = *(int *)argv[0];
db767e36 721## replace nfsquota (phys_id = var_phys_id) where nfsquota.filsys_id = fid
e7fa3293 722 return(status);
723 } else
724 return(SMS_SUCCESS);
725##}
30967516 726
a6cb4d4c 727
822a6eba 728/* Find the NFS physical partition that the named directory is on.
729 * This is done by comparing the dir against the mount point of the
730 * partition. To make sure we get the correct match when there is
731 * more than one, we sort the query in reverse order by dir name.
732 */
a6cb4d4c 733
822a6eba 734##check_nfs(mach_id, name, access)
a6cb4d4c 735## int mach_id;
822a6eba 736 char *name;
737 char *access;
738##{
a30e1c62 739## char dir[81];
822a6eba 740 char caccess;
741 register int status;
742 register char *cp1;
743 register char *cp2;
a6cb4d4c 744
822a6eba 745 caccess = (isupper(*access)) ? tolower(*access) : *access;
746 if (caccess != 'r' && caccess != 'w') return(SMS_FILESYS_ACCESS);
a6cb4d4c 747
822a6eba 748 status = SMS_NFS;
749## range of np is nfsphys
750## repeat retrieve (var_phys_id = np.#nfsphys_id, dir = trim(np.#dir))
751## where np.#mach_id = @mach_id sort by #dir:d {
752 cp1 = name;
753 cp2 = dir;
754 while (*cp2) {
755 if (*cp1++ != *cp2) break;
756 cp2++;
757 }
758 if (*cp2 == 0) {
759 status = SMS_SUCCESS;
a6cb4d4c 760## endretrieve
761 }
762## }
763
822a6eba 764 return(status);
30967516 765##}
a6cb4d4c 766
92a943d6 767
f49f997e 768/* setup_dfil: free any quota records and fsgroup info associated with
769 * a filesystem when it is deleted. Also adjust the allocation numbers.
822a6eba 770 */
92a943d6 771
822a6eba 772setup_dfil(q, argv, cl)
773 struct query *q;
774 char **argv;
775 client *cl;
776##{
777## int id;
92a943d6 778
822a6eba 779 id = *(int *)argv[0];
780## range of q is nfsquota
44bd6f44 781## range of fs is filesys
782## range of n is nfsphys
783## repeat replace n (allocated=n.allocated-sum(q.quota where q.filsys_id=@id))
784## where n.nfsphys_id = fs.phys_id and fs.filsys_id = @id
92a943d6 785
822a6eba 786## repeat delete q where q.filsys_id = @id
f49f997e 787## repeat delete fsgroup where fsgroup.filsys_id = @id
788## repeat delete fsgroup where fsgroup.group_id = @id
92a943d6 789 return(SMS_SUCCESS);
790##}
30967516 791
822a6eba 792
793/* setup_dnfp: check to see that the nfs physical partition does not have
794 * any filesystems assigned to it before allowing it to be deleted.
795 */
796
797setup_dnfp(q, argv, cl)
798 struct query *q;
799 char **argv;
92a943d6 800 client *cl;
92a943d6 801##{
822a6eba 802## int id, exists;
92a943d6 803
822a6eba 804 id = *(int *)argv[0];
805## repeat retrieve (exists = any(filesys.label where filesys.phys_id = @id))
806 if (exists)
807 return(SMS_IN_USE);
92a943d6 808 return(SMS_SUCCESS);
809##}
4b890cc4 810
4b890cc4 811
822a6eba 812/* setup_dnfq: Remove allocation from nfsphys before deleting quota.
813 * argv[0] = filsys_id
814 * argv[1] = users_id
815 */
816
817setup_dnfq(q, argv, cl)
818 struct query *q;
819 char **argv;
820 client *cl;
821##{
822## int quota, fs, user;
823
824 fs = *(int *)argv[0];
825 user = *(int *)argv[1];
826
827## range of q is nfsquota
828## repeat retrieve (quota = q.#quota) where q.users_id = @user and
829## q.filsys_id = @fs
830## repeat replace nfsphys (allocated = nfsphys.allocated - @quota)
831## where nfsphys.nfsphys_id = filesys.#phys_id and filesys.filsys_id = @fs
832 return(SMS_SUCCESS);
833##}
834
835
67d7b959 836/* setup_sshi: don't exclusive lock the machine table during
837 * set_server_host_internal.
838 */
839
840setup_sshi(q, argv, cl)
841 struct query *q;
842 char **argv;
843 client *cl;
844##{
845## set lockmode session where readlock = system
846##}
847
848
711660a5 849/* setup add_kerberos_user_mapping: add the string to the string
850 * table if necessary.
851 */
852
853setup_akum(q, argv, cl)
854struct query *q;
855char **argv;
856client *cl;
857##{
858## int id, rowcount;
859## char *name;
860
861 name = argv[1];
862## range of s is strings
863## repeat retrieve (id = s.string_id) where s.string = @name
864## inquire_equel (rowcount = "rowcount")
865 if (rowcount == 0) {
866 if (q->type != APPEND) return(SMS_STRING);
867## range of v is values
868## retrieve (id = v.value) where v.#name = "strings_id"
869 id++;
870## replace v (value = id) where v.#name = "strings_id"
871## append to strings (string_id = id, string = name)
872 }
873 *(int *)argv[1] = id;
874 return(0);
875##}
876
877
822a6eba 878\f
879/* FOLLOWUP ROUTINES */
880
881/* generic set_modtime routine. This takes the table name from the query,
882 * and will update the modtime, modby, and modwho fields in the entry in
883 * the table whose name field matches argv[0].
884 */
885
886set_modtime(q, argv, cl)
4b890cc4 887 struct query *q;
888 char *argv[];
822a6eba 889 client *cl;
4b890cc4 890##{
822a6eba 891## char *name, *entity, *table;
892## int who;
4b890cc4 893
822a6eba 894 entity = cl->entity;
711660a5 895 who = cl->client_id;
822a6eba 896 table = q->rtable;
897 name = argv[0];
4b890cc4 898
822a6eba 899## replace table (modtime = "now", modby = who, modwith = entity)
900## where table.#name = name
4b890cc4 901 return(SMS_SUCCESS);
902##}
903
822a6eba 904/* generic set_modtime_by_id routine. This takes the table name from
905 * the query, and the id name from the validate record,
906 * and will update the modtime, modby, and modwho fields in the entry in
907 * the table whose id matches argv[0].
908 */
909
910set_modtime_by_id(q, argv, cl)
4b890cc4 911 struct query *q;
822a6eba 912 char **argv;
913 client *cl;
4b890cc4 914##{
822a6eba 915## char *entity, *table, *id_name;
916## int who, id;
917
918 entity = cl->entity;
711660a5 919 who = cl->client_id;
822a6eba 920 table = q->rtable;
921 id_name = q->validate->object_id;
4b890cc4 922
822a6eba 923 id = *(int *)argv[0];
924## replace table (modtime = "now", modby = who, modwith = entity)
925## where table.id_name = id
4b890cc4 926 return(SMS_SUCCESS);
927##}
928
822a6eba 929
930/* Sets the finger modtime on a user record. The users_id will be in argv[0].
931 */
932
933set_finger_modtime(q, argv, cl)
4b890cc4 934 struct query *q;
935 char *argv[];
822a6eba 936 client *cl;
4b890cc4 937##{
822a6eba 938## int users_id, who;
939## char *entity;
940
941 entity = cl->entity;
711660a5 942 who = cl->client_id;
822a6eba 943 users_id = *(int *)argv[0];
4b890cc4 944
822a6eba 945## repeat replace u (fmodtime = "now", fmodby = @who, fmodwith = @entity)
946## where u.#users_id = @users_id
4b890cc4 947 return(SMS_SUCCESS);
948##}
05cdd922 949
822a6eba 950
951/* Sets the pobox modtime on a user record. The users_id will be in argv[0].
952 */
953
954set_pobox_modtime(q, argv, cl)
05cdd922 955 struct query *q;
822a6eba 956 char **argv;
957 client *cl;
05cdd922 958##{
822a6eba 959## int users_id, who;
960## char *entity;
05cdd922 961
822a6eba 962 entity = cl->entity;
711660a5 963 who = cl->client_id;
822a6eba 964 users_id = *(int *)argv[0];
05cdd922 965
822a6eba 966## repeat replace users (pmodtime = "now", pmodby = @who, pmodwith = @entity)
967## where users.#users_id = @users_id
968 return(SMS_SUCCESS);
969##}
05cdd922 970
05cdd922 971
3c7c4a07 972/* Like set_modtime, but uppercases the name first.
822a6eba 973 */
974
3c7c4a07 975set_uppercase_modtime(q, argv, cl)
822a6eba 976 struct query *q;
977 char **argv;
978 client *cl;
979##{
3c7c4a07 980## char *name, *entity, *table;
822a6eba 981## int who;
982
983 entity = cl->entity;
711660a5 984 who = cl->client_id;
3c7c4a07 985 table = q->rtable;
986 name = argv[0];
05cdd922 987
3c7c4a07 988## replace table (modtime = "now", modby = who, modwith = entity)
989## where table.#name = uppercase(name)
05cdd922 990 return(SMS_SUCCESS);
991##}
05cdd922 992
822a6eba 993
994/* Sets the modtime on the machine whose mach_id is in argv[0]. This routine
995 * is necessary for add_machine_to_cluster becuase the table that query
996 * operates on is "mcm", not "machine".
997 */
998
999set_mach_modtime_by_id(q, argv, cl)
05cdd922 1000 struct query *q;
05cdd922 1001 char **argv;
822a6eba 1002 client *cl;
1003##{
1004## char *entity;
1005## int who, id;
05cdd922 1006
822a6eba 1007 entity = cl->entity;
711660a5 1008 who = cl->client_id;
05cdd922 1009
822a6eba 1010 id = *(int *)argv[0];
1011## range of m is machine
1012## repeat replace m (modtime = "now", modby = @who, modwith = @entity)
1013## where m.mach_id = @id
1014 return(SMS_SUCCESS);
1015##}
05cdd922 1016
05cdd922 1017
822a6eba 1018/* Sets the modtime on the cluster whose mach_id is in argv[0]. This routine
1019 * is necessary for add_cluster_data and delete_cluster_data becuase the
1020 * table that query operates on is "svc", not "cluster".
1021 */
1022
1023set_cluster_modtime_by_id(q, argv, cl)
1024 struct query *q;
1025 char **argv;
1026 client *cl;
1027##{
1028## char *entity;
1029## int who, id;
1030
1031 entity = cl->entity;
711660a5 1032 who = cl->client_id;
822a6eba 1033
1034 id = *(int *)argv[0];
1035## range of c is cluster
1036## repeat replace c (modtime = "now", modby = @who, modwith = @entity)
1037## where c.clu_id = @id
05cdd922 1038 return(SMS_SUCCESS);
1039##}
1040
822a6eba 1041
1042/* sets the modtime on the serverhost where the service name is in argv[0]
1043 * and the mach_id is in argv[1].
1044 */
1045
1046set_serverhost_modtime(q, argv, cl)
92a943d6 1047 struct query *q;
822a6eba 1048 char **argv;
1049 client *cl;
92a943d6 1050##{
822a6eba 1051## char *entity, *serv;
1052## int who, id;
1053
1054 entity = cl->entity;
711660a5 1055 who = cl->client_id;
822a6eba 1056
1057 serv = argv[0];
1058 id = *(int *)argv[1];
1059## repeat replace sh (modtime = "now", modby = @who, modwith = @entity)
44bd6f44 1060## where sh.service = uppercase(@serv) and sh.mach_id = @id
822a6eba 1061 return(SMS_SUCCESS);
1062##}
1063
1064
1065/* sets the modtime on the nfsphys where the mach_id is in argv[0] and the
1066 * directory name is in argv[1].
1067 */
1068
1069set_nfsphys_modtime(q, argv, cl)
1070 struct query *q;
92a943d6 1071 char **argv;
822a6eba 1072 client *cl;
1073##{
1074## char *entity, *dir;
1075## int who, id;
92a943d6 1076
822a6eba 1077 entity = cl->entity;
711660a5 1078 who = cl->client_id;
92a943d6 1079
822a6eba 1080 id = *(int *)argv[0];
1081 dir = argv[1];
1082## repeat replace np (modtime = "now", modby = @who, modwith = @entity)
1083## where np.#dir = @dir and np.mach_id = @id
1084 return(SMS_SUCCESS);
1085##}
92a943d6 1086
92a943d6 1087
822a6eba 1088/* sets the modtime on a filesystem, where argv[0] contains the filesys
1089 * label.
1090 */
1091
1092set_filesys_modtime(q, argv, cl)
1093 struct query *q;
1094 char *argv[];
1095 client *cl;
1096##{
1097## char *label, *entity;
1098## int who;
1099
1100 entity = cl->entity;
711660a5 1101 who = cl->client_id;
822a6eba 1102
1103 label = argv[0];
1104 if (!strcmp(q->shortname, "ufil"))
1105 label = argv[1];
1106
1107## repeat replace fs (modtime = "now", modby = @who, modwith = @entity,
1108## #phys_id = @var_phys_id) where fs.#label = @label
92a943d6 1109 return(SMS_SUCCESS);
1110##}
05cdd922 1111
822a6eba 1112
1113/* sets the modtime on a zephyr class, where argv[0] contains the class
1114 * name.
1115 */
1116
1117set_zephyr_modtime(q, argv, cl)
1118 struct query *q;
1119 char *argv[];
1120 client *cl;
05cdd922 1121##{
822a6eba 1122## char *class, *entity;
1123## int who;
1124
1125 entity = cl->entity;
711660a5 1126 who = cl->client_id;
822a6eba 1127
1128 class = argv[0];
1129
1130## repeat replace z (modtime = "now", modby = @who, modwith = @entity)
1131## where z.#class = @class
1132 return(SMS_SUCCESS);
1133##}
1134
1135
1136/* fixes the modby field. This will be the second to last thing in the
1137 * argv, the argv length is determined from the query structure. It is
1138 * passed as a pointer to an integer. This will either turn it into a
1139 * username, or # + the users_id.
1140 */
1141followup_fix_modby(q, sq, v, action, actarg, cl)
1142 struct query *q;
1143 register struct save_queue *sq;
1144 struct validate *v;
1145 register int (*action)();
1146 register int actarg;
1147 client *cl;
1148##{
1149 register int i, j;
1150 char **argv, *malloc();
1151## int id, rowcount;
05cdd922 1152## char *name;
05cdd922 1153
822a6eba 1154 i = q->vcnt - 2;
1155 while (sq_get_data(sq, &argv)) {
1156 id = atoi(argv[i]);
1157 free(argv[i]);
711660a5 1158 argv[i] = malloc(256);
822a6eba 1159 name = argv[i];
711660a5 1160 if (id > 0)
1161## repeat retrieve (name = users.login) where users.users_id = @id
1162 else {
1163 id = -id;
1164## repeat retrieve (name = strings.string) where strings.string_id = @id
1165 id = -id;
1166 }
822a6eba 1167## inquire_equel(rowcount = "rowcount")
1168 if (rowcount != 1) {
1169 sprintf(argv[i], "#%d", id);
1170 }
1171 (*action)(q->vcnt, argv, actarg);
1172 for (j = 0; j < q->vcnt; j++)
1173 free(argv[j]);
1174 free(argv);
1175 }
1176 sq_destroy(sq);
1177 return(SMS_SUCCESS);
30967516 1178##}
1179
822a6eba 1180
30967516 1181/**
822a6eba 1182 ** followup_ausr - add finger and pobox entries, set_user_modtime
30967516 1183 **
1184 ** Inputs:
822a6eba 1185 ** argv[0] - login (add_user)
1186 ** argv[3] - last name
1187 ** argv[4] - first name
1188 ** argv[5] - middle name
30967516 1189 **
1190 **/
1191
822a6eba 1192followup_ausr(q, argv, cl)
30967516 1193 struct query *q;
822a6eba 1194 char *argv[];
1195 client *cl;
30967516 1196##{
822a6eba 1197## int who;
1198## char *login, *entity;
1199## char fullname[129];
30967516 1200
822a6eba 1201 login = argv[0];
711660a5 1202 who = cl->client_id;
822a6eba 1203 entity = cl->entity;
30967516 1204
822a6eba 1205 /* build fullname */
1206 if (strlen(argv[4]) && strlen(argv[5]))
1207 sprintf(fullname, "%s %s %s", argv[4], argv[5], argv[3]);
1208 else if (strlen(argv[4]))
1209 sprintf(fullname, "%s %s", argv[4], argv[3]);
1210 else
1211 sprintf(fullname, "%s", argv[3]);
30967516 1212
822a6eba 1213 /* create finger entry, pobox & set modtime on user */
1214## repeat replace u (modtime = "now", modby=@who, modwith=@entity,
1215## #fullname=@fullname, mit_affil = u.mit_year,
1216## fmodtime="now", fmodby=@who, fmodwith=@entity,
1217## potype="NONE", pmodtime="now", pmodby=@who, pmodwith=@entity)
1218## where u.#login = @login
30967516 1219
05cdd922 1220 return(SMS_SUCCESS);
1221##}
1222
822a6eba 1223
1224/* followup_gpob: fixes argv[2] based on the IDs currently there and the
1225 * type in argv[1]. Then completes the upcall to the user.
1226 *
1227 * argv[2] is of the form "123:234" where the first integer is the machine
1228 * ID if it is a pop box, and the second is the string ID if it is an SMTP
1229 * box. argv[1] should be "POP", "SMTP", or "NONE". Boxes of type NONE
1230 * are skipped.
1231 */
1232
1233followup_gpob(q, sq, v, action, actarg, cl)
1234 register struct query *q;
1235 register struct save_queue *sq;
1236 register struct validate *v;
1237 register int (*action)();
1238 int actarg;
1239 client *cl;
1240##{
1241 char **argv, *index();
1242 char *ptype, *p;
1243## char box[129], *name;
1244## int mid, sid, rowcount;
1245
1246 /* for each row */
1247 while (sq_get_data(sq, &argv)) {
1248 sms_trim_args(2, argv);
1249 ptype = argv[1];
1250 p = index(argv[2], ':');
1251 *p++ = 0;
1252 mid = atoi(argv[2]);
1253 sid = atoi(p);
1254 free(argv[2]);
1255
1256 if (!strcmp(ptype, "POP")) {
1257## repeat retrieve (box=machine.#name) where machine.mach_id=@mid
1258## inquire_equel(rowcount = "rowcount")
1259 if (rowcount != 1)
1260 return(SMS_MACHINE);
1261 } else if (!strcmp(ptype, "SMTP")) {
1262## repeat retrieve (box=strings.string) where strings.string_id=@sid
1263## inquire_equel(rowcount = "rowcount")
1264 if (rowcount != 1)
1265 return(SMS_STRING);
1266 } else /* ptype == "NONE" */ {
1267 goto skip;
1268 }
1269
1270 if (!strcmp(q->shortname, "gpob")) {
1271 sid = atoi(argv[4]);
1272 free(argv[4]);
711660a5 1273 argv[4] = malloc(256);
822a6eba 1274 name = argv[4];
711660a5 1275 if (sid > 0)
1276## repeat retrieve (name = users.login) where users.users_id = @sid
1277 else {
1278 sid = -sid;
1279## repeat retrieve (name = strings.string)
1280## where strings.string_id = @sid
1281 sid = -sid;
1282 }
822a6eba 1283## inquire_equel(rowcount = "rowcount")
1284 if (rowcount != 1)
1285 sprintf(name, "#%d", sid);
1286 }
1287
1288 argv[2] = box;
1289 (*action)(q->vcnt, argv, actarg);
1290 skip:
1291 /* free saved data */
1292 free(argv[0]);
1293 free(argv[1]);
711660a5 1294 free(argv[4]);
822a6eba 1295 free(argv);
1296 }
1297
1298 sq_destroy(sq);
1299 return (SMS_SUCCESS);
1300##}
1301
1302
44bd6f44 1303/* followup_glin: fix the ace_name in argv[8]. argv[7] will contain the
1304 * ace_type: "LIST", "USER", or "NONE". Decode the id in argv[8] into the
822a6eba 1305 * proper name based on the type, and repace that string in the argv.
1306 * Also fixes the modby field by called followup_fix_modby.
1307 */
1308
1309followup_glin(q, sq, v, action, actarg, cl)
1310 register struct query *q;
1311 register struct save_queue *sq;
1312 register struct validate *v;
1313 register int (*action)();
1314 int actarg;
1315 client *cl;
1316##{
1317 char **argv, *malloc(), *realloc(), *type;
1318## char *name;
1319## int id, rowcount;
1320 int i, idx;
1321
1322 idx = 8;
1323 if (!strcmp(q->shortname, "gsin"))
4f16dc86 1324 idx = 12;
822a6eba 1325
1326 while (sq_get_data(sq, &argv)) {
1327 sms_trim_args(q->vcnt, argv);
1328
1329 id = atoi(argv[i = q->vcnt - 2]);
1330 free(argv[i]);
711660a5 1331 name = argv[i] = malloc(256);
1332 if (id > 0)
1333## repeat retrieve (name = users.login) where users.users_id = @id
1334 else {
1335 id = -id;
1336## repeat retrieve (name = strings.string) where strings.string_id = @id
1337 id = -id;
1338 }
822a6eba 1339## inquire_equel(rowcount = "rowcount")
1340 if (rowcount != 1)
1341 sprintf(argv[i], "#%d", id);
1342
1343 id = atoi(argv[idx]);
1344 type = argv[idx - 1];
1345 if ((name = malloc(33)) == NULL)
1346 return(SMS_NO_MEM);
1347
1348 if (!strcmp(type, "LIST")) {
1349## repeat retrieve (name = list.#name) where list.list_id = @id
1350## inquire_equel(rowcount = "rowcount")
1351 if (rowcount != 1)
1352 strcpy(name, "???");
1353 } else if (!strcmp(type, "USER")) {
1354## repeat retrieve (name = users.login) where users.users_id = @id
f0516942 1355## inquire_equel(rowcount = "rowcount")
1356 if (rowcount != 1)
1357 strcpy(name, "???");
1358 } else if (!strcmp(type, "KERBEROS")) {
1359## repeat retrieve (name = strings.string) where strings.string_id = @id
822a6eba 1360## inquire_equel(rowcount = "rowcount")
1361 if (rowcount != 1)
1362 strcpy(name, "???");
1363 } else if (!strcmp(type, "NONE")) {
1364 strcpy(name, "NONE");
1365 } else
1366 strcpy(name, "???");
1367 free(argv[idx]);
1368 argv[idx] = name;
1369
1370 if (!strcmp(q->shortname, "glin") && atoi(argv[6]) == -1) {
1371 argv[6] = realloc(argv[6], strlen(UNIQUE_GID) + 1);
1372 strcpy(argv[6], UNIQUE_GID);
1373 }
1374
1375 /* send the data */
1376 (*action)(q->vcnt, argv, actarg);
1377
1378 /* free saved data */
1379 for (i = 0; i < q->vcnt; i++)
1380 free(argv[i]);
1381 free(argv);
1382 }
1383
1384 sq_destroy(sq);
1385 return (SMS_SUCCESS);
1386##}
1387
1388
1389/** followup_amtl - followup for amtl and dmfl; when adding a list
1390 ** member to a maillist, make member list a maillist also
1391 ** unless list is a user-group.
1392 ** Then set_list_modtime_by_id.
92a943d6 1393 **
1394 ** Inputs:
1395 ** argv[0] - list_id
822a6eba 1396 ** argv[1] - member_type
1397 ** argv[2] - member_id
92a943d6 1398 **
1399 **/
1400
822a6eba 1401followup_amtl(q, argv, cl)
92a943d6 1402 struct query *q;
1403 char *argv[];
822a6eba 1404 client *cl;
92a943d6 1405##{
92a943d6 1406## int list_id;
822a6eba 1407## int member_id;
1408## int exists, who;
1409## char *entity;
92a943d6 1410
1411 list_id = *(int *)argv[0];
822a6eba 1412 entity = cl->entity;
711660a5 1413 who = cl->client_id;
822a6eba 1414
1415## range of l is list
1416## repeat replace l (modtime = "now", modby = @who, modwith = @entity)
1417## where l.#list_id = @list_id
92a943d6 1418
822a6eba 1419 /* if query is not amtl or if member_type is not LIST then return */
1420 if (bcmp(q->shortname, "amtl", 4) || bcmp(argv[1], "LIST", 4))
1421 return(SMS_SUCCESS);
92a943d6 1422
822a6eba 1423 member_id = *(int *)argv[2];
1424
1425 /* is parent list a mailing list? */
1426## repeat retrieve (exists = l.maillist) where l.#list_id=@list_id
1427 if (!exists)
1428 return(SMS_SUCCESS);
1429
1430 /* list is not a user-group; add list to maillist table */
1431## repeat replace l (maillist = 1) where l.#list_id = @member_id
92a943d6 1432 return(SMS_SUCCESS);
1433##}
1434
822a6eba 1435
711660a5 1436/* followup_gnfq: Fix the directory name & modby fields
1437 * argv[0] = filsys_id
1438 * argv[2] = ascii(quota)
1439 */
1440
1441followup_gnfq(q, sq, v, action, actarg, cl)
1442 struct query *q;
1443 register struct save_queue *sq;
1444 struct validate *v;
1445 register int (*action)();
1446 register int actarg;
1447 client *cl;
1448##{
1449 register int j;
1450 char **argv, *malloc();
1451## int id, rowcount;
1452## char *name, *label;
1453
1454 while (sq_get_data(sq, &argv)) {
1455 id = atoi(argv[3]);
1456 free(argv[3]);
1457 argv[3] = malloc(256);
1458 name = argv[3];
1459 if (id == 0) {
1460 label = argv[0];
1461## repeat retrieve (name = filesys.#name) where filesys.#label = @label
1462 } else {
1463## repeat retrieve (name = nfsphys.dir) where nfsphys.nfsphys_id = @id
1464 }
1465## inquire_equel(rowcount = "rowcount")
1466 if (rowcount != 1) {
1467 sprintf(argv[3], "#%d", id);
1468 }
1469
1470 id = atoi(argv[6]);
1471 free(argv[6]);
1472 argv[6] = malloc(256);
1473 name = argv[6];
1474 if (id > 0)
1475## repeat retrieve (name = users.login) where users.users_id = @id
1476 else {
1477 id = -id;
1478## repeat retrieve (name = strings.string) where strings.string_id = @id
1479 id = -id;
1480 }
1481## inquire_equel(rowcount = "rowcount")
1482 if (rowcount != 1) {
1483 sprintf(argv[6], "#%d", id);
1484 }
1485 (*action)(q->vcnt, argv, actarg);
1486 for (j = 0; j < q->vcnt; j++)
1487 free(argv[j]);
1488 free(argv);
1489 }
1490 sq_destroy(sq);
1491 return(SMS_SUCCESS);
1492##}
1493
1494
822a6eba 1495/* followup_anfq: Add allocation to nfsphys after creating quota.
1496 * argv[0] = filsys_id
1497 * argv[2] = ascii(quota)
1498 */
1499
1500followup_anfq(q, argv, cl)
1501 struct query *q;
1502 char **argv;
1503 client *cl;
1504##{
1505## int quota, user, fs, who;
1506## char *entity;
1507
1508 fs = *(int *)argv[0];
1509 user = *(int *)argv[1];
1510 quota = atoi(argv[2]);
711660a5 1511 who = cl->client_id;
822a6eba 1512 entity = cl->entity;
1513
1514## repeat replace nq (modtime = "now", modby = @who, modwith = @entity)
1515## where nq.filsys_id = @fs and nq.users_id = @user
1516## repeat replace nfsphys (allocated = nfsphys.allocated + @quota)
1517## where nfsphys.nfsphys_id = filesys.#phys_id and filesys.filsys_id = @fs
1518 return(SMS_SUCCESS);
1519##}
1520
1521
1522/* followup_gzcl:
1523 */
1524
1525followup_gzcl(q, sq, v, action, actarg, cl)
1526 register struct query *q;
1527 register struct save_queue *sq;
1528 register struct validate *v;
1529 register int (*action)();
92a943d6 1530 int actarg;
822a6eba 1531 client *cl;
92a943d6 1532##{
822a6eba 1533## char *name;
1534## int rowcount, id;
1535 char **argv;
1536 int i;
92a943d6 1537
822a6eba 1538 while (sq_get_data(sq, &argv)) {
1539 sms_trim_args(q->vcnt, argv);
92a943d6 1540
822a6eba 1541 id = atoi(argv[i = q->vcnt - 2]);
1542 free(argv[i]);
711660a5 1543 name = argv[i] = malloc(256);
1544 if (id > 0)
1545## repeat retrieve (name = users.login) where users.users_id = @id
1546 else {
1547 id = -id;
1548## repeat retrieve (name = strings.string) where strings.string_id = @id
1549 id = -id;
1550 }
822a6eba 1551## inquire_equel(rowcount = "rowcount")
1552 if (rowcount != 1)
1553 sprintf(argv[i], "#%d", id);
1554
1555 for (i = 1; i < 8; i+=2) {
1556 id = atoi(argv[i+1]);
1557 free(argv[i+1]);
1558 if ((name = argv[i+1] = malloc(33)) == NULL)
1559 return(SMS_NO_MEM);
1560 if (!strcmp(argv[i], "LIST")) {
1561## repeat retrieve (name = list.#name) where list.list_id = @id
1562## inquire_equel(rowcount = "rowcount")
1563 if (rowcount != 1)
1564 strcpy(name, "???");
1565 } else if (!strcmp(argv[i], "USER")) {
1566## repeat retrieve (name = users.login) where users.users_id = @id
f0516942 1567## inquire_equel(rowcount = "rowcount")
1568 if (rowcount != 1)
1569 strcpy(name, "???");
1570 } else if (!strcmp(argv[i], "KERBEROS")) {
1571## repeat retrieve (name = strings.string) where strings.string_id = @id
822a6eba 1572## inquire_equel(rowcount = "rowcount")
1573 if (rowcount != 1)
1574 strcpy(name, "???");
1575 } else if (!strcmp(argv[i], "NONE")) {
1576 strcpy(name, "NONE");
1577 } else {
1578 strcpy(name, "???");
1579 }
1580 }
92a943d6 1581
822a6eba 1582 /* send the data */
1583 (*action)(q->vcnt, argv, actarg);
1584
1585 /* free saved data */
1586 for (i = 0; i < q->vcnt; i++)
1587 free(argv[i]);
1588 free(argv);
1589 }
1590 sq_destroy(sq);
92a943d6 1591 return(SMS_SUCCESS);
1592##}
1593
05cdd922 1594
822a6eba 1595/* followup_gsha:
1596 */
1597
1598followup_gsha(q, sq, v, action, actarg, cl)
05cdd922 1599 register struct query *q;
822a6eba 1600 register struct save_queue *sq;
1601 register struct validate *v;
1602 register int (*action)();
1603 int actarg;
1604 client *cl;
05cdd922 1605##{
822a6eba 1606## char *name;
1607## int rowcount, id;
1608 char **argv;
1609 int i;
05cdd922 1610
822a6eba 1611 while (sq_get_data(sq, &argv)) {
1612 sms_trim_args(q->vcnt, argv);
05cdd922 1613
822a6eba 1614 id = atoi(argv[4]);
1615 free(argv[4]);
711660a5 1616 name = argv[4] = malloc(256);
1617 if (id > 0)
1618## repeat retrieve (name = users.login) where users.users_id = @id
1619 else {
1620 id = -id;
1621## repeat retrieve (name = strings.string) where strings.string_id = @id
1622 id = -id;
1623 }
822a6eba 1624## inquire_equel(rowcount = "rowcount")
1625 if (rowcount != 1)
1626 sprintf(argv[4], "#%d", id);
1627
1628 id = atoi(argv[2]);
1629 free(argv[2]);
1630 if ((name = argv[2] = malloc(33)) == NULL)
1631 return(SMS_NO_MEM);
1632 if (!strcmp(argv[1], "LIST")) {
1633## repeat retrieve (name = list.#name) where list.list_id = @id
1634## inquire_equel(rowcount = "rowcount")
1635 if (rowcount != 1)
1636 strcpy(name, "???");
1637 } else if (!strcmp(argv[1], "USER")) {
1638## repeat retrieve (name = users.login) where users.users_id = @id
f0516942 1639## inquire_equel(rowcount = "rowcount")
1640 if (rowcount != 1)
1641 strcpy(name, "???");
1642 } else if (!strcmp(argv[1], "KERBEROS")) {
1643## repeat retrieve (name = strings.string) where strings.string_id = @id
822a6eba 1644## inquire_equel(rowcount = "rowcount")
1645 if (rowcount != 1)
1646 strcpy(name, "???");
1647 } else if (!strcmp(argv[1], "NONE")) {
1648 strcpy(name, "NONE");
1649 } else {
1650 strcpy(name, "???");
1651 }
05cdd922 1652
822a6eba 1653 /* send the data */
1654 (*action)(q->vcnt, argv, actarg);
1655
1656 /* free saved data */
1657 for (i = 0; i < q->vcnt; i++)
1658 free(argv[i]);
1659 free(argv);
1660 }
1661 sq_destroy(sq);
1662 return(SMS_SUCCESS);
1663##}
05cdd922 1664
05cdd922 1665
822a6eba 1666\f
1667/* Special query routines */
30967516 1668
822a6eba 1669/* set_pobox - this does all of the real work.
1670 * argv = user_id, type, box
1671 * if type is POP, then box should be a machine, and its ID should be put in
1672 * pop_id. If type is SMTP, then box should be a string and its ID should
1673 * be put in box_id. If type is NONE, then box doesn't matter.
1674 */
1675
1676int set_pobox(q, argv, cl)
1677 struct query *q;
1678 char **argv;
1679 client *cl;
1680##{
1681## int user, id, rowcount;
1682## char *box, potype[9];
1683
1684 box = argv[2];
1685 user = *(int *)argv[0];
1686
1687## repeat retrieve (id = users.pop_id, potype = users.#potype)
1688## where users.users_id = @user
e7fa3293 1689 if (!strcmp(strtrim(potype), "POP"))
822a6eba 1690 set_pop_usage(id, -1);
1691
1692 if (!strcmp(argv[1], "POP")) {
1693## repeat retrieve (id=machine.mach_id) where machine.name=uppercase(@box)
1694## inquire_equel(rowcount = "rowcount")
1695 if (rowcount != 1)
1696 return(SMS_MACHINE);
1697## repeat replace users (#potype = "POP", pop_id = @id)
1698## where users.users_id = @user
1699 set_pop_usage(id, 1);
1700 } else if (!strcmp(argv[1], "SMTP")) {
1701## range of s is strings
1702## repeat retrieve (id = s.string_id) where s.string = @box
1703## inquire_equel (rowcount = "rowcount")
1704 if (rowcount == 0) {
1705## range of v is values
1706## repeat retrieve (id = v.value) where v.name = "strings_id"
1707 id++;
1708## repeat replace v (value = @id) where v.name = "strings_id"
1709## append to strings (string_id = id, string = box)
1710 }
1711## repeat replace users (#potype = "SMTP", box_id = @id)
1712## where users.users_id = @user
1713 } else /* argv[1] == "NONE" */ {
1714## repeat replace users (#potype = "NONE") where users.users_id = @user
1715 }
1716
1717 set_pobox_modtime(q, argv, cl);
1718## repeat replace tblstats (updates = tblstats.updates + 1, modtime = "now")
1719## where tblstats.#table = "users"
30967516 1720 return(SMS_SUCCESS);
1721##}
1722
30967516 1723
822a6eba 1724/* get_list_info: passed a wildcard list name, returns lots of stuff about
1725 * each list. This is tricky: first build a queue of all requested
44bd6f44 1726 * data. Rest of processing consists of fixing gid, ace_name, and modby.
822a6eba 1727 */
1728
1729get_list_info(q, aargv, cl, action, actarg)
30967516 1730 register struct query *q;
822a6eba 1731 char **aargv;
1732 client *cl;
1733 register int (*action)();
1734 int actarg;
30967516 1735##{
822a6eba 1736 char *argv[13], *malloc(), *realloc();
1737## char *name, acl_type[9], listname[33], active[5], public[5], hidden[5];
1738## char maillist[5], group[5], gid[6], acl_name[33], desc[256], modtime[27];
711660a5 1739## char modby[256], modwith[9];
822a6eba 1740## int id, rowcount, acl_id, hid, modby_id;
1741 int returned;
1742 struct save_queue *sq, *sq_create();
30967516 1743
822a6eba 1744 returned = rowcount = 0;
1745 name = aargv[0];
30967516 1746
822a6eba 1747 sq = sq_create();
1748## range of l is list
1749## repeat retrieve (id = l.list_id) where l.#name = @name {
1750 sq_save_data(sq, id);
1751 rowcount++;
1752## }
711660a5 1753 if (ingres_errno) return(sms_errcode);
822a6eba 1754 if (rowcount == 0)
1755 return(SMS_NO_MATCH);
1756
1757 argv[0] = listname; argv[1] = active; argv[2] = public; argv[3] = hidden;
1758 argv[4] = maillist; argv[5] = group; argv[6] = gid; argv[7] = acl_type;
1759 argv[8] = acl_name; argv[9] = desc; argv[10] = modtime; argv[11] = modby;
1760 argv[12] = modwith;
1761
1762 while (sq_get_data(sq, &id)) {
1763 if (id == 0)
1764 continue;
1765 argv[6] = gid;
1766## repeat retrieve (listname = l.#name, active = text(l.#active),
1767## public = text(l.#public), hidden = text(l.#hidden),
1768## hid = l.#hidden, maillist = text(l.#maillist),
1769## group = text(l.#group), gid = text(l.#gid),
1770## acl_type = trim(l.#acl_type), acl_id = l.#acl_id,
1771## desc = l.#desc, modtime = l.#modtime, modby_id = l.#modby,
1772## modwith =l.#modwith)
1773## where l.list_id = @id
711660a5 1774 if (ingres_errno) return(sms_errcode);
822a6eba 1775
1776 if (atoi(gid) == -1)
1777 argv[6] = UNIQUE_GID;
1778
1779 if (!strcmp(acl_type, "LIST")) {
1780## repeat retrieve (acl_name = l.#name) where l.list_id = @acl_id
1781## inquire_equel(rowcount = "rowcount")
1782 if (rowcount != 1)
1783 strcpy(acl_name, "???");
1784 } else if (!strcmp(acl_type, "USER")) {
1785## repeat retrieve (acl_name = users.#login)
1786## where users.users_id = @acl_id
f0516942 1787## inquire_equel(rowcount = "rowcount")
1788 if (rowcount != 1)
1789 strcpy(acl_name, "???");
1790 } else if (!strcmp(acl_type, "KERBEROS")) {
1791## repeat retrieve (acl_name = strings.string)
1792## where strings.string_id = @acl_id
822a6eba 1793## inquire_equel(rowcount = "rowcount")
1794 if (rowcount != 1)
1795 strcpy(acl_name, "???");
1796 } else if (!strcmp(acl_type, "NONE")) {
1797 strcpy(acl_name, "NONE");
1798 } else
1799 strcpy(acl_name, "???");
1800
711660a5 1801 if (modby_id > 0)
1802## repeat retrieve (modby = users.login) where users.users_id = @modby_id
1803 else {
1804 modby_id = -modby_id;
1805## repeat retrieve (modby = strings.string)
1806## where strings.string_id = @modby_id
1807 modby_id = -modby_id;
1808 }
822a6eba 1809## inquire_equel(rowcount = "rowcount")
1810 if (rowcount != 1)
711660a5 1811 sprintf(modby, "#%d", modby_id);
1812 if (ingres_errno) return(sms_errcode);
822a6eba 1813
1814 sms_trim_args(q->vcnt, argv);
1815 returned++;
1816 (*action)(q->vcnt, argv, actarg);
1817 }
30967516 1818
822a6eba 1819 sq_destroy(sq);
1820## repeat replace tblstats (retrieves = tblstats.retrieves + 1)
1821## where tblstats.#table = "list"
5e06ce45 1822
822a6eba 1823 return (SMS_SUCCESS);
1824##}
1825
1826
a6683dad 1827/* Add_member_to_list: do list flattening as we go! MAXLISTDEPTH is
1828 * how many different ancestors a member is allowed to have.
1829 */
1830
1831#define MAXLISTDEPTH 100
1832
1833int add_member_to_list(q, argv, cl)
1834 struct query *q;
1835 char **argv;
1836 client *cl;
1837##{
1838## int id, lid, mid, exists, error;
1839## char *mtype, dtype[9];
1840 int ancestors[MAXLISTDEPTH], acount, a;
1841 int descendants[MAXLISTDEPTH], dcount, d;
1842 char *dtypes[MAXLISTDEPTH];
711660a5 1843 char *iargv[3];
a6683dad 1844
1845## range of m is imembers
1846 lid = *(int *)argv[0];
1847 mtype = argv[1];
1848 mid = *(int *)argv[2];
1849## repeat retrieve (exists = any(m.list_id where m.list_id=@lid and
1850## m.member_id = @mid and m.member_type = @mtype
1851## and m.direct = 1))
1852 if (exists)
1853 return(SMS_EXISTS);
1854 ancestors[0] = lid;
1855 acount = 1;
1856## repeat retrieve (id = m.list_id)
1857## where m.member_id = @lid and m.member_type = "LIST" {
1858 ancestors[acount++] = id;
1859 if (acount >= MAXLISTDEPTH) {
1860## endretrieve
1861 }
1862## }
711660a5 1863 if (ingres_errno) return(sms_errcode);
a6683dad 1864 if (acount >= MAXLISTDEPTH) {
1865 return(SMS_INTERNAL);
1866 }
1867 descendants[0] = mid;
1868 dtypes[0] = mtype;
1869 dcount = 1;
1870 error = 0;
1871 if (!strcmp(mtype, "LIST")) {
1872## repeat retrieve (id = m.member_id, dtype = m.member_type)
1873## where m.list_id = @mid {
1874 switch (dtype[0]) {
1875 case 'L':
1876 dtypes[dcount] = "LIST";
1877 break;
1878 case 'U':
1879 dtypes[dcount] = "USER";
1880 break;
1881 case 'S':
1882 dtypes[dcount] = "STRING";
1883 break;
1884 case 'K':
1885 dtypes[dcount] = "KERBEROS";
1886 break;
1887 default:
1888 error++;
1889## endretrieve
1890 }
1891 descendants[dcount++] = id;
1892 if (dcount >= MAXLISTDEPTH) {
1893 error++;
1894## endretrieve
1895 }
1896## }
711660a5 1897 if (ingres_errno) return(sms_errcode);
a6683dad 1898 if (error)
1899 return(SMS_INTERNAL);
1900 }
1901 for (a = 0; a < acount; a++) {
1902 lid = ancestors[a];
1903 for (d = 0; d < dcount; d++) {
1904 mid = descendants[d];
1905 mtype = dtypes[d];
1906 if (mid == lid && !strcmp(mtype, "LIST")) {
1907 return(SMS_LISTLOOP);
1908 }
1909## repeat retrieve (exists = any(m.ref_count where m.list_id = @lid
1910## and m.member_id = @mid
1911## and m.member_type = @mtype))
1912 if (exists) {
1913 if (a == 0 && d == 0)
1914## replace m (ref_count = m.ref_count+1, direct = 1)
1915## where m.list_id = lid and m.member_id = mid and
1916## m.member_type = mtype
1917 else
1918## replace m (ref_count = m.ref_count+1)
1919## where m.list_id = lid and m.member_id = mid and
1920## m.member_type = mtype
1921 } else {
711660a5 1922 incremental_clear_before();
a6683dad 1923 if (a == 0 && d == 0)
1924## append imembers (list_id=lid, member_id = mid, direct = 1,
1925## member_type=mtype, ref_count = 1)
1926 else
1927## append imembers (list_id=lid, member_id = mid,
1928## member_type=mtype, ref_count = 1)
711660a5 1929 iargv[0] = (char *)lid;
1930 iargv[1] = mtype;
1931 iargv[2] = (char *)mid;
1932 incremental_after("members", 0, iargv);
a6683dad 1933 }
1934 }
1935 }
711660a5 1936 if (ingres_errno) return(sms_errcode);
a6683dad 1937 return(SMS_SUCCESS);
1938##}
1939
1940
1941/* Delete_member_from_list: do list flattening as we go!
1942 */
1943
1944int delete_member_from_list(q, argv, cl)
1945 struct query *q;
1946 char **argv;
1947 client *cl;
1948##{
1949## int id, lid, mid, cnt, exists, error;
1950## char *mtype, dtype[9];
1951 int ancestors[MAXLISTDEPTH], acount, a;
1952 int descendants[MAXLISTDEPTH], dcount, d;
1953 char *dtypes[MAXLISTDEPTH];
711660a5 1954 char *iargv[3];
a6683dad 1955
1956## range of m is imembers
1957 lid = *(int *)argv[0];
1958 mtype = argv[1];
1959 mid = *(int *)argv[2];
1960## repeat retrieve (exists = any(m.list_id where m.list_id=@lid and
1961## m.member_id = @mid and m.member_type = @mtype
1962## and m.direct = 1))
711660a5 1963 if (ingres_errno) return(sms_errcode);
a6683dad 1964 if (!exists)
1965 return(SMS_NO_MATCH);
1966 ancestors[0] = lid;
1967 acount = 1;
1968## repeat retrieve (id = m.list_id)
1969## where m.member_id = @lid and m.member_type = "LIST" {
1970 ancestors[acount++] = id;
1971 if (acount >= MAXLISTDEPTH)
1972## endretrieve
1973## }
711660a5 1974 if (ingres_errno) return(sms_errcode);
a6683dad 1975 if (acount >= MAXLISTDEPTH)
1976 return(SMS_INTERNAL);
1977 descendants[0] = mid;
1978 dtypes[0] = mtype;
1979 dcount = 1;
1980 error = 0;
1981 if (!strcmp(mtype, "LIST")) {
1982## repeat retrieve (id = m.member_id, dtype = m.member_type)
1983## where m.list_id = @mid {
1984 switch (dtype[0]) {
1985 case 'L':
1986 dtypes[dcount] = "LIST";
1987 break;
1988 case 'U':
1989 dtypes[dcount] = "USER";
1990 break;
1991 case 'S':
1992 dtypes[dcount] = "STRING";
1993 break;
1994 case 'K':
1995 dtypes[dcount] = "KERBEROS";
1996 break;
1997 default:
1998 error++;
1999## endretrieve
2000 }
2001 descendants[dcount++] = id;
2002 if (dcount >= MAXLISTDEPTH)
2003## endretrieve
2004## }
711660a5 2005 if (ingres_errno) return(sms_errcode);
a6683dad 2006 if (error)
2007 return(SMS_INTERNAL);
2008 }
2009 for (a = 0; a < acount; a++) {
2010 lid = ancestors[a];
2011 for (d = 0; d < dcount; d++) {
2012 mid = descendants[d];
2013 mtype = dtypes[d];
2014 if (mid == lid && !strcmp(mtype, "LIST")) {
2015 return(SMS_LISTLOOP);
2016 }
2017## repeat retrieve (cnt = m.ref_count)
2018## where m.list_id = @lid and m.member_id = @mid
2019## and m.member_type = @mtype
2020 if (cnt <= 1) {
711660a5 2021 iargv[0] = (char *)lid;
2022 iargv[1] = mtype;
2023 iargv[2] = (char *)mid;
2024 incremental_before("members", 0, iargv);
a6683dad 2025## delete m where m.list_id = lid and m.member_id = mid and
2026## m.member_type = mtype
711660a5 2027 incremental_clear_after();
a6683dad 2028 } else if (a == 0 && d == 0) {
2029## replace m (ref_count = m.ref_count-1, direct = 0)
2030## where m.list_id = lid and m.member_id = mid and
2031## m.member_type = mtype
2032 } else {
2033## replace m (ref_count = m.ref_count-1)
2034## where m.list_id = lid and m.member_idn = mid and
2035## m.member_type = mtype
2036 }
2037 }
2038 }
711660a5 2039 if (ingres_errno) return(sms_errcode);
a6683dad 2040 return(SMS_SUCCESS);
2041##}
2042
2043
44bd6f44 2044/* get_ace_use - given a type and a name, return a type and a name.
2045 * The ace_type is one of "LIST", "USER", "RLIST", or "RUSER" in argv[0],
822a6eba 2046 * and argv[1] will contain the ID of the entity in question. The R*
2047 * types mean to recursively look at every containing list, not just
2048 * when the object in question is a direct member. On return, the
2049 * usage type will be one of LIST, SERVICE, FILESYS, QUOTA, QUERY, or ZEPHYR.
2050 */
2051
44bd6f44 2052int get_ace_use(q, argv, cl, action, actarg)
822a6eba 2053 struct query *q;
2054 char *argv[];
2055 client *cl;
2056 int (*action)();
2057 int actarg;
2058##{
2059 int found = 0;
2060## char *atype;
2061## int aid, listid, id;
2062 struct save_queue *sq, *sq_create();
2063
a6683dad 2064## range of m is imembers
822a6eba 2065 atype = argv[0];
2066 aid = *(int *)argv[1];
f0516942 2067 if (!strcmp(atype, "LIST") || !strcmp(atype, "USER") ||
2068 !strcmp(atype, "KERBEROS")) {
44bd6f44 2069 return(get_ace_internal(atype, aid, action, actarg));
822a6eba 2070 }
2071
2072 sq = sq_create();
2073 if (!strcmp(atype, "RLIST")) {
2074 sq_save_data(sq, aid);
2075 /* get all the list_id's of containing lists */
a6683dad 2076## range of m is imembers
2077## repeat retrieve (listid = m.list_id)
822a6eba 2078## where m.member_type = "LIST" and m.member_id = @id {
a6683dad 2079 sq_save_unique_data(sq, listid);
2080## }
822a6eba 2081 /* now process each one */
2082 while (sq_get_data(sq, &id)) {
44bd6f44 2083 if (get_ace_internal("LIST", id, action, actarg) == SMS_SUCCESS)
822a6eba 2084 found++;
2085 }
2086 }
2087
2088 if (!strcmp(atype, "RUSER")) {
822a6eba 2089## repeat retrieve (listid = m.list_id)
2090## where m.member_type = "USER" and m.member_id = @aid {
2091 sq_save_data(sq, listid);
2092## }
822a6eba 2093 /* now process each one */
2094 while (sq_get_data(sq, &id)) {
44bd6f44 2095 if (get_ace_internal("LIST", id, action, actarg) == SMS_SUCCESS)
822a6eba 2096 found++;
2097 }
44bd6f44 2098 if (get_ace_internal("USER", aid, action, actarg) == SMS_SUCCESS)
822a6eba 2099 found++;
2100 }
05cdd922 2101
f0516942 2102 if (!strcmp(atype, "RKERBERO")) {
f0516942 2103## repeat retrieve (listid = m.list_id)
2104## where m.member_type = "KERBEROS" and m.member_id = @aid {
2105 sq_save_data(sq, listid);
2106## }
f0516942 2107 /* now process each one */
2108 while (sq_get_data(sq, &id)) {
2109 if (get_ace_internal("LIST", id, action, actarg) == SMS_SUCCESS)
2110 found++;
2111 }
2112 if (get_ace_internal("KERBEROS", aid, action, actarg) == SMS_SUCCESS)
2113 found++;
2114 }
2115
822a6eba 2116 sq_destroy(sq);
2117 if (!found) return(SMS_NO_MATCH);
05cdd922 2118 return(SMS_SUCCESS);
2119##}
92a943d6 2120
822a6eba 2121
44bd6f44 2122/* This looks up a single list or user for ace use. atype must be "USER"
822a6eba 2123 * or "LIST", and aid is the ID of the corresponding object. This is used
44bd6f44 2124 * by get_ace_use above.
822a6eba 2125 */
2126
44bd6f44 2127##get_ace_internal(atype, aid, action, actarg)
822a6eba 2128## char *atype;
2129## int aid;
2130 int (*action)();
2131 int actarg;
2132##{
2133 char *rargv[2];
2134 int found = 0;
2135## char name[33];
2136
2137 rargv[1] = name;
2138 if (!strcmp(atype, "LIST")) {
2139 rargv[0] = "FILESYS";
2140## repeat retrieve (name = filesys.label)
2141## where filesys.owners = @aid {
2142 (*action)(2, rargv, actarg);
2143 found++;
2144## }
2145
2146 rargv[0] = "QUERY";
2147## repeat retrieve (name = capacls.capability)
2148## where capacls.list_id = @aid {
2149 (*action)(2, rargv, actarg);
2150 found++;
2151## }
2152 } else if (!strcmp(atype, "USER")) {
2153 rargv[0] = "FILESYS";
2154## repeat retrieve (name = filesys.label)
2155## where filesys.owner = @aid {
2156 (*action)(2, rargv, actarg);
2157 found++;
2158## }
2159 }
2160
2161 rargv[0] = "LIST";
2162## repeat retrieve (name = list.#name)
2163## where list.acl_type = @atype and list.acl_id = @aid {
2164 (*action)(2, rargv, actarg);
2165 found++;
2166## }
2167
2168 rargv[0] = "SERVICE";
2169## repeat retrieve (name = servers.#name)
2170## where servers.acl_type = @atype and servers.acl_id = @aid {
2171 (*action)(2, rargv, actarg);
2172 found++;
2173## }
2174
2175 rargv[0] = "HOSTACCESS";
2176## repeat retrieve (name = machine.#name)
2177## where machine.mach_id = hostaccess.mach_id and
2178## hostaccess.acl_type = @atype and hostaccess.acl_id = @aid {
2179 (*action)(2, rargv, actarg);
2180 found++;
2181## }
2182 rargv[0] = "ZEPHYR";
2183## repeat retrieve (name = zephyr.class)
2184## where zephyr.xmt_type = @atype and zephyr.xmt_id = @aid or
2185## zephyr.sub_type = @atype and zephyr.sub_id = @aid or
2186## zephyr.iws_type = @atype and zephyr.iws_id = @aid or
2187## zephyr.iui_type = @atype and zephyr.iui_id = @aid {
2188 (*action)(2, rargv, actarg);
2189 found++;
2190## }
2191
2192 if (!found) return(SMS_NO_MATCH);
2193 return(SMS_SUCCESS);
2194##}
2195
2196
2197/* get_lists_of_member - given a type and a name, return the name and flags
2198 * of all of the lists of the given member. The member_type is one of
2199 * "LIST", "USER", "STRING", "RLIST", "RUSER", or "RSTRING" in argv[0],
2200 * and argv[1] will contain the ID of the entity in question. The R*
2201 * types mean to recursively look at every containing list, not just
2202 * when the object in question is a direct member.
2203 */
2204
2205int get_lists_of_member(q, argv, cl, action, actarg)
92a943d6 2206 struct query *q;
2207 char *argv[];
822a6eba 2208 client *cl;
2209 int (*action)();
2210 int actarg;
92a943d6 2211##{
a6683dad 2212 int found = 0, direct = 1;
2213 char *rargv[6];
822a6eba 2214## char *atype;
2215## int aid, listid, id;
a6683dad 2216## char name[33], active[5], public[5], hidden[5], maillist[5], group[5];
822a6eba 2217
2218 atype = argv[0];
2219 aid = *(int *)argv[1];
822a6eba 2220 if (!strcmp(atype, "RLIST")) {
a6683dad 2221 atype = "LIST";
2222 direct = 0;
822a6eba 2223 }
822a6eba 2224 if (!strcmp(atype, "RUSER")) {
a6683dad 2225 atype = "USER";
2226 direct = 0;
822a6eba 2227 }
822a6eba 2228 if (!strcmp(atype, "RSTRING")) {
a6683dad 2229 atype = "STRING";
2230 direct = 0;
92a943d6 2231 }
a6683dad 2232 if (!strcmp(atype, "RKERBEROS")) {
2233 atype = "KERBEROS";
2234 direct = 0;
f0516942 2235 }
2236
822a6eba 2237 rargv[0] = name;
2238 rargv[1] = active;
2239 rargv[2] = public;
2240 rargv[3] = hidden;
2241 rargv[4] = maillist;
2242 rargv[5] = group;
a6683dad 2243 if (direct) {
2244## repeat retrieve (name = list.#name, active = text(list.#active),
2245## public = text(list.#public), hidden = text(list.#hidden),
2246## maillist = text(list.#maillist), group = text(list.#group))
2247## where list.list_id = m.list_id and m.direct = 1 and
2248## m.member_type = @atype and m.member_id = @aid {
2249 (*action)(6, rargv, actarg);
2250 found++;
2251## }
2252 } else {
2253## repeat retrieve (name = list.#name, active = text(list.#active),
822a6eba 2254## public = text(list.#public), hidden = text(list.#hidden),
2255## maillist = text(list.#maillist), group = text(list.#group))
2256## where list.list_id = m.list_id and
2257## m.member_type = @atype and m.member_id = @aid {
2258 (*action)(6, rargv, actarg);
2259 found++;
a6683dad 2260## }
2261 }
92a943d6 2262
822a6eba 2263 if (!found) return(SMS_NO_MATCH);
92a943d6 2264 return(SMS_SUCCESS);
2265##}
2266
822a6eba 2267
2268/* qualified_get_lists: passed "TRUE", "FALSE", or "DONTCARE" for each of
2269 * the five flags associated with each list. It will return the name of
2270 * each list that meets the quailifications. It does this by building a
2271 * where clause based on the arguments, then doing a retrieve.
2272 */
2273
2274static char *lflags[5] = { "active", "public", "hidden", "maillist", "group" };
2275
2276int qualified_get_lists(q, argv, cl, action, actarg)
2277 struct query *q;
2278 char *argv[];
2279 client *cl;
2280 int (*action)();
2281 int actarg;
2282{
2283 return(qualified_get(q, argv, action, actarg, "l.list_id != 0",
2284 "l", "name", lflags));
2285}
2286
2287
2288/** get_members_of_list - optimized query for retrieval of list members
c2408bd5 2289 **
2290 ** Inputs:
2291 ** argv[0] - list_id
2292 **
2293 ** Description:
2294 ** - retrieve USER members, then LIST members, then STRING members
c2408bd5 2295 **/
2296
822a6eba 2297get_members_of_list(q, argv, cl, action, actarg)
c2408bd5 2298 struct query *q;
2299 char *argv[];
822a6eba 2300 client *cl;
c2408bd5 2301 int (*action)();
2302 int actarg;
2303##{
2304## int list_id;
2305## char member_name[129];
2306 char *targv[2];
2307
2308 list_id = *(int *)argv[0];
2309 targv[0] = "USER";
2310 targv[1] = member_name;
2311
a6683dad 2312## range of m is imembers
c2408bd5 2313## repeat retrieve (member_name = users.login)
2314## where m.#list_id = @list_id and m.member_type = "USER"
a6683dad 2315## and m.member_id = users.users_id and m.direct = 1
92a943d6 2316## sort by #member_name
c2408bd5 2317## {
2318 (*action)(2, targv, actarg);
2319## }
2320
2321 targv[0] = "LIST";
2322## repeat retrieve (member_name = list.name)
2323## where m.#list_id = @list_id and m.member_type = "LIST"
a6683dad 2324## and m.member_id = list.#list_id and m.direct = 1
92a943d6 2325## sort by #member_name
c2408bd5 2326## {
2327 (*action)(2, targv, actarg);
2328## }
2329
2330 targv[0] = "STRING";
2331## repeat retrieve (member_name = strings.string)
2332## where m.#list_id = @list_id and m.member_type = "STRING"
a6683dad 2333## and m.member_id = strings.string_id and m.direct = 1
92a943d6 2334## sort by #member_name
f0516942 2335## {
2336 (*action)(2, targv, actarg);
2337## }
2338
2339 targv[0] = "KERBEROS";
2340## repeat retrieve (member_name = strings.string)
2341## where m.#list_id = @list_id and m.member_type = "KERBEROS"
a6683dad 2342## and m.member_id = strings.string_id and m.direct = 1
f0516942 2343## sort by #member_name
c2408bd5 2344## {
2345 (*action)(2, targv, actarg);
2346## }
2347
2348 return(SMS_SUCCESS);
2349##}
2350
92a943d6 2351
822a6eba 2352/* count_members_of_list: this is a simple query, but it cannot be done
2353 * through the dispatch table.
2354 */
2355
2356int count_members_of_list(q, argv, cl, action, actarg)
92a943d6 2357 struct query *q;
2358 char *argv[];
822a6eba 2359 client *cl;
92a943d6 2360 int (*action)();
2361 int actarg;
2362##{
822a6eba 2363## int list, ct = 0;
2364 char *rargv[1], countbuf[5];
2365
2366 list = *(int *)argv[0];
2367 rargv[0] = countbuf;
a6683dad 2368## repeat retrieve (ct = count(imembers.list_id
2369## where imembers.list_id = @list and
2370## imembers.direct = 1))
822a6eba 2371 sprintf(countbuf, "%d", ct);
2372 (*action)(1, rargv, actarg);
822a6eba 2373 return(SMS_SUCCESS);
2374##}
92a943d6 2375
92a943d6 2376
822a6eba 2377/* qualified_get_server: passed "TRUE", "FALSE", or "DONTCARE" for each of
2378 * the three flags associated with each service. It will return the name of
2379 * each service that meets the quailifications. It does this by building a
2380 * where clause based on the arguments, then doing a retrieve.
2381 */
92a943d6 2382
822a6eba 2383static char *sflags[3] = { "enable", "inprogress", "harderror" };
a6cb4d4c 2384
822a6eba 2385int qualified_get_server(q, argv, cl, action, actarg)
a6cb4d4c 2386 struct query *q;
2387 char *argv[];
822a6eba 2388 client *cl;
a6cb4d4c 2389 int (*action)();
2390 int actarg;
822a6eba 2391{
2392 return(qualified_get(q, argv, action, actarg, "s.name != \"\"",
2393 "s", "name", sflags));
2394}
a6cb4d4c 2395
a6cb4d4c 2396
822a6eba 2397/* generic qualified get routine, used by qualified_get_lists,
2398 * qualified_get_server, and qualified_get_serverhost.
2399 * Args:
2400 * start - a simple where clause, must not be empty
2401 * range - the name of the range variable
2402 * field - the field to return
2403 * flags - an array of strings, names of the flag variables
2404 */
c2408bd5 2405
822a6eba 2406int qualified_get(q, argv, action, actarg, start, range, field, flags)
c2408bd5 2407 struct query *q;
2408 char *argv[];
2409 int (*action)();
2410 int actarg;
822a6eba 2411 char *start;
2412 char *range;
2413 char *field;
2414 char *flags[];
c2408bd5 2415##{
822a6eba 2416## char name[33], qual[256], *rvar, *rtbl, *rfield;
2417 char *rargv[1], buf[32];
2418## int rowcount, i;
2419
2420 strcpy(qual, start);
2421 for (i = 0; i < q->argc; i++) {
2422 if (!strcmp(argv[i], "TRUE")) {
2423 sprintf(buf, " and %s.%s != 0", range, flags[i]);
2424 (void) strcat(qual, buf);
2425 } else if (!strcmp(argv[i], "FALSE")) {
2426 sprintf(buf, " and %s.%s = 0", range, flags[i]);
2427 (void) strcat(qual, buf);
2428 }
2429 }
2430
2431 rargv[0] = name;
2432 rvar = range;
2433 rtbl = q->rtable;
2434 rfield = field;
2435## range of rvar is rtbl
2436## retrieve (name = rvar.rfield) where qual {
2437 (*action)(1, rargv, actarg);
c2408bd5 2438## }
822a6eba 2439## inquire_equel(rowcount = "rowcount")
2440## repeat replace tblstats (retrieves = tblstats.retrieves + 1)
2441## where tblstats.#table = @rtbl
2442 if (rowcount == 0)
2443 return(SMS_NO_MATCH);
2444 return(SMS_SUCCESS);
2445##}
c2408bd5 2446
c2408bd5 2447
822a6eba 2448/* qualified_get_serverhost: passed "TRUE", "FALSE", or "DONTCARE" for each of
2449 * the five flags associated with each serverhost. It will return the name of
2450 * each service and host that meets the quailifications. It does this by
2451 * building a where clause based on the arguments, then doing a retrieve.
2452 */
c2408bd5 2453
822a6eba 2454static char *shflags[6] = { "service", "enable", "override", "success",
2455 "inprogress", "hosterror" };
a6cb4d4c 2456
822a6eba 2457int qualified_get_serverhost(q, argv, cl, action, actarg)
a6cb4d4c 2458 struct query *q;
2459 char *argv[];
822a6eba 2460 client *cl;
a6cb4d4c 2461 int (*action)();
2462 int actarg;
2463##{
822a6eba 2464## char sname[33], mname[33], qual[256];
2465 char *rargv[2], buf[32];
2466## int rowcount, i;
2467
44bd6f44 2468 sprintf(qual, "machine.mach_id = sh.mach_id and sh.service = uppercase(\"%s\")",
822a6eba 2469 argv[0]);
2470 for (i = 1; i < q->argc; i++) {
2471 if (!strcmp(argv[i], "TRUE")) {
2472 sprintf(buf, " and sh.%s != 0", shflags[i]);
2473 strcat(qual, buf);
2474 } else if (!strcmp(argv[i], "FALSE")) {
2475 sprintf(buf, " and sh.%s = 0", shflags[i]);
2476 strcat(qual, buf);
2477 }
2478 }
2479
2480 rargv[0] = sname;
2481 rargv[1] = mname;
2482## range of sh is serverhosts
2483## retrieve (sname = sh.service, mname = machine.name) where qual {
2484 (*action)(2, rargv, actarg);
a6cb4d4c 2485## }
822a6eba 2486## inquire_equel(rowcount = "rowcount")
2487## repeat replace tblstats (retrieves = tblstats.retrieves + 1)
2488## where tblstats.#table = "serverhosts"
2489 if (rowcount == 0)
2490 return(SMS_NO_MATCH);
2491 return(SMS_SUCCESS);
2492##}
a6cb4d4c 2493
a6cb4d4c 2494
822a6eba 2495/* register_user - change user's login name and allocate a pobox, group,
2496 * filesystem, and quota for them. The user's status must start out as 0,
2497 * and is left as 2. Arguments are: user's UID, new login name, and user's
2498 * type for filesystem allocation (SMS_FS_STUDENT, SMS_FS_FACULTY,
2499 * SMS_FS_STAFF, SMS_FS_MISC).
2500 */
2501
2502register_user(q, argv, cl)
2503 struct query *q;
2504 char **argv;
2505 client *cl;
2506##{
2507## char *login, dir[65], *entity, *directory, machname[33];
2508## int who, rowcount, mid, uid, users_id, flag, utype, nid, list_id, quota;
2509## int size, alloc, pid, m_id;
711660a5 2510 char buffer[256], *aargv[3];
822a6eba 2511 int maxsize;
2512
2513 entity = cl->entity;
711660a5 2514 who = cl->client_id;
822a6eba 2515
2516 uid = atoi(argv[0]);
2517 login = argv[1];
2518 utype = atoi(argv[2]);
2519
2520## range of u is users
2521## range of l is list
2522## range of sh is serverhosts
2523## range of n is nfsphys
2524## range of m is machine
2525
2526 /* find user */
2527## repeat retrieve (users_id = u.#users_id)
711660a5 2528## where u.#uid = @uid and (u.status = 0 or u.status = 5)
822a6eba 2529## inquire_equel(rowcount = "rowcount");
2530 if (rowcount == 0)
2531 return(SMS_NO_MATCH);
2532 if (rowcount > 1)
2533 return(SMS_NOT_UNIQUE);
2534
2535 /* check new login name */
711660a5 2536## repeat retrieve (flag = any(u.#login where u.#login = @login and
2537## u.#users_id != users_id))
e1795ce1 2538 if (ingres_errno) return(sms_errcode);
2539 if (flag) return(SMS_IN_USE);
4f16dc86 2540## repeat retrieve (flag = any(l.#name where l.#name = @login))
e1795ce1 2541 if (ingres_errno) return(sms_errcode);
2542 if (flag) return(SMS_IN_USE);
99a288b9 2543## repeat retrieve (flag = any(filesys.#label where filesys.#label = @login))
e1795ce1 2544 if (ingres_errno) return(sms_errcode);
2545 if (flag) return(SMS_IN_USE);
822a6eba 2546 com_err(whoami, 0, "new login name OK");
2547
2548 /* choose place for pobox, put in mid */
2549## repeat retrieve (mid = sh.mach_id, machname = m.name)
44bd6f44 2550## where sh.service = "POP" and m.mach_id = sh.mach_id and
2551## sh.value2 - sh.value1 = max(sh.value2-sh.value1 where sh.service="POP")
8ac9ee7a 2552## inquire_equel(rowcount = "rowcount");
822a6eba 2553 if (rowcount == 0)
44bd6f44 2554 return(SMS_NO_POBOX);
822a6eba 2555
2556 /* change login name, set pobox */
711660a5 2557 sprintf(buffer, "u.users_id = %d", users_id);
2558 incremental_before("users", buffer, 0);
822a6eba 2559## repeat replace u (#login = @login, status = 2, modtime = "now",
2560## modby = @who, modwith = @entity, potype="POP",
2561## pop_id = @mid, pmodtime="now", pmodby=@who,
2562## pmodwith=@entity)
2563## where u.#users_id = @users_id
8ac9ee7a 2564## inquire_equel(rowcount = "rowcount");
822a6eba 2565 if (rowcount != 1)
2566 return(SMS_INTERNAL);
2567 set_pop_usage(mid, 1);
2568 com_err(whoami, 0, "set login name to %s and pobox to %s", login,
711660a5 2569 strtrim(machname));
2570 incremental_after("users", buffer, 0);
822a6eba 2571
2572 /* create group list */
2573 if (set_next_object_id("gid", "list"))
44bd6f44 2574 return(SMS_NO_ID);
822a6eba 2575 if (set_next_object_id("list_id", "list"))
44bd6f44 2576 return(SMS_NO_ID);
822a6eba 2577## repeat retrieve (list_id = values.value) where values.name = "list_id"
8ac9ee7a 2578## inquire_equel(rowcount = "rowcount");
822a6eba 2579 if (rowcount != 1)
2580 return(SMS_INTERNAL);
711660a5 2581 incremental_clear_before();
822a6eba 2582## repeat append list (name = @login, #list_id = @list_id, active = 1,
2583## public = 0, hidden = 0, maillist = 0, group = 1,
2584## #gid = values.value, desc = "User Group",
2585## acl_type = "USER", acl_id = @users_id, modtime = "now",
2586## modby = @who, modwith = @entity)
2587## where values.name = "gid"
8ac9ee7a 2588## inquire_equel(rowcount = "rowcount");
44bd6f44 2589 if (rowcount != 1)
2590 return(SMS_INTERNAL);
711660a5 2591 sprintf(buffer, "l.list_id = %d", list_id);
2592 incremental_after("list", buffer, 0);
2593 aargv[0] = (char *) list_id;
2594 aargv[1] = "USER";
2595 aargv[2] = (char *) users_id;
2596 incremental_clear_before();
a6683dad 2597## repeat append imembers (#list_id = @list_id, member_type = "USER",
2598## member_id = @users_id, ref_count = 1, direct = 1)
8ac9ee7a 2599## inquire_equel(rowcount = "rowcount");
822a6eba 2600 if (rowcount != 1)
2601 return(SMS_INTERNAL);
711660a5 2602 incremental_after("members", 0, argv);
822a6eba 2603 com_err(whoami, 0, "group list created");
2604
2605 /* decide where to put filesystem */
2606 maxsize = 0;
2607 directory = NULL;
2608## repeat retrieve (mid = n.mach_id, dir = trim(n.#dir), nid = n.nfsphys_id,
2609## flag = n.status, size = n.#size, alloc = n.allocated) {
2610 if ((flag & utype) && (size != 0) && (size - alloc > maxsize)) {
2611 maxsize = size - alloc;
2612 if (directory)
2613 free(directory);
2614 directory = strsave(dir);
2615 pid = nid;
2616 m_id = mid;
2617 }
a6cb4d4c 2618## }
822a6eba 2619 if (maxsize == 0)
44bd6f44 2620 return(SMS_NO_FILESYS);
822a6eba 2621
2622 /* create filesystem */
2623 if (set_next_object_id("filsys_id", "filesys"))
44bd6f44 2624 return(SMS_NO_ID);
711660a5 2625 incremental_clear_before();
822a6eba 2626## repeat append filesys (filsys_id = values.value, phys_id = @pid,
2627## label = @login, type = "NFS", mach_id = @m_id,
4f16dc86 2628## name = @directory + "/" + @login,
2629## mount = "/mit/" + @login,
822a6eba 2630## access = "w", comments = "User Locker",
2631## owner = @users_id, owners = @list_id, createflg = 1,
2632## lockertype = "HOMEDIR", modtime = "now",
2633## modby = @who, modwith = @entity)
2634## where values.name = "filsys_id"
8ac9ee7a 2635## inquire_equel(rowcount = "rowcount");
822a6eba 2636 if (rowcount != 1)
2637 return(SMS_INTERNAL);
711660a5 2638 incremental_after("filesys",
2639 "fs.filsys_id = values.value and values.name = \"filsys_id\"",
2640 0);
822a6eba 2641 com_err(whoami, 0, "filesys created on mach %d in %s/%s", m_id,
4f16dc86 2642 directory, login);
822a6eba 2643
2644 /* set quota */
2645## repeat retrieve (quota = values.value) where values.name = "def_quota"
8ac9ee7a 2646## inquire_equel(rowcount = "rowcount");
822a6eba 2647 if (rowcount != 1)
44bd6f44 2648 return(SMS_NO_QUOTA);
711660a5 2649 incremental_clear_before();
822a6eba 2650## repeat append nfsquota (#users_id = @users_id, filsys_id = values.value,
e7fa3293 2651## #quota = @quota, phys_id = @pid, modtime = "now",
2652## modby = @who, modwith = @entity)
822a6eba 2653## where values.name = "filsys_id"
8ac9ee7a 2654## inquire_equel(rowcount = "rowcount");
822a6eba 2655 if (rowcount != 1)
2656 return(SMS_INTERNAL);
2657## repeat replace nfsphys (allocated = nfsphys.allocated + @quota)
2658## where nfsphys.nfsphys_id = filesys.#phys_id and
2659## filesys.filsys_id = values.value and values.name = "filsys_id"
8ac9ee7a 2660## inquire_equel(rowcount = "rowcount");
822a6eba 2661 if (rowcount != 1)
2662 return(SMS_INTERNAL);
711660a5 2663 aargv[0] = login;
2664 aargv[1] = login;
2665 sprintf(buffer, "nq.users_id = %d and nq.filsys_id = values.value and values.name = \"filsys_id\"", users_id);
2666 incremental_after("nfsquota", buffer, argv);
822a6eba 2667 com_err(whoami, 0, "quota of %d assigned", quota);
2668
4f16dc86 2669## repeat replace tblstats (updates = tblstats.updates + 1, modtime = "now")
2670## where tblstats.table = "users"
2671## repeat replace tblstats (appends = tblstats.appends + 1, modtime = "now")
2672## where tblstats.table = "list" or tblstats.table = "filesys" or
2673## tblstats.table = "nfsquota"
822a6eba 2674 return(SMS_SUCCESS);
2675##}
2676
2677
2678
2679/** set_pop_usage - incr/decr usage count for pop server in serverhosts talbe
2680 **
2681 ** Inputs:
2682 ** id of machine
2683 ** delta (will be +/- 1)
2684 **
2685 ** Description:
2686 ** - incr/decr value field in serverhosts table for pop/mach_id
2687 **
2688 **/
2689
2690static int set_pop_usage(id, count)
2691int id;
2692int count;
2693##{
2694## int mach_id = id;
2695## int n = count;
2696
2697## range of sh is serverhosts
2698## repeat replace sh (value1 = sh.value1 + @n)
44bd6f44 2699## where sh.service = "POP" and sh.#mach_id = @mach_id
a6cb4d4c 2700
2701 return(SMS_SUCCESS);
2702##}
822a6eba 2703
2704
c2408bd5 2705\f
05cdd922 2706/* Validation Routines */
2707
2708validate_row(q, argv, v)
2709 register struct query *q;
2710 char *argv[];
2711 register struct validate *v;
2712##{
2713## char *rvar;
2714## char *table;
2715## char *name;
2716## char qual[128];
2717## int rowcount;
2718
2719 /* build where clause */
2720 build_qual(v->qual, v->argc, argv, qual);
2721
2722 /* setup ingres variables */
2723 rvar = q->rvar;
2724 table = q->rtable;
2725 name = v->field;
2726
6388c51a 2727 if (log_flags & LOG_VALID)
b4182127 2728 /* tell the logfile what we're doing */
2729 com_err(whoami, 0, "validating row: %s", qual);
2730
05cdd922 2731 /* look for the record */
2732## range of rvar is table
2733## retrieve (rowcount = count(rvar.name where qual))
e1795ce1 2734 if (ingres_errno) return(sms_errcode);
05cdd922 2735 if (rowcount == 0) return(SMS_NO_MATCH);
2736 if (rowcount > 1) return(SMS_NOT_UNIQUE);
2737 return(SMS_EXISTS);
2738##}
2739
2740validate_fields(q, argv, vo, n)
2741 struct query *q;
2742 register char *argv[];
2743 register struct valobj *vo;
2744 register int n;
2745{
2746 register int status;
05cdd922 2747
2748 while (--n >= 0) {
2749 switch (vo->type) {
2750 case V_NAME:
6388c51a 2751 if (log_flags & LOG_VALID)
b4182127 2752 com_err(whoami, 0, "validating %s in %s: %s",
05cdd922 2753 vo->namefield, vo->table, argv[vo->index]);
05cdd922 2754 status = validate_name(argv, vo);
2755 break;
2756
2757 case V_ID:
6388c51a 2758 if (log_flags & LOG_VALID)
b4182127 2759 com_err(whoami, 0, "validating %s in %s: %s",
05cdd922 2760 vo->idfield, vo->table, argv[vo->index]);
05cdd922 2761 status = validate_id(argv, vo);
2762 break;
2763
92a943d6 2764 case V_DATE:
6388c51a 2765 if (log_flags & LOG_VALID)
92a943d6 2766 com_err(whoami, 0, "validating date: %s", argv[vo->index]);
2767 status = validate_date(argv, vo);
2768 break;
2769
05cdd922 2770 case V_TYPE:
6388c51a 2771 if (log_flags & LOG_VALID)
b4182127 2772 com_err(whoami, 0, "validating %s type: %s",
05cdd922 2773 vo->table, argv[vo->index]);
05cdd922 2774 status = validate_type(argv, vo);
2775 break;
2776
2777 case V_TYPEDATA:
6388c51a 2778 if (log_flags & LOG_VALID)
92a943d6 2779 com_err(whoami, 0, "validating typed data (%s): %s",
2780 argv[vo->index - 1], argv[vo->index]);
05cdd922 2781 status = validate_typedata(q, argv, vo);
2782 break;
2783
822a6eba 2784 case V_RENAME:
6388c51a 2785 if (log_flags & LOG_VALID)
822a6eba 2786 com_err(whoami, 0, "validating rename %s in %s",
2787 argv[vo->index], vo->table);
2788 status = validate_rename(argv, vo);
2789 break;
2790
2791 case V_CHAR:
6388c51a 2792 if (log_flags & LOG_VALID)
822a6eba 2793 com_err(whoami, 0, "validating chars: %s", argv[vo->index]);
2794 status = validate_chars(argv[vo->index]);
05cdd922 2795 break;
2796
92a943d6 2797 case V_SORT:
2798 status = SMS_EXISTS;
2799 break;
2800
e1795ce1 2801 case V_LOCK:
2802 status = lock_table(vo);
2803 break;
05cdd922 2804 }
2805
2806 if (status != SMS_EXISTS) return(status);
2807 vo++;
2808 }
2809
2810 return(SMS_SUCCESS);
2811}
2812
822a6eba 2813
2814/* validate_chars: verify that there are no illegal characters in
2815 * the string. Legal characters are printing chars other than
331b982e 2816 * ", *, ?, \, [ and ].
822a6eba 2817 */
2818static int illegalchars[] = {
2819 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* ^@ - ^O */
2820 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* ^P - ^_ */
2821 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, /* SPACE - / */
2822 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, /* 0 - ? */
2823 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* @ - O */
331b982e 2824 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, /* P - _ */
822a6eba 2825 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* ` - o */
2826 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, /* p - ^? */
2827 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2828 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2829 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2830 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2831 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2832 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2833 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2834 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2835};
2836
2837validate_chars(s)
2838register char *s;
2839{
2840 while (*s)
2841 if (illegalchars[*s++])
2842 return(SMS_BAD_CHAR);
2843 return(SMS_EXISTS);
2844}
2845
2846
05cdd922 2847validate_id(argv, vo)
2848 char *argv[];
2849 register struct valobj *vo;
2850##{
2851## char *name;
2852## char *table;
2853## char *namefield;
2854## char *idfield;
2855## int id;
2856## int rowcount;
122ec372 2857 register char *c;
05cdd922 2858
2859 name = argv[vo->index];
2860 table = vo->table;
122ec372 2861 /* minor kludge to upcasify machine names */
822a6eba 2862 if (!strcmp(table, "machine"))
122ec372 2863 for (c = name; *c; c++) if (islower(*c)) *c = toupper(*c);
05cdd922 2864 namefield = vo->namefield;
2865 idfield = vo->idfield;
822a6eba 2866 if (!strcmp(namefield, "uid")) {
9119288e 2867## retrieve (id = table.idfield) where table.namefield = int4(name)
e1795ce1 2868 if (ingres_errno) return(sms_errcode);
9119288e 2869## inquire_equel (rowcount = "rowcount")
2870 } else {
2871## retrieve (id = table.idfield) where table.namefield = name
e1795ce1 2872 if (ingres_errno) return(sms_errcode);
9119288e 2873## inquire_equel (rowcount = "rowcount")
2874 }
05cdd922 2875 if (rowcount != 1) return(vo->error);
2876 *(int *)argv[vo->index] = id;
2877 return(SMS_EXISTS);
2878##}
2879
2880validate_name(argv, vo)
2881 char *argv[];
2882 register struct valobj *vo;
2883##{
2884## char *name;
2885## char *table;
2886## char *namefield;
2887## int rowcount;
44bd6f44 2888 register char *c;
05cdd922 2889
2890 name = argv[vo->index];
2891 table = vo->table;
2892 namefield = vo->namefield;
44bd6f44 2893 if (!strcmp(table, "servers") && !strcmp(namefield, "name")) {
2894 for (c = name; *c; c++)
2895 if (islower(*c))
2896 *c = toupper(*c);
2897 }
05cdd922 2898## retrieve (rowcount = countu(table.namefield
2899## where table.namefield = name))
e1795ce1 2900 if (ingres_errno) return(sms_errcode);
05cdd922 2901 return ((rowcount == 1) ? SMS_EXISTS : vo->error);
2902##}
2903
92a943d6 2904validate_date(argv, vo)
2905 char *argv[];
2906 struct valobj *vo;
2907##{
2908## char *idate;
2909## double dd;
2910## int errorno;
2911
2912 idate = argv[vo->index];
2913
2914## retrieve (dd = interval("years", date(idate) - date("today")))
2915## inquire_equel (errorno = "errorno")
2916 if (errorno != 0 || dd > 5.0) return(SMS_DATE);
44bd6f44 2917 return(SMS_EXISTS);
92a943d6 2918##}
2919
822a6eba 2920
2921validate_rename(argv, vo)
2922char *argv[];
2923struct valobj *vo;
2924##{
2925## char *name, *table, *namefield, *idfield;
2926## int id;
2927 register char *c;
2928
2929 c = name = argv[vo->index];
2930 while (*c)
2931 if (illegalchars[*c++])
2932 return(SMS_BAD_CHAR);
2933 table = vo->table;
2934 /* minor kludge to upcasify machine names */
2935 if (!strcmp(table, "machine"))
2936 for (c = name; *c; c++) if (islower(*c)) *c = toupper(*c);
2937 namefield = vo->namefield;
2938 idfield = vo->idfield;
2939 id = -1;
2940 if (idfield == 0) {
2941 if (!strcmp(argv[vo->index], argv[vo->index - 1]))
2942 return(SMS_EXISTS);
2943## retrieve (id = any(table.namefield where table.namefield = name))
e1795ce1 2944 if (ingres_errno) return(sms_errcode);
822a6eba 2945 if (id)
2946 return(vo->error);
2947 else
2948 return(SMS_EXISTS);
2949 }
2950## retrieve (id = table.idfield) where table.namefield = name
e1795ce1 2951 if (ingres_errno) return(sms_errcode);
822a6eba 2952 if (id == -1 || id == *(int *)argv[vo->index - 1])
2953 return(SMS_EXISTS);
2954 else
2955 return(vo->error);
2956##}
2957
2958
05cdd922 2959validate_type(argv, vo)
2960 char *argv[];
2961 register struct valobj *vo;
2962##{
2963## char *typename;
2964## char *value;
822a6eba 2965## int exists;
05cdd922 2966 register char *c;
2967
2968 typename = vo->table;
822a6eba 2969 c = value = argv[vo->index];
2970 while (*c)
2971 if (illegalchars[*c++])
2972 return(SMS_BAD_CHAR);
05cdd922 2973
2974 /* uppercase type fields */
2975 for (c = value; *c; c++) if (islower(*c)) *c = toupper(*c);
2976
2977## range of a is alias
822a6eba 2978## repeat retrieve (exists = any(a.trans where a.name = @typename and
05cdd922 2979## a.type = "TYPE" and
2980## a.trans = @value))
e1795ce1 2981 if (ingres_errno) return(sms_errcode);
822a6eba 2982 return (exists ? SMS_EXISTS : vo->error);
05cdd922 2983##}
2984
2985/* validate member or type-specific data field */
2986
2987validate_typedata(q, argv, vo)
2988 register struct query *q;
2989 register char *argv[];
2990 register struct valobj *vo;
2991##{
2992## char *name;
2993## char *field_type;
822a6eba 2994## char data_type[129];
05cdd922 2995## int id;
05cdd922 2996## int rowcount;
822a6eba 2997 char *index();
a6cb4d4c 2998 register char *c;
05cdd922 2999
3000 /* get named object */
3001 name = argv[vo->index];
3002
3003 /* get field type string (known to be at index-1) */
3004 field_type = argv[vo->index-1];
3005
3006 /* get corresponding data type associated with field type name */
3007## repeat retrieve (data_type = alias.trans)
3008## where alias.#name = @field_type and alias.type = "TYPEDATA"
e1795ce1 3009 if (ingres_errno) return(sms_errcode);
05cdd922 3010## inquire_equel (rowcount = "rowcount")
3011 if (rowcount != 1) return(SMS_TYPE);
3012
3013 /* now retrieve the record id corresponding to the named object */
822a6eba 3014 if (index(data_type, ' '))
3015 *index(data_type, ' ') = 0;
05cdd922 3016 if (!strcmp(data_type, "user")) {
3017 /* USER */
3018## repeat retrieve (id = users.users_id) where users.login = @name
3019## inquire_equel (rowcount = "rowcount")
3020 if (rowcount != 1) return(SMS_USER);
3021
3022 } else if (!strcmp(data_type, "list")) {
3023 /* LIST */
3024## repeat retrieve (id = list.list_id) where list.#name = @name
3025## inquire_equel (rowcount = "rowcount")
822a6eba 3026 if (rowcount != 1) {
3027 /* if idfield is non-zero, then if argv[0] matches the string
3028 * that we're trying to resolve, we should get the value of
3029 * values.[idfield] for the id.
3030 */
3031 if (vo->idfield && !strcmp(argv[0], argv[vo->index])) {
4f16dc86 3032 set_next_object_id(q->validate->object_id, q->rtable);
822a6eba 3033 name = vo->idfield;
4f16dc86 3034## repeat retrieve (id = values.value) where values.#name = @name
822a6eba 3035## inquire_equel(rowcount = "rowcount")
3036 if (rowcount != 1) return(SMS_LIST);
3037 } else
3038 return(SMS_LIST);
3039 }
05cdd922 3040 } else if (!strcmp(data_type, "machine")) {
3041 /* MACHINE */
a6cb4d4c 3042 for (c = name; *c; c++) if (islower(*c)) *c = toupper(*c);
05cdd922 3043## repeat retrieve (id = machine.mach_id) where machine.#name = @name
3044## inquire_equel (rowcount = "rowcount")
3045 if (rowcount != 1) return(SMS_MACHINE);
3046
3047 } else if (!strcmp(data_type, "string")) {
3048 /* STRING */
3049## range of s is strings
822a6eba 3050## repeat retrieve (id = s.string_id) where s.string = @name
05cdd922 3051## inquire_equel (rowcount = "rowcount")
3052 if (rowcount == 0) {
3053 if (q->type != APPEND) return(SMS_STRING);
3054## range of v is values
3055## retrieve (id = v.value) where v.#name = "strings_id"
3056 id++;
3057## replace v (value = id) where v.#name = "strings_id"
822a6eba 3058## append to strings (string_id = id, string = name)
05cdd922 3059 }
822a6eba 3060 } else if (!strcmp(data_type, "none")) {
3061 id = 0;
05cdd922 3062 } else {
3063 return(SMS_TYPE);
3064 }
3065
3066 /* now set value in argv */
3067 *(int *)argv[vo->index] = id;
3068
3069 return (SMS_EXISTS);
3070##}
3071
05cdd922 3072
e1795ce1 3073/* Lock the table named by the validation object */
3074
3075lock_table(vo)
3076struct valobj *vo;
3077##{
3078## char *table, *idfield;
3079## int rowcount;
3080
3081 table = vo->table;
3082 idfield = vo->idfield;
3083## replace table (modtime = "now") where table.idfield = 0
3084 if (ingres_errno) return(sms_errcode);
3085## inquire_equel (rowcount = "rowcount")
3086 if (rowcount != 1)
3087 return(vo->error);
3088 else
3089 return(SMS_EXISTS);
3090##}
3091
3092
822a6eba 3093/* Check the database at startup time. For now this just resets the
3094 * inprogress flags that the DCM uses.
3095 */
05cdd922 3096
822a6eba 3097sanity_check_database()
3098##{
05cdd922 3099##}
This page took 1.005324 seconds and 5 git commands to generate.