]> andersk Git - moira.git/blame - server/qsupport.qc
punt unused function followup_amtl; have add_member_to_list and
[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
711660a5 1380/* followup_gnfq: Fix the directory name & modby fields
1381 * argv[0] = filsys_id
1382 * argv[2] = ascii(quota)
1383 */
1384
1385followup_gnfq(q, sq, v, action, actarg, cl)
1386 struct query *q;
1387 register struct save_queue *sq;
1388 struct validate *v;
1389 register int (*action)();
1390 register int actarg;
1391 client *cl;
1392##{
1393 register int j;
1394 char **argv, *malloc();
1395## int id, rowcount;
1396## char *name, *label;
1397
1398 while (sq_get_data(sq, &argv)) {
1399 id = atoi(argv[3]);
1400 free(argv[3]);
1401 argv[3] = malloc(256);
1402 name = argv[3];
1403 if (id == 0) {
1404 label = argv[0];
1405## repeat retrieve (name = filesys.#name) where filesys.#label = @label
1406 } else {
1407## repeat retrieve (name = nfsphys.dir) where nfsphys.nfsphys_id = @id
1408 }
1409## inquire_equel(rowcount = "rowcount")
1410 if (rowcount != 1) {
1411 sprintf(argv[3], "#%d", id);
1412 }
1413
1414 id = atoi(argv[6]);
1415 free(argv[6]);
1416 argv[6] = malloc(256);
1417 name = argv[6];
1418 if (id > 0)
1419## repeat retrieve (name = users.login) where users.users_id = @id
1420 else {
1421 id = -id;
1422## repeat retrieve (name = strings.string) where strings.string_id = @id
1423 id = -id;
1424 }
1425## inquire_equel(rowcount = "rowcount")
1426 if (rowcount != 1) {
1427 sprintf(argv[6], "#%d", id);
1428 }
1429 (*action)(q->vcnt, argv, actarg);
1430 for (j = 0; j < q->vcnt; j++)
1431 free(argv[j]);
1432 free(argv);
1433 }
1434 sq_destroy(sq);
1435 return(SMS_SUCCESS);
1436##}
1437
1438
822a6eba 1439/* followup_anfq: Add allocation to nfsphys after creating quota.
1440 * argv[0] = filsys_id
1441 * argv[2] = ascii(quota)
1442 */
1443
1444followup_anfq(q, argv, cl)
1445 struct query *q;
1446 char **argv;
1447 client *cl;
1448##{
1449## int quota, user, fs, who;
1450## char *entity;
1451
1452 fs = *(int *)argv[0];
1453 user = *(int *)argv[1];
1454 quota = atoi(argv[2]);
711660a5 1455 who = cl->client_id;
822a6eba 1456 entity = cl->entity;
1457
1458## repeat replace nq (modtime = "now", modby = @who, modwith = @entity)
1459## where nq.filsys_id = @fs and nq.users_id = @user
1460## repeat replace nfsphys (allocated = nfsphys.allocated + @quota)
1461## where nfsphys.nfsphys_id = filesys.#phys_id and filesys.filsys_id = @fs
02ccf7ad 1462 if (ingres_errno) return(sms_errcode);
822a6eba 1463 return(SMS_SUCCESS);
1464##}
1465
1466
1467/* followup_gzcl:
1468 */
1469
1470followup_gzcl(q, sq, v, action, actarg, cl)
1471 register struct query *q;
1472 register struct save_queue *sq;
1473 register struct validate *v;
1474 register int (*action)();
92a943d6 1475 int actarg;
822a6eba 1476 client *cl;
92a943d6 1477##{
822a6eba 1478## char *name;
1479## int rowcount, id;
1480 char **argv;
1481 int i;
92a943d6 1482
822a6eba 1483 while (sq_get_data(sq, &argv)) {
1484 sms_trim_args(q->vcnt, argv);
92a943d6 1485
822a6eba 1486 id = atoi(argv[i = q->vcnt - 2]);
1487 free(argv[i]);
711660a5 1488 name = argv[i] = malloc(256);
1489 if (id > 0)
1490## repeat retrieve (name = users.login) where users.users_id = @id
1491 else {
1492 id = -id;
1493## repeat retrieve (name = strings.string) where strings.string_id = @id
1494 id = -id;
1495 }
822a6eba 1496## inquire_equel(rowcount = "rowcount")
1497 if (rowcount != 1)
1498 sprintf(argv[i], "#%d", id);
1499
1500 for (i = 1; i < 8; i+=2) {
1501 id = atoi(argv[i+1]);
1502 free(argv[i+1]);
1503 if ((name = argv[i+1] = malloc(33)) == NULL)
1504 return(SMS_NO_MEM);
1505 if (!strcmp(argv[i], "LIST")) {
1506## repeat retrieve (name = list.#name) where list.list_id = @id
1507## inquire_equel(rowcount = "rowcount")
1508 if (rowcount != 1)
1509 strcpy(name, "???");
1510 } else if (!strcmp(argv[i], "USER")) {
1511## repeat retrieve (name = users.login) where users.users_id = @id
f0516942 1512## inquire_equel(rowcount = "rowcount")
1513 if (rowcount != 1)
1514 strcpy(name, "???");
1515 } else if (!strcmp(argv[i], "KERBEROS")) {
1516## repeat retrieve (name = strings.string) where strings.string_id = @id
822a6eba 1517## inquire_equel(rowcount = "rowcount")
1518 if (rowcount != 1)
1519 strcpy(name, "???");
1520 } else if (!strcmp(argv[i], "NONE")) {
1521 strcpy(name, "NONE");
1522 } else {
1523 strcpy(name, "???");
1524 }
1525 }
92a943d6 1526
822a6eba 1527 /* send the data */
1528 (*action)(q->vcnt, argv, actarg);
1529
1530 /* free saved data */
1531 for (i = 0; i < q->vcnt; i++)
1532 free(argv[i]);
1533 free(argv);
1534 }
1535 sq_destroy(sq);
92a943d6 1536 return(SMS_SUCCESS);
1537##}
1538
05cdd922 1539
822a6eba 1540/* followup_gsha:
1541 */
1542
1543followup_gsha(q, sq, v, action, actarg, cl)
05cdd922 1544 register struct query *q;
822a6eba 1545 register struct save_queue *sq;
1546 register struct validate *v;
1547 register int (*action)();
1548 int actarg;
1549 client *cl;
05cdd922 1550##{
822a6eba 1551## char *name;
1552## int rowcount, id;
1553 char **argv;
1554 int i;
05cdd922 1555
822a6eba 1556 while (sq_get_data(sq, &argv)) {
1557 sms_trim_args(q->vcnt, argv);
05cdd922 1558
822a6eba 1559 id = atoi(argv[4]);
1560 free(argv[4]);
711660a5 1561 name = argv[4] = malloc(256);
1562 if (id > 0)
1563## repeat retrieve (name = users.login) where users.users_id = @id
1564 else {
1565 id = -id;
1566## repeat retrieve (name = strings.string) where strings.string_id = @id
1567 id = -id;
1568 }
822a6eba 1569## inquire_equel(rowcount = "rowcount")
1570 if (rowcount != 1)
1571 sprintf(argv[4], "#%d", id);
1572
1573 id = atoi(argv[2]);
1574 free(argv[2]);
1575 if ((name = argv[2] = malloc(33)) == NULL)
1576 return(SMS_NO_MEM);
1577 if (!strcmp(argv[1], "LIST")) {
1578## repeat retrieve (name = list.#name) where list.list_id = @id
1579## inquire_equel(rowcount = "rowcount")
1580 if (rowcount != 1)
1581 strcpy(name, "???");
1582 } else if (!strcmp(argv[1], "USER")) {
1583## repeat retrieve (name = users.login) where users.users_id = @id
f0516942 1584## inquire_equel(rowcount = "rowcount")
1585 if (rowcount != 1)
1586 strcpy(name, "???");
1587 } else if (!strcmp(argv[1], "KERBEROS")) {
1588## repeat retrieve (name = strings.string) where strings.string_id = @id
822a6eba 1589## inquire_equel(rowcount = "rowcount")
1590 if (rowcount != 1)
1591 strcpy(name, "???");
1592 } else if (!strcmp(argv[1], "NONE")) {
1593 strcpy(name, "NONE");
1594 } else {
1595 strcpy(name, "???");
1596 }
05cdd922 1597
822a6eba 1598 /* send the data */
1599 (*action)(q->vcnt, argv, actarg);
1600
1601 /* free saved data */
1602 for (i = 0; i < q->vcnt; i++)
1603 free(argv[i]);
1604 free(argv);
1605 }
1606 sq_destroy(sq);
1607 return(SMS_SUCCESS);
1608##}
05cdd922 1609
05cdd922 1610
822a6eba 1611\f
1612/* Special query routines */
30967516 1613
822a6eba 1614/* set_pobox - this does all of the real work.
1615 * argv = user_id, type, box
1616 * if type is POP, then box should be a machine, and its ID should be put in
1617 * pop_id. If type is SMTP, then box should be a string and its ID should
1618 * be put in box_id. If type is NONE, then box doesn't matter.
1619 */
1620
1621int set_pobox(q, argv, cl)
1622 struct query *q;
1623 char **argv;
1624 client *cl;
1625##{
1626## int user, id, rowcount;
1627## char *box, potype[9];
1628
1629 box = argv[2];
1630 user = *(int *)argv[0];
1631
1632## repeat retrieve (id = users.pop_id, potype = users.#potype)
1633## where users.users_id = @user
02ccf7ad 1634 if (ingres_errno) return(sms_errcode);
e7fa3293 1635 if (!strcmp(strtrim(potype), "POP"))
822a6eba 1636 set_pop_usage(id, -1);
1637
1638 if (!strcmp(argv[1], "POP")) {
1639## repeat retrieve (id=machine.mach_id) where machine.name=uppercase(@box)
1640## inquire_equel(rowcount = "rowcount")
1641 if (rowcount != 1)
1642 return(SMS_MACHINE);
1643## repeat replace users (#potype = "POP", pop_id = @id)
1644## where users.users_id = @user
1645 set_pop_usage(id, 1);
1646 } else if (!strcmp(argv[1], "SMTP")) {
353cb0da 1647 if (index(box, '/') || index(box, '|'))
1648 return(SMS_BAD_CHAR);
822a6eba 1649## range of s is strings
1650## repeat retrieve (id = s.string_id) where s.string = @box
1651## inquire_equel (rowcount = "rowcount")
1652 if (rowcount == 0) {
1653## range of v is values
1654## repeat retrieve (id = v.value) where v.name = "strings_id"
1655 id++;
1656## repeat replace v (value = @id) where v.name = "strings_id"
1657## append to strings (string_id = id, string = box)
1658 }
1659## repeat replace users (#potype = "SMTP", box_id = @id)
1660## where users.users_id = @user
1661 } else /* argv[1] == "NONE" */ {
1662## repeat replace users (#potype = "NONE") where users.users_id = @user
1663 }
1664
1665 set_pobox_modtime(q, argv, cl);
1666## repeat replace tblstats (updates = tblstats.updates + 1, modtime = "now")
1667## where tblstats.#table = "users"
02ccf7ad 1668 if (ingres_errno) return(sms_errcode);
30967516 1669 return(SMS_SUCCESS);
1670##}
1671
30967516 1672
822a6eba 1673/* get_list_info: passed a wildcard list name, returns lots of stuff about
1674 * each list. This is tricky: first build a queue of all requested
44bd6f44 1675 * data. Rest of processing consists of fixing gid, ace_name, and modby.
822a6eba 1676 */
1677
1678get_list_info(q, aargv, cl, action, actarg)
30967516 1679 register struct query *q;
822a6eba 1680 char **aargv;
1681 client *cl;
1682 register int (*action)();
1683 int actarg;
30967516 1684##{
822a6eba 1685 char *argv[13], *malloc(), *realloc();
1686## char *name, acl_type[9], listname[33], active[5], public[5], hidden[5];
1687## char maillist[5], group[5], gid[6], acl_name[33], desc[256], modtime[27];
711660a5 1688## char modby[256], modwith[9];
822a6eba 1689## int id, rowcount, acl_id, hid, modby_id;
1690 int returned;
1691 struct save_queue *sq, *sq_create();
30967516 1692
822a6eba 1693 returned = rowcount = 0;
1694 name = aargv[0];
30967516 1695
822a6eba 1696 sq = sq_create();
1697## range of l is list
1698## repeat retrieve (id = l.list_id) where l.#name = @name {
1699 sq_save_data(sq, id);
1700 rowcount++;
1701## }
711660a5 1702 if (ingres_errno) return(sms_errcode);
822a6eba 1703 if (rowcount == 0)
1704 return(SMS_NO_MATCH);
1705
1706 argv[0] = listname; argv[1] = active; argv[2] = public; argv[3] = hidden;
1707 argv[4] = maillist; argv[5] = group; argv[6] = gid; argv[7] = acl_type;
1708 argv[8] = acl_name; argv[9] = desc; argv[10] = modtime; argv[11] = modby;
1709 argv[12] = modwith;
1710
1711 while (sq_get_data(sq, &id)) {
1712 if (id == 0)
1713 continue;
1714 argv[6] = gid;
1715## repeat retrieve (listname = l.#name, active = text(l.#active),
1716## public = text(l.#public), hidden = text(l.#hidden),
1717## hid = l.#hidden, maillist = text(l.#maillist),
1718## group = text(l.#group), gid = text(l.#gid),
1719## acl_type = trim(l.#acl_type), acl_id = l.#acl_id,
1720## desc = l.#desc, modtime = l.#modtime, modby_id = l.#modby,
1721## modwith =l.#modwith)
1722## where l.list_id = @id
711660a5 1723 if (ingres_errno) return(sms_errcode);
822a6eba 1724
1725 if (atoi(gid) == -1)
1726 argv[6] = UNIQUE_GID;
1727
1728 if (!strcmp(acl_type, "LIST")) {
1729## repeat retrieve (acl_name = l.#name) where l.list_id = @acl_id
1730## inquire_equel(rowcount = "rowcount")
1731 if (rowcount != 1)
1732 strcpy(acl_name, "???");
1733 } else if (!strcmp(acl_type, "USER")) {
1734## repeat retrieve (acl_name = users.#login)
1735## where users.users_id = @acl_id
f0516942 1736## inquire_equel(rowcount = "rowcount")
1737 if (rowcount != 1)
1738 strcpy(acl_name, "???");
1739 } else if (!strcmp(acl_type, "KERBEROS")) {
1740## repeat retrieve (acl_name = strings.string)
1741## where strings.string_id = @acl_id
822a6eba 1742## inquire_equel(rowcount = "rowcount")
1743 if (rowcount != 1)
1744 strcpy(acl_name, "???");
1745 } else if (!strcmp(acl_type, "NONE")) {
1746 strcpy(acl_name, "NONE");
1747 } else
1748 strcpy(acl_name, "???");
1749
711660a5 1750 if (modby_id > 0)
1751## repeat retrieve (modby = users.login) where users.users_id = @modby_id
1752 else {
1753 modby_id = -modby_id;
1754## repeat retrieve (modby = strings.string)
1755## where strings.string_id = @modby_id
1756 modby_id = -modby_id;
1757 }
822a6eba 1758## inquire_equel(rowcount = "rowcount")
1759 if (rowcount != 1)
711660a5 1760 sprintf(modby, "#%d", modby_id);
1761 if (ingres_errno) return(sms_errcode);
822a6eba 1762
1763 sms_trim_args(q->vcnt, argv);
1764 returned++;
1765 (*action)(q->vcnt, argv, actarg);
1766 }
30967516 1767
822a6eba 1768 sq_destroy(sq);
02ccf7ad 1769 if (ingres_errno) return(sms_errcode);
822a6eba 1770## repeat replace tblstats (retrieves = tblstats.retrieves + 1)
1771## where tblstats.#table = "list"
5e06ce45 1772
822a6eba 1773 return (SMS_SUCCESS);
1774##}
1775
1776
a6683dad 1777/* Add_member_to_list: do list flattening as we go! MAXLISTDEPTH is
1778 * how many different ancestors a member is allowed to have.
1779 */
1780
1781#define MAXLISTDEPTH 100
1782
1783int add_member_to_list(q, argv, cl)
1784 struct query *q;
1785 char **argv;
1786 client *cl;
1787##{
189bd6e7 1788## int id, lid, mid, exists, error, who;
1789## char *mtype, dtype[9], buf[256], *entity;
a6683dad 1790 int ancestors[MAXLISTDEPTH], acount, a;
1791 int descendants[MAXLISTDEPTH], dcount, d;
1792 char *dtypes[MAXLISTDEPTH];
711660a5 1793 char *iargv[3];
a6683dad 1794
1795## range of m is imembers
1796 lid = *(int *)argv[0];
1797 mtype = argv[1];
1798 mid = *(int *)argv[2];
1799## repeat retrieve (exists = any(m.list_id where m.list_id=@lid and
1800## m.member_id = @mid and m.member_type = @mtype
1801## and m.direct = 1))
1802 if (exists)
1803 return(SMS_EXISTS);
353cb0da 1804 if (!strcasecmp(mtype, "STRING")) {
1805## repeat retrieve (buf = strings.string) where strings.string_id = @mid
1806 if (index(buf, '/') || index(buf, '|'))
1807 return(SMS_BAD_CHAR);
1808 }
1809
a6683dad 1810 ancestors[0] = lid;
1811 acount = 1;
1812## repeat retrieve (id = m.list_id)
1813## where m.member_id = @lid and m.member_type = "LIST" {
1814 ancestors[acount++] = id;
1815 if (acount >= MAXLISTDEPTH) {
1816## endretrieve
1817 }
1818## }
711660a5 1819 if (ingres_errno) return(sms_errcode);
a6683dad 1820 if (acount >= MAXLISTDEPTH) {
1821 return(SMS_INTERNAL);
1822 }
1823 descendants[0] = mid;
1824 dtypes[0] = mtype;
1825 dcount = 1;
1826 error = 0;
1827 if (!strcmp(mtype, "LIST")) {
1828## repeat retrieve (id = m.member_id, dtype = m.member_type)
1829## where m.list_id = @mid {
1830 switch (dtype[0]) {
1831 case 'L':
1832 dtypes[dcount] = "LIST";
1833 break;
1834 case 'U':
1835 dtypes[dcount] = "USER";
1836 break;
1837 case 'S':
1838 dtypes[dcount] = "STRING";
1839 break;
1840 case 'K':
1841 dtypes[dcount] = "KERBEROS";
1842 break;
1843 default:
1844 error++;
1845## endretrieve
1846 }
1847 descendants[dcount++] = id;
1848 if (dcount >= MAXLISTDEPTH) {
1849 error++;
1850## endretrieve
1851 }
1852## }
711660a5 1853 if (ingres_errno) return(sms_errcode);
a6683dad 1854 if (error)
1855 return(SMS_INTERNAL);
1856 }
1857 for (a = 0; a < acount; a++) {
1858 lid = ancestors[a];
1859 for (d = 0; d < dcount; d++) {
1860 mid = descendants[d];
1861 mtype = dtypes[d];
1862 if (mid == lid && !strcmp(mtype, "LIST")) {
1863 return(SMS_LISTLOOP);
1864 }
1865## repeat retrieve (exists = any(m.ref_count where m.list_id = @lid
1866## and m.member_id = @mid
1867## and m.member_type = @mtype))
1868 if (exists) {
1869 if (a == 0 && d == 0)
1870## replace m (ref_count = m.ref_count+1, direct = 1)
1871## where m.list_id = lid and m.member_id = mid and
1872## m.member_type = mtype
1873 else
1874## replace m (ref_count = m.ref_count+1)
1875## where m.list_id = lid and m.member_id = mid and
1876## m.member_type = mtype
1877 } else {
711660a5 1878 incremental_clear_before();
a6683dad 1879 if (a == 0 && d == 0)
1880## append imembers (list_id=lid, member_id = mid, direct = 1,
1881## member_type=mtype, ref_count = 1)
1882 else
1883## append imembers (list_id=lid, member_id = mid,
1884## member_type=mtype, ref_count = 1)
711660a5 1885 iargv[0] = (char *)lid;
1886 iargv[1] = mtype;
1887 iargv[2] = (char *)mid;
1888 incremental_after("members", 0, iargv);
a6683dad 1889 }
1890 }
1891 }
189bd6e7 1892 lid = *(int *)argv[0];
1893 entity = cl->entity;
1894 who = cl->client_id;
1895## repeat replace list (modtime = "now", modby = @who, modwith = @entity)
1896## where list.#list_id = @lid
711660a5 1897 if (ingres_errno) return(sms_errcode);
a6683dad 1898 return(SMS_SUCCESS);
1899##}
1900
1901
1902/* Delete_member_from_list: do list flattening as we go!
1903 */
1904
1905int delete_member_from_list(q, argv, cl)
1906 struct query *q;
1907 char **argv;
1908 client *cl;
1909##{
189bd6e7 1910## int id, lid, mid, cnt, exists, error, who;
1911## char *mtype, dtype[9], *entity;
a6683dad 1912 int ancestors[MAXLISTDEPTH], acount, a;
1913 int descendants[MAXLISTDEPTH], dcount, d;
1914 char *dtypes[MAXLISTDEPTH];
711660a5 1915 char *iargv[3];
a6683dad 1916
1917## range of m is imembers
1918 lid = *(int *)argv[0];
1919 mtype = argv[1];
1920 mid = *(int *)argv[2];
1921## repeat retrieve (exists = any(m.list_id where m.list_id=@lid and
1922## m.member_id = @mid and m.member_type = @mtype
1923## and m.direct = 1))
711660a5 1924 if (ingres_errno) return(sms_errcode);
a6683dad 1925 if (!exists)
1926 return(SMS_NO_MATCH);
1927 ancestors[0] = lid;
1928 acount = 1;
1929## repeat retrieve (id = m.list_id)
1930## where m.member_id = @lid and m.member_type = "LIST" {
1931 ancestors[acount++] = id;
1932 if (acount >= MAXLISTDEPTH)
1933## endretrieve
1934## }
711660a5 1935 if (ingres_errno) return(sms_errcode);
a6683dad 1936 if (acount >= MAXLISTDEPTH)
1937 return(SMS_INTERNAL);
1938 descendants[0] = mid;
1939 dtypes[0] = mtype;
1940 dcount = 1;
1941 error = 0;
1942 if (!strcmp(mtype, "LIST")) {
1943## repeat retrieve (id = m.member_id, dtype = m.member_type)
1944## where m.list_id = @mid {
1945 switch (dtype[0]) {
1946 case 'L':
1947 dtypes[dcount] = "LIST";
1948 break;
1949 case 'U':
1950 dtypes[dcount] = "USER";
1951 break;
1952 case 'S':
1953 dtypes[dcount] = "STRING";
1954 break;
1955 case 'K':
1956 dtypes[dcount] = "KERBEROS";
1957 break;
1958 default:
1959 error++;
1960## endretrieve
1961 }
1962 descendants[dcount++] = id;
1963 if (dcount >= MAXLISTDEPTH)
1964## endretrieve
1965## }
711660a5 1966 if (ingres_errno) return(sms_errcode);
a6683dad 1967 if (error)
1968 return(SMS_INTERNAL);
1969 }
1970 for (a = 0; a < acount; a++) {
1971 lid = ancestors[a];
1972 for (d = 0; d < dcount; d++) {
1973 mid = descendants[d];
1974 mtype = dtypes[d];
1975 if (mid == lid && !strcmp(mtype, "LIST")) {
1976 return(SMS_LISTLOOP);
1977 }
1978## repeat retrieve (cnt = m.ref_count)
1979## where m.list_id = @lid and m.member_id = @mid
1980## and m.member_type = @mtype
1981 if (cnt <= 1) {
711660a5 1982 iargv[0] = (char *)lid;
1983 iargv[1] = mtype;
1984 iargv[2] = (char *)mid;
1985 incremental_before("members", 0, iargv);
a6683dad 1986## delete m where m.list_id = lid and m.member_id = mid and
1987## m.member_type = mtype
711660a5 1988 incremental_clear_after();
a6683dad 1989 } else if (a == 0 && d == 0) {
1990## replace m (ref_count = m.ref_count-1, direct = 0)
1991## where m.list_id = lid and m.member_id = mid and
1992## m.member_type = mtype
1993 } else {
1994## replace m (ref_count = m.ref_count-1)
353cb0da 1995## where m.list_id = lid and m.member_id = mid and
a6683dad 1996## m.member_type = mtype
1997 }
1998 }
1999 }
189bd6e7 2000 lid = *(int *)argv[0];
2001 entity = cl->entity;
2002 who = cl->client_id;
2003## repeat replace list (modtime = "now", modby = @who, modwith = @entity)
2004## where list.#list_id = @lid
711660a5 2005 if (ingres_errno) return(sms_errcode);
a6683dad 2006 return(SMS_SUCCESS);
2007##}
2008
2009
44bd6f44 2010/* get_ace_use - given a type and a name, return a type and a name.
2011 * The ace_type is one of "LIST", "USER", "RLIST", or "RUSER" in argv[0],
822a6eba 2012 * and argv[1] will contain the ID of the entity in question. The R*
2013 * types mean to recursively look at every containing list, not just
2014 * when the object in question is a direct member. On return, the
2015 * usage type will be one of LIST, SERVICE, FILESYS, QUOTA, QUERY, or ZEPHYR.
2016 */
2017
44bd6f44 2018int get_ace_use(q, argv, cl, action, actarg)
822a6eba 2019 struct query *q;
2020 char *argv[];
2021 client *cl;
2022 int (*action)();
2023 int actarg;
2024##{
2025 int found = 0;
2026## char *atype;
2027## int aid, listid, id;
2028 struct save_queue *sq, *sq_create();
2029
a6683dad 2030## range of m is imembers
822a6eba 2031 atype = argv[0];
2032 aid = *(int *)argv[1];
f0516942 2033 if (!strcmp(atype, "LIST") || !strcmp(atype, "USER") ||
2034 !strcmp(atype, "KERBEROS")) {
44bd6f44 2035 return(get_ace_internal(atype, aid, action, actarg));
822a6eba 2036 }
2037
2038 sq = sq_create();
2039 if (!strcmp(atype, "RLIST")) {
2040 sq_save_data(sq, aid);
2041 /* get all the list_id's of containing lists */
a6683dad 2042## range of m is imembers
2043## repeat retrieve (listid = m.list_id)
822a6eba 2044## where m.member_type = "LIST" and m.member_id = @id {
a6683dad 2045 sq_save_unique_data(sq, listid);
2046## }
822a6eba 2047 /* now process each one */
2048 while (sq_get_data(sq, &id)) {
44bd6f44 2049 if (get_ace_internal("LIST", id, action, actarg) == SMS_SUCCESS)
822a6eba 2050 found++;
2051 }
2052 }
2053
2054 if (!strcmp(atype, "RUSER")) {
822a6eba 2055## repeat retrieve (listid = m.list_id)
2056## where m.member_type = "USER" and m.member_id = @aid {
2057 sq_save_data(sq, listid);
2058## }
822a6eba 2059 /* now process each one */
2060 while (sq_get_data(sq, &id)) {
44bd6f44 2061 if (get_ace_internal("LIST", id, action, actarg) == SMS_SUCCESS)
822a6eba 2062 found++;
2063 }
44bd6f44 2064 if (get_ace_internal("USER", aid, action, actarg) == SMS_SUCCESS)
822a6eba 2065 found++;
2066 }
05cdd922 2067
f0516942 2068 if (!strcmp(atype, "RKERBERO")) {
f0516942 2069## repeat retrieve (listid = m.list_id)
2070## where m.member_type = "KERBEROS" and m.member_id = @aid {
2071 sq_save_data(sq, listid);
2072## }
f0516942 2073 /* now process each one */
2074 while (sq_get_data(sq, &id)) {
2075 if (get_ace_internal("LIST", id, action, actarg) == SMS_SUCCESS)
2076 found++;
2077 }
2078 if (get_ace_internal("KERBEROS", aid, action, actarg) == SMS_SUCCESS)
2079 found++;
2080 }
2081
822a6eba 2082 sq_destroy(sq);
02ccf7ad 2083 if (ingres_errno) return(sms_errcode);
822a6eba 2084 if (!found) return(SMS_NO_MATCH);
05cdd922 2085 return(SMS_SUCCESS);
2086##}
92a943d6 2087
822a6eba 2088
44bd6f44 2089/* This looks up a single list or user for ace use. atype must be "USER"
822a6eba 2090 * or "LIST", and aid is the ID of the corresponding object. This is used
44bd6f44 2091 * by get_ace_use above.
822a6eba 2092 */
2093
44bd6f44 2094##get_ace_internal(atype, aid, action, actarg)
822a6eba 2095## char *atype;
2096## int aid;
2097 int (*action)();
2098 int actarg;
2099##{
2100 char *rargv[2];
2101 int found = 0;
2102## char name[33];
2103
2104 rargv[1] = name;
2105 if (!strcmp(atype, "LIST")) {
2106 rargv[0] = "FILESYS";
2107## repeat retrieve (name = filesys.label)
2108## where filesys.owners = @aid {
2109 (*action)(2, rargv, actarg);
2110 found++;
2111## }
2112
2113 rargv[0] = "QUERY";
2114## repeat retrieve (name = capacls.capability)
2115## where capacls.list_id = @aid {
2116 (*action)(2, rargv, actarg);
2117 found++;
2118## }
2119 } else if (!strcmp(atype, "USER")) {
2120 rargv[0] = "FILESYS";
2121## repeat retrieve (name = filesys.label)
2122## where filesys.owner = @aid {
2123 (*action)(2, rargv, actarg);
2124 found++;
2125## }
2126 }
2127
2128 rargv[0] = "LIST";
2129## repeat retrieve (name = list.#name)
2130## where list.acl_type = @atype and list.acl_id = @aid {
2131 (*action)(2, rargv, actarg);
2132 found++;
2133## }
2134
2135 rargv[0] = "SERVICE";
2136## repeat retrieve (name = servers.#name)
2137## where servers.acl_type = @atype and servers.acl_id = @aid {
2138 (*action)(2, rargv, actarg);
2139 found++;
2140## }
2141
2142 rargv[0] = "HOSTACCESS";
2143## repeat retrieve (name = machine.#name)
2144## where machine.mach_id = hostaccess.mach_id and
2145## hostaccess.acl_type = @atype and hostaccess.acl_id = @aid {
2146 (*action)(2, rargv, actarg);
2147 found++;
2148## }
2149 rargv[0] = "ZEPHYR";
2150## repeat retrieve (name = zephyr.class)
2151## where zephyr.xmt_type = @atype and zephyr.xmt_id = @aid or
2152## zephyr.sub_type = @atype and zephyr.sub_id = @aid or
2153## zephyr.iws_type = @atype and zephyr.iws_id = @aid or
2154## zephyr.iui_type = @atype and zephyr.iui_id = @aid {
2155 (*action)(2, rargv, actarg);
2156 found++;
2157## }
2158
2159 if (!found) return(SMS_NO_MATCH);
2160 return(SMS_SUCCESS);
2161##}
2162
2163
2164/* get_lists_of_member - given a type and a name, return the name and flags
2165 * of all of the lists of the given member. The member_type is one of
2166 * "LIST", "USER", "STRING", "RLIST", "RUSER", or "RSTRING" in argv[0],
2167 * and argv[1] will contain the ID of the entity in question. The R*
2168 * types mean to recursively look at every containing list, not just
2169 * when the object in question is a direct member.
2170 */
2171
2172int get_lists_of_member(q, argv, cl, action, actarg)
92a943d6 2173 struct query *q;
2174 char *argv[];
822a6eba 2175 client *cl;
2176 int (*action)();
2177 int actarg;
92a943d6 2178##{
a6683dad 2179 int found = 0, direct = 1;
2180 char *rargv[6];
822a6eba 2181## char *atype;
2182## int aid, listid, id;
a6683dad 2183## char name[33], active[5], public[5], hidden[5], maillist[5], group[5];
822a6eba 2184
2185 atype = argv[0];
2186 aid = *(int *)argv[1];
822a6eba 2187 if (!strcmp(atype, "RLIST")) {
a6683dad 2188 atype = "LIST";
2189 direct = 0;
822a6eba 2190 }
822a6eba 2191 if (!strcmp(atype, "RUSER")) {
a6683dad 2192 atype = "USER";
2193 direct = 0;
822a6eba 2194 }
822a6eba 2195 if (!strcmp(atype, "RSTRING")) {
a6683dad 2196 atype = "STRING";
2197 direct = 0;
92a943d6 2198 }
a6683dad 2199 if (!strcmp(atype, "RKERBEROS")) {
2200 atype = "KERBEROS";
2201 direct = 0;
f0516942 2202 }
2203
822a6eba 2204 rargv[0] = name;
2205 rargv[1] = active;
2206 rargv[2] = public;
2207 rargv[3] = hidden;
2208 rargv[4] = maillist;
2209 rargv[5] = group;
a6683dad 2210 if (direct) {
2211## repeat retrieve (name = list.#name, active = text(list.#active),
2212## public = text(list.#public), hidden = text(list.#hidden),
2213## maillist = text(list.#maillist), group = text(list.#group))
2214## where list.list_id = m.list_id and m.direct = 1 and
2215## m.member_type = @atype and m.member_id = @aid {
2216 (*action)(6, rargv, actarg);
2217 found++;
2218## }
2219 } else {
2220## repeat retrieve (name = list.#name, active = text(list.#active),
822a6eba 2221## public = text(list.#public), hidden = text(list.#hidden),
2222## maillist = text(list.#maillist), group = text(list.#group))
2223## where list.list_id = m.list_id and
2224## m.member_type = @atype and m.member_id = @aid {
2225 (*action)(6, rargv, actarg);
2226 found++;
a6683dad 2227## }
2228 }
92a943d6 2229
02ccf7ad 2230 if (ingres_errno) return(sms_errcode);
822a6eba 2231 if (!found) return(SMS_NO_MATCH);
92a943d6 2232 return(SMS_SUCCESS);
2233##}
2234
822a6eba 2235
2236/* qualified_get_lists: passed "TRUE", "FALSE", or "DONTCARE" for each of
2237 * the five flags associated with each list. It will return the name of
2238 * each list that meets the quailifications. It does this by building a
2239 * where clause based on the arguments, then doing a retrieve.
2240 */
2241
2242static char *lflags[5] = { "active", "public", "hidden", "maillist", "group" };
2243
2244int qualified_get_lists(q, argv, cl, action, actarg)
2245 struct query *q;
2246 char *argv[];
2247 client *cl;
2248 int (*action)();
2249 int actarg;
2250{
2251 return(qualified_get(q, argv, action, actarg, "l.list_id != 0",
2252 "l", "name", lflags));
2253}
2254
2255
2256/** get_members_of_list - optimized query for retrieval of list members
c2408bd5 2257 **
2258 ** Inputs:
2259 ** argv[0] - list_id
2260 **
2261 ** Description:
2262 ** - retrieve USER members, then LIST members, then STRING members
c2408bd5 2263 **/
2264
822a6eba 2265get_members_of_list(q, argv, cl, action, actarg)
c2408bd5 2266 struct query *q;
2267 char *argv[];
822a6eba 2268 client *cl;
c2408bd5 2269 int (*action)();
2270 int actarg;
2271##{
2272## int list_id;
2273## char member_name[129];
2274 char *targv[2];
2275
2276 list_id = *(int *)argv[0];
2277 targv[0] = "USER";
2278 targv[1] = member_name;
2279
a6683dad 2280## range of m is imembers
c2408bd5 2281## repeat retrieve (member_name = users.login)
2282## where m.#list_id = @list_id and m.member_type = "USER"
a6683dad 2283## and m.member_id = users.users_id and m.direct = 1
92a943d6 2284## sort by #member_name
c2408bd5 2285## {
2286 (*action)(2, targv, actarg);
2287## }
02ccf7ad 2288 if (ingres_errno) return(sms_errcode);
c2408bd5 2289
2290 targv[0] = "LIST";
2291## repeat retrieve (member_name = list.name)
2292## where m.#list_id = @list_id and m.member_type = "LIST"
a6683dad 2293## and m.member_id = list.#list_id and m.direct = 1
92a943d6 2294## sort by #member_name
c2408bd5 2295## {
2296 (*action)(2, targv, actarg);
2297## }
02ccf7ad 2298 if (ingres_errno) return(sms_errcode);
c2408bd5 2299
2300 targv[0] = "STRING";
2301## repeat retrieve (member_name = strings.string)
2302## where m.#list_id = @list_id and m.member_type = "STRING"
a6683dad 2303## and m.member_id = strings.string_id and m.direct = 1
92a943d6 2304## sort by #member_name
f0516942 2305## {
2306 (*action)(2, targv, actarg);
2307## }
02ccf7ad 2308 if (ingres_errno) return(sms_errcode);
f0516942 2309
2310 targv[0] = "KERBEROS";
2311## repeat retrieve (member_name = strings.string)
2312## where m.#list_id = @list_id and m.member_type = "KERBEROS"
a6683dad 2313## and m.member_id = strings.string_id and m.direct = 1
f0516942 2314## sort by #member_name
c2408bd5 2315## {
2316 (*action)(2, targv, actarg);
2317## }
02ccf7ad 2318 if (ingres_errno) return(sms_errcode);
c2408bd5 2319
2320 return(SMS_SUCCESS);
2321##}
2322
92a943d6 2323
822a6eba 2324/* count_members_of_list: this is a simple query, but it cannot be done
2325 * through the dispatch table.
2326 */
2327
2328int count_members_of_list(q, argv, cl, action, actarg)
92a943d6 2329 struct query *q;
2330 char *argv[];
822a6eba 2331 client *cl;
92a943d6 2332 int (*action)();
2333 int actarg;
2334##{
822a6eba 2335## int list, ct = 0;
2336 char *rargv[1], countbuf[5];
2337
2338 list = *(int *)argv[0];
2339 rargv[0] = countbuf;
a6683dad 2340## repeat retrieve (ct = count(imembers.list_id
2341## where imembers.list_id = @list and
2342## imembers.direct = 1))
02ccf7ad 2343 if (ingres_errno) return(sms_errcode);
822a6eba 2344 sprintf(countbuf, "%d", ct);
2345 (*action)(1, rargv, actarg);
822a6eba 2346 return(SMS_SUCCESS);
2347##}
92a943d6 2348
92a943d6 2349
822a6eba 2350/* qualified_get_server: passed "TRUE", "FALSE", or "DONTCARE" for each of
2351 * the three flags associated with each service. It will return the name of
2352 * each service that meets the quailifications. It does this by building a
2353 * where clause based on the arguments, then doing a retrieve.
2354 */
92a943d6 2355
822a6eba 2356static char *sflags[3] = { "enable", "inprogress", "harderror" };
a6cb4d4c 2357
822a6eba 2358int qualified_get_server(q, argv, cl, action, actarg)
a6cb4d4c 2359 struct query *q;
2360 char *argv[];
822a6eba 2361 client *cl;
a6cb4d4c 2362 int (*action)();
2363 int actarg;
822a6eba 2364{
2365 return(qualified_get(q, argv, action, actarg, "s.name != \"\"",
2366 "s", "name", sflags));
2367}
a6cb4d4c 2368
a6cb4d4c 2369
822a6eba 2370/* generic qualified get routine, used by qualified_get_lists,
2371 * qualified_get_server, and qualified_get_serverhost.
2372 * Args:
2373 * start - a simple where clause, must not be empty
2374 * range - the name of the range variable
2375 * field - the field to return
2376 * flags - an array of strings, names of the flag variables
2377 */
c2408bd5 2378
822a6eba 2379int qualified_get(q, argv, action, actarg, start, range, field, flags)
c2408bd5 2380 struct query *q;
2381 char *argv[];
2382 int (*action)();
2383 int actarg;
822a6eba 2384 char *start;
2385 char *range;
2386 char *field;
2387 char *flags[];
c2408bd5 2388##{
822a6eba 2389## char name[33], qual[256], *rvar, *rtbl, *rfield;
2390 char *rargv[1], buf[32];
2391## int rowcount, i;
2392
2393 strcpy(qual, start);
2394 for (i = 0; i < q->argc; i++) {
2395 if (!strcmp(argv[i], "TRUE")) {
2396 sprintf(buf, " and %s.%s != 0", range, flags[i]);
2397 (void) strcat(qual, buf);
2398 } else if (!strcmp(argv[i], "FALSE")) {
2399 sprintf(buf, " and %s.%s = 0", range, flags[i]);
2400 (void) strcat(qual, buf);
2401 }
2402 }
2403
2404 rargv[0] = name;
2405 rvar = range;
2406 rtbl = q->rtable;
2407 rfield = field;
2408## range of rvar is rtbl
2409## retrieve (name = rvar.rfield) where qual {
2410 (*action)(1, rargv, actarg);
c2408bd5 2411## }
02ccf7ad 2412 if (ingres_errno) return(sms_errcode);
822a6eba 2413## inquire_equel(rowcount = "rowcount")
2414## repeat replace tblstats (retrieves = tblstats.retrieves + 1)
2415## where tblstats.#table = @rtbl
2416 if (rowcount == 0)
2417 return(SMS_NO_MATCH);
2418 return(SMS_SUCCESS);
2419##}
c2408bd5 2420
c2408bd5 2421
822a6eba 2422/* qualified_get_serverhost: passed "TRUE", "FALSE", or "DONTCARE" for each of
2423 * the five flags associated with each serverhost. It will return the name of
2424 * each service and host that meets the quailifications. It does this by
2425 * building a where clause based on the arguments, then doing a retrieve.
2426 */
c2408bd5 2427
822a6eba 2428static char *shflags[6] = { "service", "enable", "override", "success",
2429 "inprogress", "hosterror" };
a6cb4d4c 2430
822a6eba 2431int qualified_get_serverhost(q, argv, cl, action, actarg)
a6cb4d4c 2432 struct query *q;
2433 char *argv[];
822a6eba 2434 client *cl;
a6cb4d4c 2435 int (*action)();
2436 int actarg;
2437##{
822a6eba 2438## char sname[33], mname[33], qual[256];
2439 char *rargv[2], buf[32];
2440## int rowcount, i;
2441
44bd6f44 2442 sprintf(qual, "machine.mach_id = sh.mach_id and sh.service = uppercase(\"%s\")",
822a6eba 2443 argv[0]);
2444 for (i = 1; i < q->argc; i++) {
2445 if (!strcmp(argv[i], "TRUE")) {
2446 sprintf(buf, " and sh.%s != 0", shflags[i]);
2447 strcat(qual, buf);
2448 } else if (!strcmp(argv[i], "FALSE")) {
2449 sprintf(buf, " and sh.%s = 0", shflags[i]);
2450 strcat(qual, buf);
2451 }
2452 }
2453
2454 rargv[0] = sname;
2455 rargv[1] = mname;
2456## range of sh is serverhosts
2457## retrieve (sname = sh.service, mname = machine.name) where qual {
2458 (*action)(2, rargv, actarg);
a6cb4d4c 2459## }
02ccf7ad 2460 if (ingres_errno) return(sms_errcode);
822a6eba 2461## inquire_equel(rowcount = "rowcount")
2462## repeat replace tblstats (retrieves = tblstats.retrieves + 1)
2463## where tblstats.#table = "serverhosts"
2464 if (rowcount == 0)
2465 return(SMS_NO_MATCH);
2466 return(SMS_SUCCESS);
2467##}
a6cb4d4c 2468
a6cb4d4c 2469
822a6eba 2470/* register_user - change user's login name and allocate a pobox, group,
2471 * filesystem, and quota for them. The user's status must start out as 0,
2472 * and is left as 2. Arguments are: user's UID, new login name, and user's
2473 * type for filesystem allocation (SMS_FS_STUDENT, SMS_FS_FACULTY,
2474 * SMS_FS_STAFF, SMS_FS_MISC).
2475 */
2476
2477register_user(q, argv, cl)
2478 struct query *q;
2479 char **argv;
2480 client *cl;
2481##{
2482## char *login, dir[65], *entity, *directory, machname[33];
2483## int who, rowcount, mid, uid, users_id, flag, utype, nid, list_id, quota;
2484## int size, alloc, pid, m_id;
711660a5 2485 char buffer[256], *aargv[3];
822a6eba 2486 int maxsize;
2487
2488 entity = cl->entity;
711660a5 2489 who = cl->client_id;
822a6eba 2490
2491 uid = atoi(argv[0]);
2492 login = argv[1];
2493 utype = atoi(argv[2]);
2494
2495## range of u is users
2496## range of l is list
2497## range of sh is serverhosts
2498## range of n is nfsphys
2499## range of m is machine
2500
2501 /* find user */
2502## repeat retrieve (users_id = u.#users_id)
711660a5 2503## where u.#uid = @uid and (u.status = 0 or u.status = 5)
822a6eba 2504## inquire_equel(rowcount = "rowcount");
2505 if (rowcount == 0)
2506 return(SMS_NO_MATCH);
2507 if (rowcount > 1)
2508 return(SMS_NOT_UNIQUE);
2509
2510 /* check new login name */
711660a5 2511## repeat retrieve (flag = any(u.#login where u.#login = @login and
2512## u.#users_id != users_id))
e1795ce1 2513 if (ingres_errno) return(sms_errcode);
2514 if (flag) return(SMS_IN_USE);
4f16dc86 2515## repeat retrieve (flag = any(l.#name where l.#name = @login))
e1795ce1 2516 if (ingres_errno) return(sms_errcode);
2517 if (flag) return(SMS_IN_USE);
99a288b9 2518## repeat retrieve (flag = any(filesys.#label where filesys.#label = @login))
e1795ce1 2519 if (ingres_errno) return(sms_errcode);
2520 if (flag) return(SMS_IN_USE);
822a6eba 2521 com_err(whoami, 0, "new login name OK");
2522
2523 /* choose place for pobox, put in mid */
2524## repeat retrieve (mid = sh.mach_id, machname = m.name)
44bd6f44 2525## where sh.service = "POP" and m.mach_id = sh.mach_id and
2526## sh.value2 - sh.value1 = max(sh.value2-sh.value1 where sh.service="POP")
02ccf7ad 2527 if (ingres_errno) return(sms_errcode);
8ac9ee7a 2528## inquire_equel(rowcount = "rowcount");
822a6eba 2529 if (rowcount == 0)
44bd6f44 2530 return(SMS_NO_POBOX);
822a6eba 2531
2532 /* change login name, set pobox */
711660a5 2533 sprintf(buffer, "u.users_id = %d", users_id);
2534 incremental_before("users", buffer, 0);
822a6eba 2535## repeat replace u (#login = @login, status = 2, modtime = "now",
2536## modby = @who, modwith = @entity, potype="POP",
2537## pop_id = @mid, pmodtime="now", pmodby=@who,
2538## pmodwith=@entity)
2539## where u.#users_id = @users_id
8ac9ee7a 2540## inquire_equel(rowcount = "rowcount");
02ccf7ad 2541 if (ingres_errno) return(sms_errcode);
822a6eba 2542 if (rowcount != 1)
2543 return(SMS_INTERNAL);
2544 set_pop_usage(mid, 1);
2545 com_err(whoami, 0, "set login name to %s and pobox to %s", login,
711660a5 2546 strtrim(machname));
2547 incremental_after("users", buffer, 0);
822a6eba 2548
2549 /* create group list */
2550 if (set_next_object_id("gid", "list"))
44bd6f44 2551 return(SMS_NO_ID);
822a6eba 2552 if (set_next_object_id("list_id", "list"))
44bd6f44 2553 return(SMS_NO_ID);
822a6eba 2554## repeat retrieve (list_id = values.value) where values.name = "list_id"
02ccf7ad 2555 if (ingres_errno) return(sms_errcode);
8ac9ee7a 2556## inquire_equel(rowcount = "rowcount");
822a6eba 2557 if (rowcount != 1)
2558 return(SMS_INTERNAL);
711660a5 2559 incremental_clear_before();
822a6eba 2560## repeat append list (name = @login, #list_id = @list_id, active = 1,
2561## public = 0, hidden = 0, maillist = 0, group = 1,
2562## #gid = values.value, desc = "User Group",
2563## acl_type = "USER", acl_id = @users_id, modtime = "now",
2564## modby = @who, modwith = @entity)
2565## where values.name = "gid"
02ccf7ad 2566 if (ingres_errno) return(sms_errcode);
8ac9ee7a 2567## inquire_equel(rowcount = "rowcount");
44bd6f44 2568 if (rowcount != 1)
2569 return(SMS_INTERNAL);
711660a5 2570 sprintf(buffer, "l.list_id = %d", list_id);
2571 incremental_after("list", buffer, 0);
2572 aargv[0] = (char *) list_id;
2573 aargv[1] = "USER";
2574 aargv[2] = (char *) users_id;
2575 incremental_clear_before();
a6683dad 2576## repeat append imembers (#list_id = @list_id, member_type = "USER",
2577## member_id = @users_id, ref_count = 1, direct = 1)
02ccf7ad 2578 if (ingres_errno) return(sms_errcode);
8ac9ee7a 2579## inquire_equel(rowcount = "rowcount");
822a6eba 2580 if (rowcount != 1)
2581 return(SMS_INTERNAL);
60610bc7 2582 incremental_after("members", 0, aargv);
822a6eba 2583 com_err(whoami, 0, "group list created");
2584
2585 /* decide where to put filesystem */
2586 maxsize = 0;
2587 directory = NULL;
2588## repeat retrieve (mid = n.mach_id, dir = trim(n.#dir), nid = n.nfsphys_id,
2589## flag = n.status, size = n.#size, alloc = n.allocated) {
2590 if ((flag & utype) && (size != 0) && (size - alloc > maxsize)) {
2591 maxsize = size - alloc;
2592 if (directory)
2593 free(directory);
2594 directory = strsave(dir);
2595 pid = nid;
2596 m_id = mid;
2597 }
a6cb4d4c 2598## }
02ccf7ad 2599 if (ingres_errno) return(sms_errcode);
822a6eba 2600 if (maxsize == 0)
44bd6f44 2601 return(SMS_NO_FILESYS);
822a6eba 2602
2603 /* create filesystem */
2604 if (set_next_object_id("filsys_id", "filesys"))
44bd6f44 2605 return(SMS_NO_ID);
711660a5 2606 incremental_clear_before();
822a6eba 2607## repeat append filesys (filsys_id = values.value, phys_id = @pid,
2608## label = @login, type = "NFS", mach_id = @m_id,
4f16dc86 2609## name = @directory + "/" + @login,
2610## mount = "/mit/" + @login,
822a6eba 2611## access = "w", comments = "User Locker",
2612## owner = @users_id, owners = @list_id, createflg = 1,
2613## lockertype = "HOMEDIR", modtime = "now",
2614## modby = @who, modwith = @entity)
2615## where values.name = "filsys_id"
02ccf7ad 2616 if (ingres_errno) return(sms_errcode);
8ac9ee7a 2617## inquire_equel(rowcount = "rowcount");
822a6eba 2618 if (rowcount != 1)
2619 return(SMS_INTERNAL);
711660a5 2620 incremental_after("filesys",
2621 "fs.filsys_id = values.value and values.name = \"filsys_id\"",
2622 0);
822a6eba 2623 com_err(whoami, 0, "filesys created on mach %d in %s/%s", m_id,
4f16dc86 2624 directory, login);
822a6eba 2625
2626 /* set quota */
2627## repeat retrieve (quota = values.value) where values.name = "def_quota"
02ccf7ad 2628 if (ingres_errno) return(sms_errcode);
8ac9ee7a 2629## inquire_equel(rowcount = "rowcount");
822a6eba 2630 if (rowcount != 1)
44bd6f44 2631 return(SMS_NO_QUOTA);
711660a5 2632 incremental_clear_before();
822a6eba 2633## repeat append nfsquota (#users_id = @users_id, filsys_id = values.value,
e7fa3293 2634## #quota = @quota, phys_id = @pid, modtime = "now",
2635## modby = @who, modwith = @entity)
822a6eba 2636## where values.name = "filsys_id"
02ccf7ad 2637 if (ingres_errno) return(sms_errcode);
8ac9ee7a 2638## inquire_equel(rowcount = "rowcount");
822a6eba 2639 if (rowcount != 1)
2640 return(SMS_INTERNAL);
2641## repeat replace nfsphys (allocated = nfsphys.allocated + @quota)
2642## where nfsphys.nfsphys_id = filesys.#phys_id and
2643## filesys.filsys_id = values.value and values.name = "filsys_id"
02ccf7ad 2644 if (ingres_errno) return(sms_errcode);
8ac9ee7a 2645## inquire_equel(rowcount = "rowcount");
822a6eba 2646 if (rowcount != 1)
2647 return(SMS_INTERNAL);
711660a5 2648 aargv[0] = login;
2649 aargv[1] = login;
2650 sprintf(buffer, "nq.users_id = %d and nq.filsys_id = values.value and values.name = \"filsys_id\"", users_id);
60610bc7 2651 incremental_after("nfsquota", buffer, aargv);
822a6eba 2652 com_err(whoami, 0, "quota of %d assigned", quota);
02ccf7ad 2653 if (ingres_errno) return(sms_errcode);
822a6eba 2654
4f16dc86 2655## repeat replace tblstats (updates = tblstats.updates + 1, modtime = "now")
2656## where tblstats.table = "users"
2657## repeat replace tblstats (appends = tblstats.appends + 1, modtime = "now")
2658## where tblstats.table = "list" or tblstats.table = "filesys" or
2659## tblstats.table = "nfsquota"
02ccf7ad 2660 if (ingres_errno) return(sms_errcode);
822a6eba 2661 return(SMS_SUCCESS);
2662##}
2663
2664
2665
2666/** set_pop_usage - incr/decr usage count for pop server in serverhosts talbe
2667 **
2668 ** Inputs:
2669 ** id of machine
2670 ** delta (will be +/- 1)
2671 **
2672 ** Description:
2673 ** - incr/decr value field in serverhosts table for pop/mach_id
2674 **
2675 **/
2676
2677static int set_pop_usage(id, count)
2678int id;
2679int count;
2680##{
2681## int mach_id = id;
2682## int n = count;
2683
2684## range of sh is serverhosts
2685## repeat replace sh (value1 = sh.value1 + @n)
44bd6f44 2686## where sh.service = "POP" and sh.#mach_id = @mach_id
a6cb4d4c 2687
02ccf7ad 2688 if (ingres_errno) return(sms_errcode);
a6cb4d4c 2689 return(SMS_SUCCESS);
2690##}
822a6eba 2691
2692
c2408bd5 2693\f
05cdd922 2694/* Validation Routines */
2695
2696validate_row(q, argv, v)
2697 register struct query *q;
2698 char *argv[];
2699 register struct validate *v;
2700##{
2701## char *rvar;
2702## char *table;
2703## char *name;
2704## char qual[128];
2705## int rowcount;
2706
2707 /* build where clause */
2708 build_qual(v->qual, v->argc, argv, qual);
2709
2710 /* setup ingres variables */
2711 rvar = q->rvar;
2712 table = q->rtable;
2713 name = v->field;
2714
6388c51a 2715 if (log_flags & LOG_VALID)
b4182127 2716 /* tell the logfile what we're doing */
2717 com_err(whoami, 0, "validating row: %s", qual);
2718
05cdd922 2719 /* look for the record */
2720## range of rvar is table
2721## retrieve (rowcount = count(rvar.name where qual))
e1795ce1 2722 if (ingres_errno) return(sms_errcode);
05cdd922 2723 if (rowcount == 0) return(SMS_NO_MATCH);
2724 if (rowcount > 1) return(SMS_NOT_UNIQUE);
2725 return(SMS_EXISTS);
2726##}
2727
2728validate_fields(q, argv, vo, n)
2729 struct query *q;
2730 register char *argv[];
2731 register struct valobj *vo;
2732 register int n;
2733{
2734 register int status;
05cdd922 2735
2736 while (--n >= 0) {
2737 switch (vo->type) {
2738 case V_NAME:
6388c51a 2739 if (log_flags & LOG_VALID)
b4182127 2740 com_err(whoami, 0, "validating %s in %s: %s",
05cdd922 2741 vo->namefield, vo->table, argv[vo->index]);
05cdd922 2742 status = validate_name(argv, vo);
2743 break;
2744
2745 case V_ID:
6388c51a 2746 if (log_flags & LOG_VALID)
b4182127 2747 com_err(whoami, 0, "validating %s in %s: %s",
05cdd922 2748 vo->idfield, vo->table, argv[vo->index]);
05cdd922 2749 status = validate_id(argv, vo);
2750 break;
2751
92a943d6 2752 case V_DATE:
6388c51a 2753 if (log_flags & LOG_VALID)
92a943d6 2754 com_err(whoami, 0, "validating date: %s", argv[vo->index]);
2755 status = validate_date(argv, vo);
2756 break;
2757
05cdd922 2758 case V_TYPE:
6388c51a 2759 if (log_flags & LOG_VALID)
b4182127 2760 com_err(whoami, 0, "validating %s type: %s",
05cdd922 2761 vo->table, argv[vo->index]);
05cdd922 2762 status = validate_type(argv, vo);
2763 break;
2764
2765 case V_TYPEDATA:
6388c51a 2766 if (log_flags & LOG_VALID)
92a943d6 2767 com_err(whoami, 0, "validating typed data (%s): %s",
2768 argv[vo->index - 1], argv[vo->index]);
05cdd922 2769 status = validate_typedata(q, argv, vo);
2770 break;
2771
822a6eba 2772 case V_RENAME:
6388c51a 2773 if (log_flags & LOG_VALID)
822a6eba 2774 com_err(whoami, 0, "validating rename %s in %s",
2775 argv[vo->index], vo->table);
2776 status = validate_rename(argv, vo);
2777 break;
2778
2779 case V_CHAR:
6388c51a 2780 if (log_flags & LOG_VALID)
822a6eba 2781 com_err(whoami, 0, "validating chars: %s", argv[vo->index]);
2782 status = validate_chars(argv[vo->index]);
05cdd922 2783 break;
2784
92a943d6 2785 case V_SORT:
2786 status = SMS_EXISTS;
2787 break;
2788
e1795ce1 2789 case V_LOCK:
2790 status = lock_table(vo);
2791 break;
05cdd922 2792 }
2793
2794 if (status != SMS_EXISTS) return(status);
2795 vo++;
2796 }
2797
02ccf7ad 2798 if (ingres_errno) return(sms_errcode);
05cdd922 2799 return(SMS_SUCCESS);
2800}
2801
822a6eba 2802
2803/* validate_chars: verify that there are no illegal characters in
2804 * the string. Legal characters are printing chars other than
331b982e 2805 * ", *, ?, \, [ and ].
822a6eba 2806 */
2807static int illegalchars[] = {
2808 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* ^@ - ^O */
2809 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* ^P - ^_ */
2810 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, /* SPACE - / */
2811 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, /* 0 - ? */
2812 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* @ - O */
331b982e 2813 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, /* P - _ */
822a6eba 2814 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* ` - o */
2815 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, /* p - ^? */
2816 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2817 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2818 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2819 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2820 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2821 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2822 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2823 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2824};
2825
2826validate_chars(s)
2827register char *s;
2828{
2829 while (*s)
2830 if (illegalchars[*s++])
2831 return(SMS_BAD_CHAR);
2832 return(SMS_EXISTS);
2833}
2834
2835
05cdd922 2836validate_id(argv, vo)
2837 char *argv[];
2838 register struct valobj *vo;
2839##{
2840## char *name;
2841## char *table;
2842## char *namefield;
2843## char *idfield;
2844## int id;
2845## int rowcount;
122ec372 2846 register char *c;
05cdd922 2847
2848 name = argv[vo->index];
2849 table = vo->table;
122ec372 2850 /* minor kludge to upcasify machine names */
822a6eba 2851 if (!strcmp(table, "machine"))
122ec372 2852 for (c = name; *c; c++) if (islower(*c)) *c = toupper(*c);
05cdd922 2853 namefield = vo->namefield;
2854 idfield = vo->idfield;
822a6eba 2855 if (!strcmp(namefield, "uid")) {
9119288e 2856## retrieve (id = table.idfield) where table.namefield = int4(name)
e1795ce1 2857 if (ingres_errno) return(sms_errcode);
9119288e 2858## inquire_equel (rowcount = "rowcount")
2859 } else {
2860## retrieve (id = table.idfield) where table.namefield = name
e1795ce1 2861 if (ingres_errno) return(sms_errcode);
9119288e 2862## inquire_equel (rowcount = "rowcount")
2863 }
05cdd922 2864 if (rowcount != 1) return(vo->error);
2865 *(int *)argv[vo->index] = id;
2866 return(SMS_EXISTS);
2867##}
2868
2869validate_name(argv, vo)
2870 char *argv[];
2871 register struct valobj *vo;
2872##{
2873## char *name;
2874## char *table;
2875## char *namefield;
2876## int rowcount;
44bd6f44 2877 register char *c;
05cdd922 2878
2879 name = argv[vo->index];
2880 table = vo->table;
2881 namefield = vo->namefield;
44bd6f44 2882 if (!strcmp(table, "servers") && !strcmp(namefield, "name")) {
2883 for (c = name; *c; c++)
2884 if (islower(*c))
2885 *c = toupper(*c);
2886 }
05cdd922 2887## retrieve (rowcount = countu(table.namefield
2888## where table.namefield = name))
e1795ce1 2889 if (ingres_errno) return(sms_errcode);
05cdd922 2890 return ((rowcount == 1) ? SMS_EXISTS : vo->error);
2891##}
2892
92a943d6 2893validate_date(argv, vo)
2894 char *argv[];
2895 struct valobj *vo;
2896##{
2897## char *idate;
2898## double dd;
2899## int errorno;
2900
2901 idate = argv[vo->index];
2902
2903## retrieve (dd = interval("years", date(idate) - date("today")))
2904## inquire_equel (errorno = "errorno")
2905 if (errorno != 0 || dd > 5.0) return(SMS_DATE);
44bd6f44 2906 return(SMS_EXISTS);
92a943d6 2907##}
2908
822a6eba 2909
2910validate_rename(argv, vo)
2911char *argv[];
2912struct valobj *vo;
2913##{
2914## char *name, *table, *namefield, *idfield;
2915## int id;
2916 register char *c;
2917
2918 c = name = argv[vo->index];
2919 while (*c)
2920 if (illegalchars[*c++])
2921 return(SMS_BAD_CHAR);
2922 table = vo->table;
2923 /* minor kludge to upcasify machine names */
2924 if (!strcmp(table, "machine"))
2925 for (c = name; *c; c++) if (islower(*c)) *c = toupper(*c);
2926 namefield = vo->namefield;
2927 idfield = vo->idfield;
2928 id = -1;
2929 if (idfield == 0) {
2930 if (!strcmp(argv[vo->index], argv[vo->index - 1]))
2931 return(SMS_EXISTS);
2932## retrieve (id = any(table.namefield where table.namefield = name))
e1795ce1 2933 if (ingres_errno) return(sms_errcode);
822a6eba 2934 if (id)
2935 return(vo->error);
2936 else
2937 return(SMS_EXISTS);
2938 }
2939## retrieve (id = table.idfield) where table.namefield = name
e1795ce1 2940 if (ingres_errno) return(sms_errcode);
822a6eba 2941 if (id == -1 || id == *(int *)argv[vo->index - 1])
2942 return(SMS_EXISTS);
2943 else
2944 return(vo->error);
2945##}
2946
2947
05cdd922 2948validate_type(argv, vo)
2949 char *argv[];
2950 register struct valobj *vo;
2951##{
2952## char *typename;
2953## char *value;
822a6eba 2954## int exists;
05cdd922 2955 register char *c;
2956
2957 typename = vo->table;
822a6eba 2958 c = value = argv[vo->index];
2959 while (*c)
2960 if (illegalchars[*c++])
2961 return(SMS_BAD_CHAR);
05cdd922 2962
2963 /* uppercase type fields */
2964 for (c = value; *c; c++) if (islower(*c)) *c = toupper(*c);
2965
2966## range of a is alias
822a6eba 2967## repeat retrieve (exists = any(a.trans where a.name = @typename and
05cdd922 2968## a.type = "TYPE" and
2969## a.trans = @value))
e1795ce1 2970 if (ingres_errno) return(sms_errcode);
822a6eba 2971 return (exists ? SMS_EXISTS : vo->error);
05cdd922 2972##}
2973
2974/* validate member or type-specific data field */
2975
2976validate_typedata(q, argv, vo)
2977 register struct query *q;
2978 register char *argv[];
2979 register struct valobj *vo;
2980##{
2981## char *name;
2982## char *field_type;
822a6eba 2983## char data_type[129];
05cdd922 2984## int id;
05cdd922 2985## int rowcount;
822a6eba 2986 char *index();
a6cb4d4c 2987 register char *c;
05cdd922 2988
2989 /* get named object */
2990 name = argv[vo->index];
2991
2992 /* get field type string (known to be at index-1) */
2993 field_type = argv[vo->index-1];
2994
2995 /* get corresponding data type associated with field type name */
2996## repeat retrieve (data_type = alias.trans)
2997## where alias.#name = @field_type and alias.type = "TYPEDATA"
e1795ce1 2998 if (ingres_errno) return(sms_errcode);
05cdd922 2999## inquire_equel (rowcount = "rowcount")
3000 if (rowcount != 1) return(SMS_TYPE);
3001
3002 /* now retrieve the record id corresponding to the named object */
822a6eba 3003 if (index(data_type, ' '))
3004 *index(data_type, ' ') = 0;
05cdd922 3005 if (!strcmp(data_type, "user")) {
3006 /* USER */
3007## repeat retrieve (id = users.users_id) where users.login = @name
3008## inquire_equel (rowcount = "rowcount")
3009 if (rowcount != 1) return(SMS_USER);
3010
3011 } else if (!strcmp(data_type, "list")) {
3012 /* LIST */
3013## repeat retrieve (id = list.list_id) where list.#name = @name
3014## inquire_equel (rowcount = "rowcount")
822a6eba 3015 if (rowcount != 1) {
3016 /* if idfield is non-zero, then if argv[0] matches the string
3017 * that we're trying to resolve, we should get the value of
3018 * values.[idfield] for the id.
3019 */
3020 if (vo->idfield && !strcmp(argv[0], argv[vo->index])) {
4f16dc86 3021 set_next_object_id(q->validate->object_id, q->rtable);
822a6eba 3022 name = vo->idfield;
4f16dc86 3023## repeat retrieve (id = values.value) where values.#name = @name
822a6eba 3024## inquire_equel(rowcount = "rowcount")
3025 if (rowcount != 1) return(SMS_LIST);
3026 } else
3027 return(SMS_LIST);
3028 }
05cdd922 3029 } else if (!strcmp(data_type, "machine")) {
3030 /* MACHINE */
a6cb4d4c 3031 for (c = name; *c; c++) if (islower(*c)) *c = toupper(*c);
05cdd922 3032## repeat retrieve (id = machine.mach_id) where machine.#name = @name
3033## inquire_equel (rowcount = "rowcount")
3034 if (rowcount != 1) return(SMS_MACHINE);
3035
3036 } else if (!strcmp(data_type, "string")) {
3037 /* STRING */
3038## range of s is strings
822a6eba 3039## repeat retrieve (id = s.string_id) where s.string = @name
05cdd922 3040## inquire_equel (rowcount = "rowcount")
3041 if (rowcount == 0) {
3042 if (q->type != APPEND) return(SMS_STRING);
3043## range of v is values
3044## retrieve (id = v.value) where v.#name = "strings_id"
3045 id++;
3046## replace v (value = id) where v.#name = "strings_id"
822a6eba 3047## append to strings (string_id = id, string = name)
05cdd922 3048 }
822a6eba 3049 } else if (!strcmp(data_type, "none")) {
3050 id = 0;
05cdd922 3051 } else {
3052 return(SMS_TYPE);
3053 }
3054
3055 /* now set value in argv */
3056 *(int *)argv[vo->index] = id;
3057
3058 return (SMS_EXISTS);
3059##}
3060
05cdd922 3061
e1795ce1 3062/* Lock the table named by the validation object */
3063
3064lock_table(vo)
3065struct valobj *vo;
3066##{
3067## char *table, *idfield;
3068## int rowcount;
3069
3070 table = vo->table;
3071 idfield = vo->idfield;
3072## replace table (modtime = "now") where table.idfield = 0
3073 if (ingres_errno) return(sms_errcode);
3074## inquire_equel (rowcount = "rowcount")
3075 if (rowcount != 1)
3076 return(vo->error);
3077 else
3078 return(SMS_EXISTS);
3079##}
3080
3081
822a6eba 3082/* Check the database at startup time. For now this just resets the
3083 * inprogress flags that the DCM uses.
3084 */
05cdd922 3085
822a6eba 3086sanity_check_database()
3087##{
05cdd922 3088##}
This page took 0.558076 seconds and 5 git commands to generate.