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