]> andersk Git - moira.git/blame - server/qsupport.qc
integrate name<->id cache; remove need for some range statements
[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;
49189928 693## int fid, total;
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;
49189928 700 fid = *(int *)argv[0];
a6cb4d4c 701
e7fa3293 702 if (!strcmp(type, "NFS")) {
703 status = check_nfs(mach_id, name, access);
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);
49189928 707 } else if (!strcmp(type, "AFS")) {
708 total = 0;
709## retrieve (total = sum(nfsquota.quota where nfsquota.filsys_id = fid))
710 if (ingres_errno) return(sms_errcode);
711 if (total != 0) {
712## delete nfsquota where nfsquota.filsys_id = fid
713 if (ingres_errno) return(sms_errcode);
714## append nfsquota (quota = total, filsys_id = fid,
715## phys_id = 0, users_id = 0)
716 if (ingres_errno) return(sms_errcode);
717 }
718 } else {
719## replace nfsquota (phys_id = 0) where nfsquota.filsys_id = fid
720 if (ingres_errno) return(sms_errcode);
721 }
722 return(SMS_SUCCESS);
e7fa3293 723##}
30967516 724
a6cb4d4c 725
822a6eba 726/* Find the NFS physical partition that the named directory is on.
727 * This is done by comparing the dir against the mount point of the
728 * partition. To make sure we get the correct match when there is
729 * more than one, we sort the query in reverse order by dir name.
730 */
a6cb4d4c 731
822a6eba 732##check_nfs(mach_id, name, access)
a6cb4d4c 733## int mach_id;
822a6eba 734 char *name;
735 char *access;
736##{
a30e1c62 737## char dir[81];
822a6eba 738 char caccess;
739 register int status;
740 register char *cp1;
741 register char *cp2;
a6cb4d4c 742
822a6eba 743 caccess = (isupper(*access)) ? tolower(*access) : *access;
49189928 744 if (caccess != 'r' && caccess != 'w' && caccess != 'n')
745 return(SMS_FILESYS_ACCESS);
a6cb4d4c 746
822a6eba 747 status = SMS_NFS;
748## range of np is nfsphys
749## repeat retrieve (var_phys_id = np.#nfsphys_id, dir = trim(np.#dir))
750## where np.#mach_id = @mach_id sort by #dir:d {
751 cp1 = name;
752 cp2 = dir;
753 while (*cp2) {
754 if (*cp1++ != *cp2) break;
755 cp2++;
756 }
757 if (*cp2 == 0) {
758 status = SMS_SUCCESS;
a6cb4d4c 759## endretrieve
760 }
761## }
02ccf7ad 762 if (ingres_errno)
763 return(sms_errcode);
822a6eba 764 return(status);
30967516 765##}
a6cb4d4c 766
92a943d6 767
f49f997e 768/* setup_dfil: free any quota records and fsgroup info associated with
769 * a filesystem when it is deleted. Also adjust the allocation numbers.
822a6eba 770 */
92a943d6 771
822a6eba 772setup_dfil(q, argv, cl)
773 struct query *q;
774 char **argv;
775 client *cl;
776##{
777## int id;
92a943d6 778
822a6eba 779 id = *(int *)argv[0];
780## range of q is nfsquota
44bd6f44 781## range of n is nfsphys
782## repeat replace n (allocated=n.allocated-sum(q.quota where q.filsys_id=@id))
cc588c08 783## where n.nfsphys_id = filesys.phys_id and filesys.filsys_id = @id
92a943d6 784
822a6eba 785## repeat delete q where q.filsys_id = @id
f49f997e 786## repeat delete fsgroup where fsgroup.filsys_id = @id
787## repeat delete fsgroup where fsgroup.group_id = @id
02ccf7ad 788 if (ingres_errno) return(sms_errcode);
92a943d6 789 return(SMS_SUCCESS);
790##}
30967516 791
822a6eba 792
793/* setup_dnfp: check to see that the nfs physical partition does not have
794 * any filesystems assigned to it before allowing it to be deleted.
795 */
796
797setup_dnfp(q, argv, cl)
798 struct query *q;
799 char **argv;
92a943d6 800 client *cl;
92a943d6 801##{
822a6eba 802## int id, exists;
92a943d6 803
822a6eba 804 id = *(int *)argv[0];
805## repeat retrieve (exists = any(filesys.label where filesys.phys_id = @id))
806 if (exists)
807 return(SMS_IN_USE);
02ccf7ad 808 if (ingres_errno)
809 return(sms_errcode);
92a943d6 810 return(SMS_SUCCESS);
811##}
4b890cc4 812
4b890cc4 813
822a6eba 814/* setup_dnfq: Remove allocation from nfsphys before deleting quota.
815 * argv[0] = filsys_id
816 * argv[1] = users_id
817 */
818
819setup_dnfq(q, argv, cl)
820 struct query *q;
821 char **argv;
822 client *cl;
823##{
824## int quota, fs, user;
825
826 fs = *(int *)argv[0];
827 user = *(int *)argv[1];
828
829## range of q is nfsquota
830## repeat retrieve (quota = q.#quota) where q.users_id = @user and
831## q.filsys_id = @fs
832## repeat replace nfsphys (allocated = nfsphys.allocated - @quota)
833## where nfsphys.nfsphys_id = filesys.#phys_id and filesys.filsys_id = @fs
02ccf7ad 834 if (ingres_errno) return(sms_errcode);
822a6eba 835 return(SMS_SUCCESS);
836##}
837
838
67d7b959 839/* setup_sshi: don't exclusive lock the machine table during
840 * set_server_host_internal.
841 */
842
843setup_sshi(q, argv, cl)
844 struct query *q;
845 char **argv;
846 client *cl;
847##{
848## set lockmode session where readlock = system
849##}
850
851
711660a5 852/* setup add_kerberos_user_mapping: add the string to the string
853 * table if necessary.
854 */
855
856setup_akum(q, argv, cl)
857struct query *q;
858char **argv;
859client *cl;
860##{
861## int id, rowcount;
862## char *name;
863
864 name = argv[1];
cc588c08 865 if (name_to_id(name, "STRING", &id) != SMS_SUCCESS) {
711660a5 866 if (q->type != APPEND) return(SMS_STRING);
867## range of v is values
868## retrieve (id = v.value) where v.#name = "strings_id"
869 id++;
870## replace v (value = id) where v.#name = "strings_id"
871## append to strings (string_id = id, string = name)
cc588c08 872 cache_entry(name, "STRING", id);
711660a5 873 }
02ccf7ad 874 if (ingres_errno) return(sms_errcode);
711660a5 875 *(int *)argv[1] = id;
02ccf7ad 876 return(SMS_SUCCESS);
711660a5 877##}
878
879
822a6eba 880\f
881/* FOLLOWUP ROUTINES */
882
883/* generic set_modtime routine. This takes the table name from the query,
884 * and will update the modtime, modby, and modwho fields in the entry in
885 * the table whose name field matches argv[0].
886 */
887
888set_modtime(q, argv, cl)
4b890cc4 889 struct query *q;
890 char *argv[];
822a6eba 891 client *cl;
4b890cc4 892##{
822a6eba 893## char *name, *entity, *table;
894## int who;
4b890cc4 895
822a6eba 896 entity = cl->entity;
711660a5 897 who = cl->client_id;
822a6eba 898 table = q->rtable;
899 name = argv[0];
4b890cc4 900
822a6eba 901## replace table (modtime = "now", modby = who, modwith = entity)
902## where table.#name = name
4b890cc4 903 return(SMS_SUCCESS);
904##}
905
822a6eba 906/* generic set_modtime_by_id routine. This takes the table name from
907 * the query, and the id name from the validate record,
908 * and will update the modtime, modby, and modwho fields in the entry in
909 * the table whose id matches argv[0].
910 */
911
912set_modtime_by_id(q, argv, cl)
4b890cc4 913 struct query *q;
822a6eba 914 char **argv;
915 client *cl;
4b890cc4 916##{
822a6eba 917## char *entity, *table, *id_name;
918## int who, id;
919
920 entity = cl->entity;
711660a5 921 who = cl->client_id;
822a6eba 922 table = q->rtable;
923 id_name = q->validate->object_id;
4b890cc4 924
822a6eba 925 id = *(int *)argv[0];
926## replace table (modtime = "now", modby = who, modwith = entity)
927## where table.id_name = id
4b890cc4 928 return(SMS_SUCCESS);
929##}
930
822a6eba 931
932/* Sets the finger modtime on a user record. The users_id will be in argv[0].
933 */
934
935set_finger_modtime(q, argv, cl)
4b890cc4 936 struct query *q;
937 char *argv[];
822a6eba 938 client *cl;
4b890cc4 939##{
822a6eba 940## int users_id, who;
941## char *entity;
942
943 entity = cl->entity;
711660a5 944 who = cl->client_id;
822a6eba 945 users_id = *(int *)argv[0];
4b890cc4 946
822a6eba 947## repeat replace u (fmodtime = "now", fmodby = @who, fmodwith = @entity)
948## where u.#users_id = @users_id
4b890cc4 949 return(SMS_SUCCESS);
950##}
05cdd922 951
822a6eba 952
953/* Sets the pobox modtime on a user record. The users_id will be in argv[0].
954 */
955
956set_pobox_modtime(q, argv, cl)
05cdd922 957 struct query *q;
822a6eba 958 char **argv;
959 client *cl;
05cdd922 960##{
822a6eba 961## int users_id, who;
962## char *entity;
05cdd922 963
822a6eba 964 entity = cl->entity;
711660a5 965 who = cl->client_id;
822a6eba 966 users_id = *(int *)argv[0];
05cdd922 967
822a6eba 968## repeat replace users (pmodtime = "now", pmodby = @who, pmodwith = @entity)
969## where users.#users_id = @users_id
970 return(SMS_SUCCESS);
971##}
05cdd922 972
05cdd922 973
3c7c4a07 974/* Like set_modtime, but uppercases the name first.
822a6eba 975 */
976
3c7c4a07 977set_uppercase_modtime(q, argv, cl)
822a6eba 978 struct query *q;
979 char **argv;
980 client *cl;
981##{
3c7c4a07 982## char *name, *entity, *table;
822a6eba 983## int who;
984
985 entity = cl->entity;
711660a5 986 who = cl->client_id;
3c7c4a07 987 table = q->rtable;
988 name = argv[0];
05cdd922 989
3c7c4a07 990## replace table (modtime = "now", modby = who, modwith = entity)
991## where table.#name = uppercase(name)
05cdd922 992 return(SMS_SUCCESS);
993##}
05cdd922 994
822a6eba 995
996/* Sets the modtime on the machine whose mach_id is in argv[0]. This routine
997 * is necessary for add_machine_to_cluster becuase the table that query
998 * operates on is "mcm", not "machine".
999 */
1000
1001set_mach_modtime_by_id(q, argv, cl)
05cdd922 1002 struct query *q;
05cdd922 1003 char **argv;
822a6eba 1004 client *cl;
1005##{
1006## char *entity;
1007## int who, id;
05cdd922 1008
822a6eba 1009 entity = cl->entity;
711660a5 1010 who = cl->client_id;
05cdd922 1011
822a6eba 1012 id = *(int *)argv[0];
cc588c08 1013## repeat replace machine (modtime = "now", modby = @who, modwith = @entity)
1014## where machine.mach_id = @id
822a6eba 1015 return(SMS_SUCCESS);
1016##}
05cdd922 1017
05cdd922 1018
822a6eba 1019/* Sets the modtime on the cluster whose mach_id is in argv[0]. This routine
1020 * is necessary for add_cluster_data and delete_cluster_data becuase the
1021 * table that query operates on is "svc", not "cluster".
1022 */
1023
1024set_cluster_modtime_by_id(q, argv, cl)
1025 struct query *q;
1026 char **argv;
1027 client *cl;
1028##{
1029## char *entity;
1030## int who, id;
1031
1032 entity = cl->entity;
711660a5 1033 who = cl->client_id;
822a6eba 1034
1035 id = *(int *)argv[0];
cc588c08 1036## repeat replace cluster (modtime = "now", modby = @who, modwith = @entity)
1037## where cluster.clu_id = @id
05cdd922 1038 return(SMS_SUCCESS);
1039##}
1040
822a6eba 1041
1042/* sets the modtime on the serverhost where the service name is in argv[0]
1043 * and the mach_id is in argv[1].
1044 */
1045
1046set_serverhost_modtime(q, argv, cl)
92a943d6 1047 struct query *q;
822a6eba 1048 char **argv;
1049 client *cl;
92a943d6 1050##{
822a6eba 1051## char *entity, *serv;
1052## int who, id;
1053
1054 entity = cl->entity;
711660a5 1055 who = cl->client_id;
822a6eba 1056
1057 serv = argv[0];
1058 id = *(int *)argv[1];
1059## repeat replace sh (modtime = "now", modby = @who, modwith = @entity)
44bd6f44 1060## where sh.service = uppercase(@serv) and sh.mach_id = @id
822a6eba 1061 return(SMS_SUCCESS);
1062##}
1063
1064
1065/* sets the modtime on the nfsphys where the mach_id is in argv[0] and the
1066 * directory name is in argv[1].
1067 */
1068
1069set_nfsphys_modtime(q, argv, cl)
1070 struct query *q;
92a943d6 1071 char **argv;
822a6eba 1072 client *cl;
1073##{
1074## char *entity, *dir;
1075## int who, id;
92a943d6 1076
822a6eba 1077 entity = cl->entity;
711660a5 1078 who = cl->client_id;
92a943d6 1079
822a6eba 1080 id = *(int *)argv[0];
1081 dir = argv[1];
1082## repeat replace np (modtime = "now", modby = @who, modwith = @entity)
1083## where np.#dir = @dir and np.mach_id = @id
1084 return(SMS_SUCCESS);
1085##}
92a943d6 1086
92a943d6 1087
822a6eba 1088/* sets the modtime on a filesystem, where argv[0] contains the filesys
1089 * label.
1090 */
1091
1092set_filesys_modtime(q, argv, cl)
1093 struct query *q;
1094 char *argv[];
1095 client *cl;
1096##{
1097## char *label, *entity;
1098## int who;
1099
1100 entity = cl->entity;
711660a5 1101 who = cl->client_id;
822a6eba 1102
1103 label = argv[0];
1104 if (!strcmp(q->shortname, "ufil"))
1105 label = argv[1];
1106
1107## repeat replace fs (modtime = "now", modby = @who, modwith = @entity,
1108## #phys_id = @var_phys_id) where fs.#label = @label
92a943d6 1109 return(SMS_SUCCESS);
1110##}
05cdd922 1111
822a6eba 1112
1113/* sets the modtime on a zephyr class, where argv[0] contains the class
1114 * name.
1115 */
1116
1117set_zephyr_modtime(q, argv, cl)
1118 struct query *q;
1119 char *argv[];
1120 client *cl;
05cdd922 1121##{
822a6eba 1122## char *class, *entity;
1123## int who;
1124
1125 entity = cl->entity;
711660a5 1126 who = cl->client_id;
822a6eba 1127
1128 class = argv[0];
1129
1130## repeat replace z (modtime = "now", modby = @who, modwith = @entity)
1131## where z.#class = @class
1132 return(SMS_SUCCESS);
1133##}
1134
1135
1136/* fixes the modby field. This will be the second to last thing in the
1137 * argv, the argv length is determined from the query structure. It is
1138 * passed as a pointer to an integer. This will either turn it into a
1139 * username, or # + the users_id.
1140 */
1141followup_fix_modby(q, sq, v, action, actarg, cl)
1142 struct query *q;
1143 register struct save_queue *sq;
1144 struct validate *v;
1145 register int (*action)();
1146 register int actarg;
1147 client *cl;
cc588c08 1148{
822a6eba 1149 register int i, j;
1150 char **argv, *malloc();
cc588c08 1151 int id, status;
05cdd922 1152
822a6eba 1153 i = q->vcnt - 2;
1154 while (sq_get_data(sq, &argv)) {
1155 id = atoi(argv[i]);
711660a5 1156 if (id > 0)
cc588c08 1157 status = id_to_name(id, "USER", &argv[i]);
1158 else
1159 status = id_to_name(-id, "STRING", &argv[i]);
1160 if (status && status != SMS_NO_MATCH)
1161 return(status);
822a6eba 1162 (*action)(q->vcnt, argv, actarg);
1163 for (j = 0; j < q->vcnt; j++)
1164 free(argv[j]);
1165 free(argv);
1166 }
1167 sq_destroy(sq);
1168 return(SMS_SUCCESS);
cc588c08 1169}
30967516 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;
cc588c08 1231{
822a6eba 1232 char **argv, *index();
1233 char *ptype, *p;
cc588c08 1234 int mid, sid, status;
822a6eba 1235
1236 /* for each row */
1237 while (sq_get_data(sq, &argv)) {
1238 sms_trim_args(2, argv);
1239 ptype = argv[1];
1240 p = index(argv[2], ':');
1241 *p++ = 0;
1242 mid = atoi(argv[2]);
1243 sid = atoi(p);
822a6eba 1244
1245 if (!strcmp(ptype, "POP")) {
cc588c08 1246 status = id_to_name(mid, "MACHINE", &argv[2]);
1247 if (status == SMS_NO_MATCH)
822a6eba 1248 return(SMS_MACHINE);
1249 } else if (!strcmp(ptype, "SMTP")) {
cc588c08 1250 status = id_to_name(sid, "STRING", &argv[2]);
1251 if (status == SMS_NO_MATCH)
822a6eba 1252 return(SMS_STRING);
1253 } else /* ptype == "NONE" */ {
1254 goto skip;
1255 }
cc588c08 1256 if (status) return(status);
822a6eba 1257
1258 if (!strcmp(q->shortname, "gpob")) {
1259 sid = atoi(argv[4]);
711660a5 1260 if (sid > 0)
cc588c08 1261 status = id_to_name(sid, "USER", &argv[4]);
1262 else
1263 status = id_to_name(-sid, "STRING", &argv[4]);
822a6eba 1264 }
cc588c08 1265 if (status && status != SMS_NO_MATCH) return(status);
822a6eba 1266
822a6eba 1267 (*action)(q->vcnt, argv, actarg);
1268 skip:
1269 /* free saved data */
1270 free(argv[0]);
1271 free(argv[1]);
711660a5 1272 free(argv[4]);
822a6eba 1273 free(argv);
1274 }
1275
1276 sq_destroy(sq);
1277 return (SMS_SUCCESS);
cc588c08 1278}
822a6eba 1279
1280
44bd6f44 1281/* followup_glin: fix the ace_name in argv[8]. argv[7] will contain the
1282 * ace_type: "LIST", "USER", or "NONE". Decode the id in argv[8] into the
822a6eba 1283 * proper name based on the type, and repace that string in the argv.
1284 * Also fixes the modby field by called followup_fix_modby.
1285 */
1286
1287followup_glin(q, sq, v, action, actarg, cl)
1288 register struct query *q;
1289 register struct save_queue *sq;
1290 register struct validate *v;
1291 register int (*action)();
1292 int actarg;
1293 client *cl;
cc588c08 1294{
822a6eba 1295 char **argv, *malloc(), *realloc(), *type;
cc588c08 1296 int id, i, idx, status;
822a6eba 1297
1298 idx = 8;
1299 if (!strcmp(q->shortname, "gsin"))
4f16dc86 1300 idx = 12;
822a6eba 1301
1302 while (sq_get_data(sq, &argv)) {
1303 sms_trim_args(q->vcnt, argv);
1304
1305 id = atoi(argv[i = q->vcnt - 2]);
711660a5 1306 if (id > 0)
cc588c08 1307 status = id_to_name(id, "USER", &argv[i]);
1308 else
1309 status = id_to_name(-id, "STRING", &argv[i]);
1310 if (status && status != SMS_NO_MATCH)
1311 return(status);
822a6eba 1312
1313 id = atoi(argv[idx]);
1314 type = argv[idx - 1];
822a6eba 1315
1316 if (!strcmp(type, "LIST")) {
cc588c08 1317 status = id_to_name(id, "LIST", &argv[idx]);
822a6eba 1318 } else if (!strcmp(type, "USER")) {
cc588c08 1319 status = id_to_name(id, "USER", &argv[idx]);
f0516942 1320 } else if (!strcmp(type, "KERBEROS")) {
cc588c08 1321 status = id_to_name(id, "STRING", &argv[idx]);
822a6eba 1322 } else if (!strcmp(type, "NONE")) {
cc588c08 1323 status = 0;
1324 free(argv[idx]);
1325 argv[idx] = strsave("NONE");
1326 } else {
1327 status = 0;
1328 free(argv[idx]);
1329 argv[idx] = strsave("???");
1330 }
1331 if (status && status != SMS_NO_MATCH)
1332 return(status);
822a6eba 1333
1334 if (!strcmp(q->shortname, "glin") && atoi(argv[6]) == -1) {
1335 argv[6] = realloc(argv[6], strlen(UNIQUE_GID) + 1);
1336 strcpy(argv[6], UNIQUE_GID);
1337 }
1338
1339 /* send the data */
1340 (*action)(q->vcnt, argv, actarg);
1341
1342 /* free saved data */
1343 for (i = 0; i < q->vcnt; i++)
1344 free(argv[i]);
1345 free(argv);
1346 }
1347
1348 sq_destroy(sq);
1349 return (SMS_SUCCESS);
cc588c08 1350}
822a6eba 1351
1352
711660a5 1353/* followup_gnfq: Fix the directory name & modby fields
1354 * argv[0] = filsys_id
1355 * argv[2] = ascii(quota)
1356 */
1357
1358followup_gnfq(q, sq, v, action, actarg, cl)
1359 struct query *q;
1360 register struct save_queue *sq;
1361 struct validate *v;
1362 register int (*action)();
1363 register int actarg;
1364 client *cl;
1365##{
1366 register int j;
1367 char **argv, *malloc();
1368## int id, rowcount;
1369## char *name, *label;
cc588c08 1370 int status;
711660a5 1371
1372 while (sq_get_data(sq, &argv)) {
1373 id = atoi(argv[3]);
1374 free(argv[3]);
1375 argv[3] = malloc(256);
1376 name = argv[3];
1377 if (id == 0) {
1378 label = argv[0];
1379## repeat retrieve (name = filesys.#name) where filesys.#label = @label
1380 } else {
1381## repeat retrieve (name = nfsphys.dir) where nfsphys.nfsphys_id = @id
1382 }
1383## inquire_equel(rowcount = "rowcount")
1384 if (rowcount != 1) {
1385 sprintf(argv[3], "#%d", id);
1386 }
1387
1388 id = atoi(argv[6]);
711660a5 1389 if (id > 0)
cc588c08 1390 status = id_to_name(id, "USER", &argv[6]);
1391 else
1392 status = id_to_name(-id, "STRING", &argv[6]);
1393 if (status && status != SMS_NO_MATCH)
1394 return(status);
711660a5 1395 (*action)(q->vcnt, argv, actarg);
1396 for (j = 0; j < q->vcnt; j++)
1397 free(argv[j]);
1398 free(argv);
1399 }
1400 sq_destroy(sq);
1401 return(SMS_SUCCESS);
1402##}
1403
1404
822a6eba 1405/* followup_anfq: Add allocation to nfsphys after creating quota.
1406 * argv[0] = filsys_id
1407 * argv[2] = ascii(quota)
1408 */
1409
1410followup_anfq(q, argv, cl)
1411 struct query *q;
1412 char **argv;
1413 client *cl;
1414##{
1415## int quota, user, fs, who;
1416## char *entity;
1417
1418 fs = *(int *)argv[0];
1419 user = *(int *)argv[1];
1420 quota = atoi(argv[2]);
711660a5 1421 who = cl->client_id;
822a6eba 1422 entity = cl->entity;
1423
1424## repeat replace nq (modtime = "now", modby = @who, modwith = @entity)
1425## where nq.filsys_id = @fs and nq.users_id = @user
1426## repeat replace nfsphys (allocated = nfsphys.allocated + @quota)
1427## where nfsphys.nfsphys_id = filesys.#phys_id and filesys.filsys_id = @fs
02ccf7ad 1428 if (ingres_errno) return(sms_errcode);
822a6eba 1429 return(SMS_SUCCESS);
1430##}
1431
1432
1433/* followup_gzcl:
1434 */
1435
1436followup_gzcl(q, sq, v, action, actarg, cl)
1437 register struct query *q;
1438 register struct save_queue *sq;
1439 register struct validate *v;
1440 register int (*action)();
92a943d6 1441 int actarg;
822a6eba 1442 client *cl;
cc588c08 1443{
1444 int id, i, status;
822a6eba 1445 char **argv;
92a943d6 1446
822a6eba 1447 while (sq_get_data(sq, &argv)) {
1448 sms_trim_args(q->vcnt, argv);
92a943d6 1449
822a6eba 1450 id = atoi(argv[i = q->vcnt - 2]);
711660a5 1451 if (id > 0)
cc588c08 1452 status = id_to_name(id, "USER", &argv[i]);
1453 else
1454 status = id_to_name(-id, "STRING", &argv[i]);
1455 if (status && status != SMS_NO_MATCH)
1456 return(status);
822a6eba 1457
1458 for (i = 1; i < 8; i+=2) {
1459 id = atoi(argv[i+1]);
822a6eba 1460 if (!strcmp(argv[i], "LIST")) {
cc588c08 1461 status = id_to_name(id, "LIST", &argv[i+1]);
822a6eba 1462 } else if (!strcmp(argv[i], "USER")) {
cc588c08 1463 status = id_to_name(id, "USER", &argv[i+1]);
f0516942 1464 } else if (!strcmp(argv[i], "KERBEROS")) {
cc588c08 1465 status = id_to_name(id, "STRING", &argv[i+1]);
822a6eba 1466 } else if (!strcmp(argv[i], "NONE")) {
cc588c08 1467 status = 0;
1468 free(argv[i+1]);
1469 argv[i+1] = strsave("NONE");
822a6eba 1470 } else {
cc588c08 1471 status = 0;
1472 free(argv[i+1]);
1473 argv[i+1] = strsave("???");
822a6eba 1474 }
cc588c08 1475 if (status && status != SMS_NO_MATCH)
1476 return(status);
822a6eba 1477 }
92a943d6 1478
822a6eba 1479 /* send the data */
1480 (*action)(q->vcnt, argv, actarg);
1481
1482 /* free saved data */
1483 for (i = 0; i < q->vcnt; i++)
1484 free(argv[i]);
1485 free(argv);
1486 }
1487 sq_destroy(sq);
92a943d6 1488 return(SMS_SUCCESS);
cc588c08 1489}
92a943d6 1490
05cdd922 1491
822a6eba 1492/* followup_gsha:
1493 */
1494
1495followup_gsha(q, sq, v, action, actarg, cl)
05cdd922 1496 register struct query *q;
822a6eba 1497 register struct save_queue *sq;
1498 register struct validate *v;
1499 register int (*action)();
1500 int actarg;
1501 client *cl;
cc588c08 1502{
822a6eba 1503 char **argv;
cc588c08 1504 int i, id, status;
05cdd922 1505
822a6eba 1506 while (sq_get_data(sq, &argv)) {
1507 sms_trim_args(q->vcnt, argv);
05cdd922 1508
822a6eba 1509 id = atoi(argv[4]);
711660a5 1510 if (id > 0)
cc588c08 1511 status = id_to_name(id, "USER", &argv[4]);
1512 else
1513 status = id_to_name(-id, "STRING", &argv[4]);
1514 if (status && status != SMS_NO_MATCH)
1515 return(status);
822a6eba 1516
1517 id = atoi(argv[2]);
822a6eba 1518 if (!strcmp(argv[1], "LIST")) {
cc588c08 1519 status = id_to_name(id, "LIST", &argv[2]);
822a6eba 1520 } else if (!strcmp(argv[1], "USER")) {
cc588c08 1521 status = id_to_name(id, "USER", &argv[2]);
f0516942 1522 } else if (!strcmp(argv[1], "KERBEROS")) {
cc588c08 1523 status = id_to_name(id, "STRING", &argv[2]);
822a6eba 1524 } else if (!strcmp(argv[1], "NONE")) {
cc588c08 1525 status = 0;
1526 free(argv[2]);
1527 argv[2] = strsave("NONE");
822a6eba 1528 } else {
cc588c08 1529 status = 0;
1530 free(argv[2]);
1531 argv[2] = strsave("???");
822a6eba 1532 }
cc588c08 1533 if (status && status != SMS_NO_MATCH)
1534 return(status);
05cdd922 1535
822a6eba 1536 /* send the data */
1537 (*action)(q->vcnt, argv, actarg);
1538
1539 /* free saved data */
1540 for (i = 0; i < q->vcnt; i++)
1541 free(argv[i]);
1542 free(argv);
1543 }
1544 sq_destroy(sq);
1545 return(SMS_SUCCESS);
cc588c08 1546}
05cdd922 1547
05cdd922 1548
822a6eba 1549\f
1550/* Special query routines */
30967516 1551
822a6eba 1552/* set_pobox - this does all of the real work.
1553 * argv = user_id, type, box
1554 * if type is POP, then box should be a machine, and its ID should be put in
1555 * pop_id. If type is SMTP, then box should be a string and its ID should
1556 * be put in box_id. If type is NONE, then box doesn't matter.
1557 */
1558
1559int set_pobox(q, argv, cl)
1560 struct query *q;
1561 char **argv;
1562 client *cl;
1563##{
1564## int user, id, rowcount;
1565## char *box, potype[9];
cc588c08 1566 int status;
822a6eba 1567
1568 box = argv[2];
1569 user = *(int *)argv[0];
1570
1571## repeat retrieve (id = users.pop_id, potype = users.#potype)
1572## where users.users_id = @user
02ccf7ad 1573 if (ingres_errno) return(sms_errcode);
e7fa3293 1574 if (!strcmp(strtrim(potype), "POP"))
822a6eba 1575 set_pop_usage(id, -1);
1576
1577 if (!strcmp(argv[1], "POP")) {
cc588c08 1578 status = name_to_id(box, "MACHINE", &id);
1579 if (status == SMS_NO_MATCH)
1580 return(SMS_MACHINE);
1581 else if (status)
1582 return(status);
822a6eba 1583## repeat replace users (#potype = "POP", pop_id = @id)
1584## where users.users_id = @user
1585 set_pop_usage(id, 1);
1586 } else if (!strcmp(argv[1], "SMTP")) {
353cb0da 1587 if (index(box, '/') || index(box, '|'))
1588 return(SMS_BAD_CHAR);
cc588c08 1589 status = name_to_id(box, "STRING", &id);
1590 if (status == SMS_NO_MATCH) {
1591## repeat retrieve (id = values.value) where values.name = "strings_id"
822a6eba 1592 id++;
cc588c08 1593## repeat replace values (value = @id) where values.name = "strings_id"
822a6eba 1594## append to strings (string_id = id, string = box)
cc588c08 1595 } else if (status)
1596 return(status);
822a6eba 1597## repeat replace users (#potype = "SMTP", box_id = @id)
1598## where users.users_id = @user
1599 } else /* argv[1] == "NONE" */ {
1600## repeat replace users (#potype = "NONE") where users.users_id = @user
1601 }
1602
1603 set_pobox_modtime(q, argv, cl);
1604## repeat replace tblstats (updates = tblstats.updates + 1, modtime = "now")
1605## where tblstats.#table = "users"
02ccf7ad 1606 if (ingres_errno) return(sms_errcode);
30967516 1607 return(SMS_SUCCESS);
1608##}
1609
30967516 1610
822a6eba 1611/* get_list_info: passed a wildcard list name, returns lots of stuff about
1612 * each list. This is tricky: first build a queue of all requested
44bd6f44 1613 * data. Rest of processing consists of fixing gid, ace_name, and modby.
822a6eba 1614 */
1615
1616get_list_info(q, aargv, cl, action, actarg)
30967516 1617 register struct query *q;
822a6eba 1618 char **aargv;
1619 client *cl;
1620 register int (*action)();
1621 int actarg;
30967516 1622##{
822a6eba 1623 char *argv[13], *malloc(), *realloc();
1624## char *name, acl_type[9], listname[33], active[5], public[5], hidden[5];
49189928 1625## char maillist[5], group[5], gid[6], acl_name[256], desc[256], modtime[27];
711660a5 1626## char modby[256], modwith[9];
822a6eba 1627## int id, rowcount, acl_id, hid, modby_id;
cc588c08 1628 int returned, status;
822a6eba 1629 struct save_queue *sq, *sq_create();
30967516 1630
822a6eba 1631 returned = rowcount = 0;
1632 name = aargv[0];
30967516 1633
822a6eba 1634 sq = sq_create();
1635## range of l is list
1636## repeat retrieve (id = l.list_id) where l.#name = @name {
1637 sq_save_data(sq, id);
1638 rowcount++;
1639## }
711660a5 1640 if (ingres_errno) return(sms_errcode);
822a6eba 1641 if (rowcount == 0)
1642 return(SMS_NO_MATCH);
1643
1644 argv[0] = listname; argv[1] = active; argv[2] = public; argv[3] = hidden;
1645 argv[4] = maillist; argv[5] = group; argv[6] = gid; argv[7] = acl_type;
cc588c08 1646 argv[9] = desc; argv[10] = modtime; argv[12] = modwith;
822a6eba 1647
1648 while (sq_get_data(sq, &id)) {
1649 if (id == 0)
1650 continue;
1651 argv[6] = gid;
1652## repeat retrieve (listname = l.#name, active = text(l.#active),
1653## public = text(l.#public), hidden = text(l.#hidden),
1654## hid = l.#hidden, maillist = text(l.#maillist),
1655## group = text(l.#group), gid = text(l.#gid),
1656## acl_type = trim(l.#acl_type), acl_id = l.#acl_id,
1657## desc = l.#desc, modtime = l.#modtime, modby_id = l.#modby,
1658## modwith =l.#modwith)
1659## where l.list_id = @id
711660a5 1660 if (ingres_errno) return(sms_errcode);
822a6eba 1661
1662 if (atoi(gid) == -1)
1663 argv[6] = UNIQUE_GID;
1664
cc588c08 1665 argv[8] = malloc(0);
822a6eba 1666 if (!strcmp(acl_type, "LIST")) {
cc588c08 1667 status = id_to_name(acl_id, "LIST", &argv[8]);
822a6eba 1668 } else if (!strcmp(acl_type, "USER")) {
cc588c08 1669 status = id_to_name(acl_id, "USER", &argv[8]);
f0516942 1670 } else if (!strcmp(acl_type, "KERBEROS")) {
cc588c08 1671 status = id_to_name(acl_id, "STRING", &argv[8]);
822a6eba 1672 } else if (!strcmp(acl_type, "NONE")) {
cc588c08 1673 status = 0;
1674 free(argv[8]);
1675 argv[8] = strsave("NONE");
1676 } else {
1677 status = 0;
1678 free(argv[8]);
1679 argv[8] = strsave("???");
1680 }
1681 if (status && status != SMS_NO_MATCH) return(status);
822a6eba 1682
cc588c08 1683 argv[11] = malloc(0);
711660a5 1684 if (modby_id > 0)
cc588c08 1685 status = id_to_name(modby_id, "USER", &argv[11]);
1686 else
1687 status = id_to_name(-modby_id, "STRING", &argv[11]);
1688 if (status && status != SMS_NO_MATCH) return(status);
822a6eba 1689
1690 sms_trim_args(q->vcnt, argv);
1691 returned++;
1692 (*action)(q->vcnt, argv, actarg);
cc588c08 1693 free(argv[8]);
1694 free(argv[11]);
822a6eba 1695 }
30967516 1696
822a6eba 1697 sq_destroy(sq);
02ccf7ad 1698 if (ingres_errno) return(sms_errcode);
822a6eba 1699 return (SMS_SUCCESS);
1700##}
1701
1702
a6683dad 1703/* Add_member_to_list: do list flattening as we go! MAXLISTDEPTH is
1704 * how many different ancestors a member is allowed to have.
1705 */
1706
1707#define MAXLISTDEPTH 100
1708
1709int add_member_to_list(q, argv, cl)
1710 struct query *q;
1711 char **argv;
1712 client *cl;
1713##{
49189928 1714## int id, lid, mid, exists, error, who, ref;
cc588c08 1715## char *mtype, dtype[9], *entity;
49189928 1716 int ancestors[MAXLISTDEPTH], aref[MAXLISTDEPTH], acount, a;
1717 int descendants[MAXLISTDEPTH], dref[MAXLISTDEPTH], dcount, d;
cc588c08 1718 int status;
a6683dad 1719 char *dtypes[MAXLISTDEPTH];
cc588c08 1720 char *iargv[3], *buf;
a6683dad 1721
1722## range of m is imembers
1723 lid = *(int *)argv[0];
1724 mtype = argv[1];
1725 mid = *(int *)argv[2];
49189928 1726 /* if the member is already a direct member of the list, punt */
a6683dad 1727## repeat retrieve (exists = any(m.list_id where m.list_id=@lid and
1728## m.member_id = @mid and m.member_type = @mtype
1729## and m.direct = 1))
1730 if (exists)
1731 return(SMS_EXISTS);
353cb0da 1732 if (!strcasecmp(mtype, "STRING")) {
cc588c08 1733 buf = malloc(0);
1734 status = id_to_name(mid, "STRING", &buf);
1735 if (status) return(status);
1736 if (index(buf, '/') || index(buf, '|')) {
1737 free(buf);
1738 return(SMS_BAD_CHAR);
1739 }
1740 free(buf);
353cb0da 1741 }
1742
a6683dad 1743 ancestors[0] = lid;
49189928 1744 aref[0] = 1;
a6683dad 1745 acount = 1;
49189928 1746## repeat retrieve (id = m.list_id, ref = m.ref_count)
a6683dad 1747## where m.member_id = @lid and m.member_type = "LIST" {
49189928 1748 aref[acount] = ref;
a6683dad 1749 ancestors[acount++] = id;
1750 if (acount >= MAXLISTDEPTH) {
1751## endretrieve
1752 }
1753## }
711660a5 1754 if (ingres_errno) return(sms_errcode);
a6683dad 1755 if (acount >= MAXLISTDEPTH) {
1756 return(SMS_INTERNAL);
1757 }
1758 descendants[0] = mid;
1759 dtypes[0] = mtype;
49189928 1760 dref[0] = 1;
a6683dad 1761 dcount = 1;
1762 error = 0;
1763 if (!strcmp(mtype, "LIST")) {
49189928 1764## repeat retrieve (id = m.member_id, dtype = m.member_type,
1765## ref = m.ref_count)
a6683dad 1766## where m.list_id = @mid {
1767 switch (dtype[0]) {
1768 case 'L':
1769 dtypes[dcount] = "LIST";
1770 break;
1771 case 'U':
1772 dtypes[dcount] = "USER";
1773 break;
1774 case 'S':
1775 dtypes[dcount] = "STRING";
1776 break;
1777 case 'K':
1778 dtypes[dcount] = "KERBEROS";
1779 break;
1780 default:
1781 error++;
1782## endretrieve
1783 }
49189928 1784 dref[dcount] = ref;
a6683dad 1785 descendants[dcount++] = id;
1786 if (dcount >= MAXLISTDEPTH) {
1787 error++;
1788## endretrieve
1789 }
1790## }
711660a5 1791 if (ingres_errno) return(sms_errcode);
a6683dad 1792 if (error)
1793 return(SMS_INTERNAL);
1794 }
1795 for (a = 0; a < acount; a++) {
1796 lid = ancestors[a];
1797 for (d = 0; d < dcount; d++) {
1798 mid = descendants[d];
1799 mtype = dtypes[d];
1800 if (mid == lid && !strcmp(mtype, "LIST")) {
1801 return(SMS_LISTLOOP);
1802 }
1803## repeat retrieve (exists = any(m.ref_count where m.list_id = @lid
1804## and m.member_id = @mid
1805## and m.member_type = @mtype))
49189928 1806 ref = aref[a] * dref[d];
a6683dad 1807 if (exists) {
1808 if (a == 0 && d == 0)
49189928 1809## replace m (ref_count = m.ref_count+ref, direct = 1)
a6683dad 1810## where m.list_id = lid and m.member_id = mid and
1811## m.member_type = mtype
1812 else
49189928 1813## replace m (ref_count = m.ref_count+ref)
a6683dad 1814## where m.list_id = lid and m.member_id = mid and
1815## m.member_type = mtype
1816 } else {
711660a5 1817 incremental_clear_before();
a6683dad 1818 if (a == 0 && d == 0)
1819## append imembers (list_id=lid, member_id = mid, direct = 1,
1820## member_type=mtype, ref_count = 1)
1821 else
1822## append imembers (list_id=lid, member_id = mid,
49189928 1823## member_type=mtype, ref_count = ref)
711660a5 1824 iargv[0] = (char *)lid;
1825 iargv[1] = mtype;
1826 iargv[2] = (char *)mid;
1827 incremental_after("members", 0, iargv);
a6683dad 1828 }
1829 }
1830 }
189bd6e7 1831 lid = *(int *)argv[0];
1832 entity = cl->entity;
1833 who = cl->client_id;
1834## repeat replace list (modtime = "now", modby = @who, modwith = @entity)
1835## where list.#list_id = @lid
711660a5 1836 if (ingres_errno) return(sms_errcode);
a6683dad 1837 return(SMS_SUCCESS);
1838##}
1839
1840
1841/* Delete_member_from_list: do list flattening as we go!
1842 */
1843
1844int delete_member_from_list(q, argv, cl)
1845 struct query *q;
1846 char **argv;
1847 client *cl;
1848##{
49189928 1849## int id, lid, mid, cnt, exists, error, who, ref;
189bd6e7 1850## char *mtype, dtype[9], *entity;
49189928 1851 int ancestors[MAXLISTDEPTH], aref[MAXLISTDEPTH], acount, a;
1852 int descendants[MAXLISTDEPTH], dref[MAXLISTDEPTH], dcount, d;
a6683dad 1853 char *dtypes[MAXLISTDEPTH];
711660a5 1854 char *iargv[3];
a6683dad 1855
1856## range of m is imembers
1857 lid = *(int *)argv[0];
1858 mtype = argv[1];
1859 mid = *(int *)argv[2];
49189928 1860 /* if the member is not a direct member of the list, punt */
a6683dad 1861## repeat retrieve (exists = any(m.list_id where m.list_id=@lid and
1862## m.member_id = @mid and m.member_type = @mtype
1863## and m.direct = 1))
711660a5 1864 if (ingres_errno) return(sms_errcode);
a6683dad 1865 if (!exists)
1866 return(SMS_NO_MATCH);
1867 ancestors[0] = lid;
49189928 1868 aref[0] = 1;
a6683dad 1869 acount = 1;
49189928 1870## repeat retrieve (id = m.list_id, ref = m.ref_count)
a6683dad 1871## where m.member_id = @lid and m.member_type = "LIST" {
49189928 1872 aref[acount] = ref;
a6683dad 1873 ancestors[acount++] = id;
1874 if (acount >= MAXLISTDEPTH)
1875## endretrieve
1876## }
711660a5 1877 if (ingres_errno) return(sms_errcode);
a6683dad 1878 if (acount >= MAXLISTDEPTH)
1879 return(SMS_INTERNAL);
1880 descendants[0] = mid;
1881 dtypes[0] = mtype;
49189928 1882 dref[0] = 1;
a6683dad 1883 dcount = 1;
1884 error = 0;
1885 if (!strcmp(mtype, "LIST")) {
49189928 1886## repeat retrieve (id = m.member_id, dtype = m.member_type,
1887## ref = m.ref_count)
a6683dad 1888## where m.list_id = @mid {
1889 switch (dtype[0]) {
1890 case 'L':
1891 dtypes[dcount] = "LIST";
1892 break;
1893 case 'U':
1894 dtypes[dcount] = "USER";
1895 break;
1896 case 'S':
1897 dtypes[dcount] = "STRING";
1898 break;
1899 case 'K':
1900 dtypes[dcount] = "KERBEROS";
1901 break;
1902 default:
1903 error++;
1904## endretrieve
1905 }
49189928 1906 dref[dcount] = ref;
a6683dad 1907 descendants[dcount++] = id;
1908 if (dcount >= MAXLISTDEPTH)
1909## endretrieve
1910## }
711660a5 1911 if (ingres_errno) return(sms_errcode);
a6683dad 1912 if (error)
1913 return(SMS_INTERNAL);
1914 }
1915 for (a = 0; a < acount; a++) {
1916 lid = ancestors[a];
1917 for (d = 0; d < dcount; d++) {
1918 mid = descendants[d];
1919 mtype = dtypes[d];
1920 if (mid == lid && !strcmp(mtype, "LIST")) {
1921 return(SMS_LISTLOOP);
1922 }
1923## repeat retrieve (cnt = m.ref_count)
1924## where m.list_id = @lid and m.member_id = @mid
1925## and m.member_type = @mtype
49189928 1926 ref = aref[a] * dref[d];
1927 if (cnt <= ref) {
711660a5 1928 iargv[0] = (char *)lid;
1929 iargv[1] = mtype;
1930 iargv[2] = (char *)mid;
1931 incremental_before("members", 0, iargv);
a6683dad 1932## delete m where m.list_id = lid and m.member_id = mid and
1933## m.member_type = mtype
711660a5 1934 incremental_clear_after();
a6683dad 1935 } else if (a == 0 && d == 0) {
49189928 1936## replace m (ref_count = m.ref_count-ref, direct = 0)
a6683dad 1937## where m.list_id = lid and m.member_id = mid and
1938## m.member_type = mtype
1939 } else {
49189928 1940## replace m (ref_count = m.ref_count-ref)
353cb0da 1941## where m.list_id = lid and m.member_id = mid and
a6683dad 1942## m.member_type = mtype
1943 }
1944 }
1945 }
189bd6e7 1946 lid = *(int *)argv[0];
1947 entity = cl->entity;
1948 who = cl->client_id;
1949## repeat replace list (modtime = "now", modby = @who, modwith = @entity)
1950## where list.#list_id = @lid
711660a5 1951 if (ingres_errno) return(sms_errcode);
a6683dad 1952 return(SMS_SUCCESS);
1953##}
1954
1955
44bd6f44 1956/* get_ace_use - given a type and a name, return a type and a name.
1957 * The ace_type is one of "LIST", "USER", "RLIST", or "RUSER" in argv[0],
822a6eba 1958 * and argv[1] will contain the ID of the entity in question. The R*
1959 * types mean to recursively look at every containing list, not just
1960 * when the object in question is a direct member. On return, the
1961 * usage type will be one of LIST, SERVICE, FILESYS, QUOTA, QUERY, or ZEPHYR.
1962 */
1963
44bd6f44 1964int get_ace_use(q, argv, cl, action, actarg)
822a6eba 1965 struct query *q;
1966 char *argv[];
1967 client *cl;
1968 int (*action)();
1969 int actarg;
1970##{
1971 int found = 0;
1972## char *atype;
1973## int aid, listid, id;
1974 struct save_queue *sq, *sq_create();
1975
a6683dad 1976## range of m is imembers
822a6eba 1977 atype = argv[0];
1978 aid = *(int *)argv[1];
f0516942 1979 if (!strcmp(atype, "LIST") || !strcmp(atype, "USER") ||
1980 !strcmp(atype, "KERBEROS")) {
44bd6f44 1981 return(get_ace_internal(atype, aid, action, actarg));
822a6eba 1982 }
1983
1984 sq = sq_create();
1985 if (!strcmp(atype, "RLIST")) {
1986 sq_save_data(sq, aid);
1987 /* get all the list_id's of containing lists */
a6683dad 1988## repeat retrieve (listid = m.list_id)
822a6eba 1989## where m.member_type = "LIST" and m.member_id = @id {
a6683dad 1990 sq_save_unique_data(sq, listid);
1991## }
822a6eba 1992 /* now process each one */
1993 while (sq_get_data(sq, &id)) {
44bd6f44 1994 if (get_ace_internal("LIST", id, action, actarg) == SMS_SUCCESS)
822a6eba 1995 found++;
1996 }
1997 }
1998
1999 if (!strcmp(atype, "RUSER")) {
822a6eba 2000## repeat retrieve (listid = m.list_id)
2001## where m.member_type = "USER" and m.member_id = @aid {
2002 sq_save_data(sq, listid);
2003## }
822a6eba 2004 /* now process each one */
2005 while (sq_get_data(sq, &id)) {
44bd6f44 2006 if (get_ace_internal("LIST", id, action, actarg) == SMS_SUCCESS)
822a6eba 2007 found++;
2008 }
44bd6f44 2009 if (get_ace_internal("USER", aid, action, actarg) == SMS_SUCCESS)
822a6eba 2010 found++;
2011 }
05cdd922 2012
f0516942 2013 if (!strcmp(atype, "RKERBERO")) {
f0516942 2014## repeat retrieve (listid = m.list_id)
2015## where m.member_type = "KERBEROS" and m.member_id = @aid {
2016 sq_save_data(sq, listid);
2017## }
f0516942 2018 /* now process each one */
2019 while (sq_get_data(sq, &id)) {
2020 if (get_ace_internal("LIST", id, action, actarg) == SMS_SUCCESS)
2021 found++;
2022 }
2023 if (get_ace_internal("KERBEROS", aid, action, actarg) == SMS_SUCCESS)
2024 found++;
2025 }
2026
822a6eba 2027 sq_destroy(sq);
02ccf7ad 2028 if (ingres_errno) return(sms_errcode);
822a6eba 2029 if (!found) return(SMS_NO_MATCH);
05cdd922 2030 return(SMS_SUCCESS);
2031##}
92a943d6 2032
822a6eba 2033
44bd6f44 2034/* This looks up a single list or user for ace use. atype must be "USER"
822a6eba 2035 * or "LIST", and aid is the ID of the corresponding object. This is used
44bd6f44 2036 * by get_ace_use above.
822a6eba 2037 */
2038
44bd6f44 2039##get_ace_internal(atype, aid, action, actarg)
822a6eba 2040## char *atype;
2041## int aid;
2042 int (*action)();
2043 int actarg;
2044##{
2045 char *rargv[2];
2046 int found = 0;
2047## char name[33];
2048
2049 rargv[1] = name;
2050 if (!strcmp(atype, "LIST")) {
2051 rargv[0] = "FILESYS";
2052## repeat retrieve (name = filesys.label)
2053## where filesys.owners = @aid {
2054 (*action)(2, rargv, actarg);
2055 found++;
2056## }
2057
2058 rargv[0] = "QUERY";
2059## repeat retrieve (name = capacls.capability)
2060## where capacls.list_id = @aid {
2061 (*action)(2, rargv, actarg);
2062 found++;
2063## }
2064 } else if (!strcmp(atype, "USER")) {
2065 rargv[0] = "FILESYS";
2066## repeat retrieve (name = filesys.label)
2067## where filesys.owner = @aid {
2068 (*action)(2, rargv, actarg);
2069 found++;
2070## }
2071 }
2072
2073 rargv[0] = "LIST";
2074## repeat retrieve (name = list.#name)
2075## where list.acl_type = @atype and list.acl_id = @aid {
2076 (*action)(2, rargv, actarg);
2077 found++;
2078## }
2079
2080 rargv[0] = "SERVICE";
2081## repeat retrieve (name = servers.#name)
2082## where servers.acl_type = @atype and servers.acl_id = @aid {
2083 (*action)(2, rargv, actarg);
2084 found++;
2085## }
2086
2087 rargv[0] = "HOSTACCESS";
2088## repeat retrieve (name = machine.#name)
2089## where machine.mach_id = hostaccess.mach_id and
2090## hostaccess.acl_type = @atype and hostaccess.acl_id = @aid {
2091 (*action)(2, rargv, actarg);
2092 found++;
2093## }
2094 rargv[0] = "ZEPHYR";
2095## repeat retrieve (name = zephyr.class)
2096## where zephyr.xmt_type = @atype and zephyr.xmt_id = @aid or
2097## zephyr.sub_type = @atype and zephyr.sub_id = @aid or
2098## zephyr.iws_type = @atype and zephyr.iws_id = @aid or
2099## zephyr.iui_type = @atype and zephyr.iui_id = @aid {
2100 (*action)(2, rargv, actarg);
2101 found++;
2102## }
2103
2104 if (!found) return(SMS_NO_MATCH);
2105 return(SMS_SUCCESS);
2106##}
2107
2108
2109/* get_lists_of_member - given a type and a name, return the name and flags
2110 * of all of the lists of the given member. The member_type is one of
2111 * "LIST", "USER", "STRING", "RLIST", "RUSER", or "RSTRING" in argv[0],
2112 * and argv[1] will contain the ID of the entity in question. The R*
2113 * types mean to recursively look at every containing list, not just
2114 * when the object in question is a direct member.
2115 */
2116
2117int get_lists_of_member(q, argv, cl, action, actarg)
92a943d6 2118 struct query *q;
2119 char *argv[];
822a6eba 2120 client *cl;
2121 int (*action)();
2122 int actarg;
92a943d6 2123##{
a6683dad 2124 int found = 0, direct = 1;
2125 char *rargv[6];
822a6eba 2126## char *atype;
2127## int aid, listid, id;
a6683dad 2128## char name[33], active[5], public[5], hidden[5], maillist[5], group[5];
822a6eba 2129
2130 atype = argv[0];
2131 aid = *(int *)argv[1];
822a6eba 2132 if (!strcmp(atype, "RLIST")) {
a6683dad 2133 atype = "LIST";
2134 direct = 0;
822a6eba 2135 }
822a6eba 2136 if (!strcmp(atype, "RUSER")) {
a6683dad 2137 atype = "USER";
2138 direct = 0;
822a6eba 2139 }
822a6eba 2140 if (!strcmp(atype, "RSTRING")) {
a6683dad 2141 atype = "STRING";
2142 direct = 0;
92a943d6 2143 }
a6683dad 2144 if (!strcmp(atype, "RKERBEROS")) {
2145 atype = "KERBEROS";
2146 direct = 0;
f0516942 2147 }
2148
822a6eba 2149 rargv[0] = name;
2150 rargv[1] = active;
2151 rargv[2] = public;
2152 rargv[3] = hidden;
2153 rargv[4] = maillist;
2154 rargv[5] = group;
9bcb4bf5 2155## range of m is imembers
a6683dad 2156 if (direct) {
2157## repeat retrieve (name = list.#name, active = text(list.#active),
2158## public = text(list.#public), hidden = text(list.#hidden),
2159## maillist = text(list.#maillist), group = text(list.#group))
2160## where list.list_id = m.list_id and m.direct = 1 and
2161## m.member_type = @atype and m.member_id = @aid {
2162 (*action)(6, rargv, actarg);
2163 found++;
2164## }
2165 } else {
2166## repeat retrieve (name = list.#name, active = text(list.#active),
822a6eba 2167## public = text(list.#public), hidden = text(list.#hidden),
2168## maillist = text(list.#maillist), group = text(list.#group))
2169## where list.list_id = m.list_id and
2170## m.member_type = @atype and m.member_id = @aid {
2171 (*action)(6, rargv, actarg);
2172 found++;
a6683dad 2173## }
2174 }
92a943d6 2175
02ccf7ad 2176 if (ingres_errno) return(sms_errcode);
822a6eba 2177 if (!found) return(SMS_NO_MATCH);
92a943d6 2178 return(SMS_SUCCESS);
2179##}
2180
822a6eba 2181
2182/* qualified_get_lists: passed "TRUE", "FALSE", or "DONTCARE" for each of
2183 * the five flags associated with each list. It will return the name of
2184 * each list that meets the quailifications. It does this by building a
2185 * where clause based on the arguments, then doing a retrieve.
2186 */
2187
2188static char *lflags[5] = { "active", "public", "hidden", "maillist", "group" };
2189
2190int qualified_get_lists(q, argv, cl, action, actarg)
2191 struct query *q;
2192 char *argv[];
2193 client *cl;
2194 int (*action)();
2195 int actarg;
2196{
2197 return(qualified_get(q, argv, action, actarg, "l.list_id != 0",
2198 "l", "name", lflags));
2199}
2200
2201
2202/** get_members_of_list - optimized query for retrieval of list members
c2408bd5 2203 **
2204 ** Inputs:
2205 ** argv[0] - list_id
2206 **
2207 ** Description:
2208 ** - retrieve USER members, then LIST members, then STRING members
c2408bd5 2209 **/
2210
822a6eba 2211get_members_of_list(q, argv, cl, action, actarg)
c2408bd5 2212 struct query *q;
2213 char *argv[];
822a6eba 2214 client *cl;
c2408bd5 2215 int (*action)();
2216 int actarg;
2217##{
2218## int list_id;
2219## char member_name[129];
2220 char *targv[2];
2221
2222 list_id = *(int *)argv[0];
2223 targv[0] = "USER";
2224 targv[1] = member_name;
2225
a6683dad 2226## range of m is imembers
c2408bd5 2227## repeat retrieve (member_name = users.login)
2228## where m.#list_id = @list_id and m.member_type = "USER"
a6683dad 2229## and m.member_id = users.users_id and m.direct = 1
92a943d6 2230## sort by #member_name
c2408bd5 2231## {
2232 (*action)(2, targv, actarg);
2233## }
02ccf7ad 2234 if (ingres_errno) return(sms_errcode);
c2408bd5 2235
2236 targv[0] = "LIST";
2237## repeat retrieve (member_name = list.name)
2238## where m.#list_id = @list_id and m.member_type = "LIST"
a6683dad 2239## and m.member_id = list.#list_id and m.direct = 1
92a943d6 2240## sort by #member_name
c2408bd5 2241## {
2242 (*action)(2, targv, actarg);
2243## }
02ccf7ad 2244 if (ingres_errno) return(sms_errcode);
c2408bd5 2245
2246 targv[0] = "STRING";
2247## repeat retrieve (member_name = strings.string)
2248## where m.#list_id = @list_id and m.member_type = "STRING"
a6683dad 2249## and m.member_id = strings.string_id and m.direct = 1
92a943d6 2250## sort by #member_name
f0516942 2251## {
2252 (*action)(2, targv, actarg);
2253## }
02ccf7ad 2254 if (ingres_errno) return(sms_errcode);
f0516942 2255
2256 targv[0] = "KERBEROS";
2257## repeat retrieve (member_name = strings.string)
2258## where m.#list_id = @list_id and m.member_type = "KERBEROS"
a6683dad 2259## and m.member_id = strings.string_id and m.direct = 1
f0516942 2260## sort by #member_name
c2408bd5 2261## {
2262 (*action)(2, targv, actarg);
2263## }
02ccf7ad 2264 if (ingres_errno) return(sms_errcode);
c2408bd5 2265
2266 return(SMS_SUCCESS);
2267##}
2268
92a943d6 2269
822a6eba 2270/* count_members_of_list: this is a simple query, but it cannot be done
2271 * through the dispatch table.
2272 */
2273
2274int count_members_of_list(q, argv, cl, action, actarg)
92a943d6 2275 struct query *q;
2276 char *argv[];
822a6eba 2277 client *cl;
92a943d6 2278 int (*action)();
2279 int actarg;
2280##{
822a6eba 2281## int list, ct = 0;
2282 char *rargv[1], countbuf[5];
2283
2284 list = *(int *)argv[0];
2285 rargv[0] = countbuf;
a6683dad 2286## repeat retrieve (ct = count(imembers.list_id
2287## where imembers.list_id = @list and
2288## imembers.direct = 1))
02ccf7ad 2289 if (ingres_errno) return(sms_errcode);
822a6eba 2290 sprintf(countbuf, "%d", ct);
2291 (*action)(1, rargv, actarg);
822a6eba 2292 return(SMS_SUCCESS);
2293##}
92a943d6 2294
92a943d6 2295
822a6eba 2296/* qualified_get_server: passed "TRUE", "FALSE", or "DONTCARE" for each of
2297 * the three flags associated with each service. It will return the name of
2298 * each service that meets the quailifications. It does this by building a
2299 * where clause based on the arguments, then doing a retrieve.
2300 */
92a943d6 2301
822a6eba 2302static char *sflags[3] = { "enable", "inprogress", "harderror" };
a6cb4d4c 2303
822a6eba 2304int qualified_get_server(q, argv, cl, action, actarg)
a6cb4d4c 2305 struct query *q;
2306 char *argv[];
822a6eba 2307 client *cl;
a6cb4d4c 2308 int (*action)();
2309 int actarg;
822a6eba 2310{
2311 return(qualified_get(q, argv, action, actarg, "s.name != \"\"",
2312 "s", "name", sflags));
2313}
a6cb4d4c 2314
a6cb4d4c 2315
822a6eba 2316/* generic qualified get routine, used by qualified_get_lists,
2317 * qualified_get_server, and qualified_get_serverhost.
2318 * Args:
2319 * start - a simple where clause, must not be empty
2320 * range - the name of the range variable
2321 * field - the field to return
2322 * flags - an array of strings, names of the flag variables
2323 */
c2408bd5 2324
822a6eba 2325int qualified_get(q, argv, action, actarg, start, range, field, flags)
c2408bd5 2326 struct query *q;
2327 char *argv[];
2328 int (*action)();
2329 int actarg;
822a6eba 2330 char *start;
2331 char *range;
2332 char *field;
2333 char *flags[];
c2408bd5 2334##{
822a6eba 2335## char name[33], qual[256], *rvar, *rtbl, *rfield;
2336 char *rargv[1], buf[32];
2337## int rowcount, i;
2338
2339 strcpy(qual, start);
2340 for (i = 0; i < q->argc; i++) {
2341 if (!strcmp(argv[i], "TRUE")) {
2342 sprintf(buf, " and %s.%s != 0", range, flags[i]);
2343 (void) strcat(qual, buf);
2344 } else if (!strcmp(argv[i], "FALSE")) {
2345 sprintf(buf, " and %s.%s = 0", range, flags[i]);
2346 (void) strcat(qual, buf);
2347 }
2348 }
2349
2350 rargv[0] = name;
2351 rvar = range;
2352 rtbl = q->rtable;
2353 rfield = field;
2354## range of rvar is rtbl
2355## retrieve (name = rvar.rfield) where qual {
2356 (*action)(1, rargv, actarg);
c2408bd5 2357## }
02ccf7ad 2358 if (ingres_errno) return(sms_errcode);
822a6eba 2359## inquire_equel(rowcount = "rowcount")
822a6eba 2360 if (rowcount == 0)
2361 return(SMS_NO_MATCH);
2362 return(SMS_SUCCESS);
2363##}
c2408bd5 2364
c2408bd5 2365
822a6eba 2366/* qualified_get_serverhost: passed "TRUE", "FALSE", or "DONTCARE" for each of
2367 * the five flags associated with each serverhost. It will return the name of
2368 * each service and host that meets the quailifications. It does this by
2369 * building a where clause based on the arguments, then doing a retrieve.
2370 */
c2408bd5 2371
822a6eba 2372static char *shflags[6] = { "service", "enable", "override", "success",
2373 "inprogress", "hosterror" };
a6cb4d4c 2374
822a6eba 2375int qualified_get_serverhost(q, argv, cl, action, actarg)
a6cb4d4c 2376 struct query *q;
2377 char *argv[];
822a6eba 2378 client *cl;
a6cb4d4c 2379 int (*action)();
2380 int actarg;
2381##{
822a6eba 2382## char sname[33], mname[33], qual[256];
2383 char *rargv[2], buf[32];
2384## int rowcount, i;
2385
44bd6f44 2386 sprintf(qual, "machine.mach_id = sh.mach_id and sh.service = uppercase(\"%s\")",
822a6eba 2387 argv[0]);
2388 for (i = 1; i < q->argc; i++) {
2389 if (!strcmp(argv[i], "TRUE")) {
2390 sprintf(buf, " and sh.%s != 0", shflags[i]);
2391 strcat(qual, buf);
2392 } else if (!strcmp(argv[i], "FALSE")) {
2393 sprintf(buf, " and sh.%s = 0", shflags[i]);
2394 strcat(qual, buf);
2395 }
2396 }
2397
2398 rargv[0] = sname;
2399 rargv[1] = mname;
2400## range of sh is serverhosts
2401## retrieve (sname = sh.service, mname = machine.name) where qual {
2402 (*action)(2, rargv, actarg);
a6cb4d4c 2403## }
02ccf7ad 2404 if (ingres_errno) return(sms_errcode);
822a6eba 2405## inquire_equel(rowcount = "rowcount")
822a6eba 2406 if (rowcount == 0)
2407 return(SMS_NO_MATCH);
2408 return(SMS_SUCCESS);
2409##}
a6cb4d4c 2410
a6cb4d4c 2411
822a6eba 2412/* register_user - change user's login name and allocate a pobox, group,
2413 * filesystem, and quota for them. The user's status must start out as 0,
2414 * and is left as 2. Arguments are: user's UID, new login name, and user's
2415 * type for filesystem allocation (SMS_FS_STUDENT, SMS_FS_FACULTY,
2416 * SMS_FS_STAFF, SMS_FS_MISC).
2417 */
2418
2419register_user(q, argv, cl)
2420 struct query *q;
2421 char **argv;
2422 client *cl;
2423##{
2424## char *login, dir[65], *entity, *directory, machname[33];
2425## int who, rowcount, mid, uid, users_id, flag, utype, nid, list_id, quota;
2426## int size, alloc, pid, m_id;
711660a5 2427 char buffer[256], *aargv[3];
822a6eba 2428 int maxsize;
2429
2430 entity = cl->entity;
711660a5 2431 who = cl->client_id;
822a6eba 2432
2433 uid = atoi(argv[0]);
2434 login = argv[1];
2435 utype = atoi(argv[2]);
2436
2437## range of u is users
2438## range of l is list
2439## range of sh is serverhosts
2440## range of n is nfsphys
2441## range of m is machine
2442
2443 /* find user */
2444## repeat retrieve (users_id = u.#users_id)
711660a5 2445## where u.#uid = @uid and (u.status = 0 or u.status = 5)
822a6eba 2446## inquire_equel(rowcount = "rowcount");
2447 if (rowcount == 0)
2448 return(SMS_NO_MATCH);
2449 if (rowcount > 1)
2450 return(SMS_NOT_UNIQUE);
2451
2452 /* check new login name */
711660a5 2453## repeat retrieve (flag = any(u.#login where u.#login = @login and
2454## u.#users_id != users_id))
e1795ce1 2455 if (ingres_errno) return(sms_errcode);
2456 if (flag) return(SMS_IN_USE);
4f16dc86 2457## repeat retrieve (flag = any(l.#name where l.#name = @login))
e1795ce1 2458 if (ingres_errno) return(sms_errcode);
2459 if (flag) return(SMS_IN_USE);
99a288b9 2460## repeat retrieve (flag = any(filesys.#label where filesys.#label = @login))
e1795ce1 2461 if (ingres_errno) return(sms_errcode);
2462 if (flag) return(SMS_IN_USE);
822a6eba 2463 com_err(whoami, 0, "new login name OK");
2464
2465 /* choose place for pobox, put in mid */
2466## repeat retrieve (mid = sh.mach_id, machname = m.name)
44bd6f44 2467## where sh.service = "POP" and m.mach_id = sh.mach_id and
2468## sh.value2 - sh.value1 = max(sh.value2-sh.value1 where sh.service="POP")
02ccf7ad 2469 if (ingres_errno) return(sms_errcode);
8ac9ee7a 2470## inquire_equel(rowcount = "rowcount");
822a6eba 2471 if (rowcount == 0)
44bd6f44 2472 return(SMS_NO_POBOX);
822a6eba 2473
2474 /* change login name, set pobox */
711660a5 2475 sprintf(buffer, "u.users_id = %d", users_id);
2476 incremental_before("users", buffer, 0);
822a6eba 2477## repeat replace u (#login = @login, status = 2, modtime = "now",
2478## modby = @who, modwith = @entity, potype="POP",
2479## pop_id = @mid, pmodtime="now", pmodby=@who,
2480## pmodwith=@entity)
2481## where u.#users_id = @users_id
8ac9ee7a 2482## inquire_equel(rowcount = "rowcount");
02ccf7ad 2483 if (ingres_errno) return(sms_errcode);
822a6eba 2484 if (rowcount != 1)
2485 return(SMS_INTERNAL);
2486 set_pop_usage(mid, 1);
2487 com_err(whoami, 0, "set login name to %s and pobox to %s", login,
711660a5 2488 strtrim(machname));
2489 incremental_after("users", buffer, 0);
822a6eba 2490
2491 /* create group list */
2492 if (set_next_object_id("gid", "list"))
44bd6f44 2493 return(SMS_NO_ID);
822a6eba 2494 if (set_next_object_id("list_id", "list"))
44bd6f44 2495 return(SMS_NO_ID);
822a6eba 2496## repeat retrieve (list_id = values.value) where values.name = "list_id"
02ccf7ad 2497 if (ingres_errno) return(sms_errcode);
8ac9ee7a 2498## inquire_equel(rowcount = "rowcount");
822a6eba 2499 if (rowcount != 1)
2500 return(SMS_INTERNAL);
711660a5 2501 incremental_clear_before();
822a6eba 2502## repeat append list (name = @login, #list_id = @list_id, active = 1,
2503## public = 0, hidden = 0, maillist = 0, group = 1,
2504## #gid = values.value, desc = "User Group",
2505## acl_type = "USER", acl_id = @users_id, modtime = "now",
2506## modby = @who, modwith = @entity)
2507## where values.name = "gid"
02ccf7ad 2508 if (ingres_errno) return(sms_errcode);
8ac9ee7a 2509## inquire_equel(rowcount = "rowcount");
44bd6f44 2510 if (rowcount != 1)
2511 return(SMS_INTERNAL);
711660a5 2512 sprintf(buffer, "l.list_id = %d", list_id);
2513 incremental_after("list", buffer, 0);
2514 aargv[0] = (char *) list_id;
2515 aargv[1] = "USER";
2516 aargv[2] = (char *) users_id;
2517 incremental_clear_before();
a6683dad 2518## repeat append imembers (#list_id = @list_id, member_type = "USER",
2519## member_id = @users_id, ref_count = 1, direct = 1)
02ccf7ad 2520 if (ingres_errno) return(sms_errcode);
8ac9ee7a 2521## inquire_equel(rowcount = "rowcount");
822a6eba 2522 if (rowcount != 1)
2523 return(SMS_INTERNAL);
60610bc7 2524 incremental_after("members", 0, aargv);
822a6eba 2525 com_err(whoami, 0, "group list created");
2526
2527 /* decide where to put filesystem */
2528 maxsize = 0;
2529 directory = NULL;
2530## repeat retrieve (mid = n.mach_id, dir = trim(n.#dir), nid = n.nfsphys_id,
2531## flag = n.status, size = n.#size, alloc = n.allocated) {
2532 if ((flag & utype) && (size != 0) && (size - alloc > maxsize)) {
2533 maxsize = size - alloc;
2534 if (directory)
2535 free(directory);
2536 directory = strsave(dir);
2537 pid = nid;
2538 m_id = mid;
2539 }
a6cb4d4c 2540## }
02ccf7ad 2541 if (ingres_errno) return(sms_errcode);
822a6eba 2542 if (maxsize == 0)
44bd6f44 2543 return(SMS_NO_FILESYS);
822a6eba 2544
2545 /* create filesystem */
2546 if (set_next_object_id("filsys_id", "filesys"))
44bd6f44 2547 return(SMS_NO_ID);
711660a5 2548 incremental_clear_before();
822a6eba 2549## repeat append filesys (filsys_id = values.value, phys_id = @pid,
2550## label = @login, type = "NFS", mach_id = @m_id,
4f16dc86 2551## name = @directory + "/" + @login,
2552## mount = "/mit/" + @login,
822a6eba 2553## access = "w", comments = "User Locker",
2554## owner = @users_id, owners = @list_id, createflg = 1,
2555## lockertype = "HOMEDIR", modtime = "now",
2556## modby = @who, modwith = @entity)
2557## where values.name = "filsys_id"
02ccf7ad 2558 if (ingres_errno) return(sms_errcode);
8ac9ee7a 2559## inquire_equel(rowcount = "rowcount");
822a6eba 2560 if (rowcount != 1)
2561 return(SMS_INTERNAL);
711660a5 2562 incremental_after("filesys",
2563 "fs.filsys_id = values.value and values.name = \"filsys_id\"",
2564 0);
822a6eba 2565 com_err(whoami, 0, "filesys created on mach %d in %s/%s", m_id,
4f16dc86 2566 directory, login);
822a6eba 2567
2568 /* set quota */
2569## repeat retrieve (quota = values.value) where values.name = "def_quota"
02ccf7ad 2570 if (ingres_errno) return(sms_errcode);
8ac9ee7a 2571## inquire_equel(rowcount = "rowcount");
822a6eba 2572 if (rowcount != 1)
44bd6f44 2573 return(SMS_NO_QUOTA);
711660a5 2574 incremental_clear_before();
822a6eba 2575## repeat append nfsquota (#users_id = @users_id, filsys_id = values.value,
e7fa3293 2576## #quota = @quota, phys_id = @pid, modtime = "now",
2577## modby = @who, modwith = @entity)
822a6eba 2578## where values.name = "filsys_id"
02ccf7ad 2579 if (ingres_errno) return(sms_errcode);
8ac9ee7a 2580## inquire_equel(rowcount = "rowcount");
822a6eba 2581 if (rowcount != 1)
2582 return(SMS_INTERNAL);
2583## repeat replace nfsphys (allocated = nfsphys.allocated + @quota)
2584## where nfsphys.nfsphys_id = filesys.#phys_id and
2585## filesys.filsys_id = values.value and values.name = "filsys_id"
02ccf7ad 2586 if (ingres_errno) return(sms_errcode);
8ac9ee7a 2587## inquire_equel(rowcount = "rowcount");
822a6eba 2588 if (rowcount != 1)
2589 return(SMS_INTERNAL);
711660a5 2590 aargv[0] = login;
2591 aargv[1] = login;
2592 sprintf(buffer, "nq.users_id = %d and nq.filsys_id = values.value and values.name = \"filsys_id\"", users_id);
60610bc7 2593 incremental_after("nfsquota", buffer, aargv);
822a6eba 2594 com_err(whoami, 0, "quota of %d assigned", quota);
02ccf7ad 2595 if (ingres_errno) return(sms_errcode);
822a6eba 2596
cc588c08 2597 cache_entry(login, "USER", users_id);
2598
4f16dc86 2599## repeat replace tblstats (updates = tblstats.updates + 1, modtime = "now")
2600## where tblstats.table = "users"
2601## repeat replace tblstats (appends = tblstats.appends + 1, modtime = "now")
2602## where tblstats.table = "list" or tblstats.table = "filesys" or
2603## tblstats.table = "nfsquota"
02ccf7ad 2604 if (ingres_errno) return(sms_errcode);
822a6eba 2605 return(SMS_SUCCESS);
2606##}
2607
2608
2609
2610/** set_pop_usage - incr/decr usage count for pop server in serverhosts talbe
2611 **
2612 ** Inputs:
2613 ** id of machine
2614 ** delta (will be +/- 1)
2615 **
2616 ** Description:
2617 ** - incr/decr value field in serverhosts table for pop/mach_id
2618 **
2619 **/
2620
2621static int set_pop_usage(id, count)
2622int id;
2623int count;
2624##{
2625## int mach_id = id;
2626## int n = count;
2627
cc588c08 2628## repeat replace serverhosts (value1 = serverhosts.value1 + @n)
2629## where serverhosts.service = "POP" and serverhosts.#mach_id = @mach_id
a6cb4d4c 2630
02ccf7ad 2631 if (ingres_errno) return(sms_errcode);
a6cb4d4c 2632 return(SMS_SUCCESS);
2633##}
822a6eba 2634
2635
c2408bd5 2636\f
05cdd922 2637/* Validation Routines */
2638
2639validate_row(q, argv, v)
2640 register struct query *q;
2641 char *argv[];
2642 register struct validate *v;
2643##{
2644## char *rvar;
2645## char *table;
2646## char *name;
2647## char qual[128];
2648## int rowcount;
2649
2650 /* build where clause */
2651 build_qual(v->qual, v->argc, argv, qual);
2652
2653 /* setup ingres variables */
2654 rvar = q->rvar;
2655 table = q->rtable;
2656 name = v->field;
2657
6388c51a 2658 if (log_flags & LOG_VALID)
b4182127 2659 /* tell the logfile what we're doing */
2660 com_err(whoami, 0, "validating row: %s", qual);
2661
05cdd922 2662 /* look for the record */
2663## range of rvar is table
2664## retrieve (rowcount = count(rvar.name where qual))
e1795ce1 2665 if (ingres_errno) return(sms_errcode);
05cdd922 2666 if (rowcount == 0) return(SMS_NO_MATCH);
2667 if (rowcount > 1) return(SMS_NOT_UNIQUE);
2668 return(SMS_EXISTS);
2669##}
2670
2671validate_fields(q, argv, vo, n)
2672 struct query *q;
2673 register char *argv[];
2674 register struct valobj *vo;
2675 register int n;
2676{
2677 register int status;
05cdd922 2678
2679 while (--n >= 0) {
2680 switch (vo->type) {
2681 case V_NAME:
6388c51a 2682 if (log_flags & LOG_VALID)
b4182127 2683 com_err(whoami, 0, "validating %s in %s: %s",
05cdd922 2684 vo->namefield, vo->table, argv[vo->index]);
05cdd922 2685 status = validate_name(argv, vo);
2686 break;
2687
2688 case V_ID:
6388c51a 2689 if (log_flags & LOG_VALID)
b4182127 2690 com_err(whoami, 0, "validating %s in %s: %s",
05cdd922 2691 vo->idfield, vo->table, argv[vo->index]);
05cdd922 2692 status = validate_id(argv, vo);
2693 break;
2694
92a943d6 2695 case V_DATE:
6388c51a 2696 if (log_flags & LOG_VALID)
92a943d6 2697 com_err(whoami, 0, "validating date: %s", argv[vo->index]);
2698 status = validate_date(argv, vo);
2699 break;
2700
05cdd922 2701 case V_TYPE:
6388c51a 2702 if (log_flags & LOG_VALID)
b4182127 2703 com_err(whoami, 0, "validating %s type: %s",
05cdd922 2704 vo->table, argv[vo->index]);
05cdd922 2705 status = validate_type(argv, vo);
2706 break;
2707
2708 case V_TYPEDATA:
6388c51a 2709 if (log_flags & LOG_VALID)
92a943d6 2710 com_err(whoami, 0, "validating typed data (%s): %s",
2711 argv[vo->index - 1], argv[vo->index]);
05cdd922 2712 status = validate_typedata(q, argv, vo);
2713 break;
2714
822a6eba 2715 case V_RENAME:
6388c51a 2716 if (log_flags & LOG_VALID)
822a6eba 2717 com_err(whoami, 0, "validating rename %s in %s",
2718 argv[vo->index], vo->table);
2719 status = validate_rename(argv, vo);
2720 break;
2721
2722 case V_CHAR:
6388c51a 2723 if (log_flags & LOG_VALID)
822a6eba 2724 com_err(whoami, 0, "validating chars: %s", argv[vo->index]);
2725 status = validate_chars(argv[vo->index]);
05cdd922 2726 break;
2727
92a943d6 2728 case V_SORT:
2729 status = SMS_EXISTS;
2730 break;
2731
e1795ce1 2732 case V_LOCK:
2733 status = lock_table(vo);
2734 break;
05cdd922 2735 }
2736
2737 if (status != SMS_EXISTS) return(status);
2738 vo++;
2739 }
2740
02ccf7ad 2741 if (ingres_errno) return(sms_errcode);
05cdd922 2742 return(SMS_SUCCESS);
2743}
2744
822a6eba 2745
2746/* validate_chars: verify that there are no illegal characters in
2747 * the string. Legal characters are printing chars other than
331b982e 2748 * ", *, ?, \, [ and ].
822a6eba 2749 */
2750static int illegalchars[] = {
2751 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* ^@ - ^O */
2752 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* ^P - ^_ */
2753 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, /* SPACE - / */
2754 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, /* 0 - ? */
2755 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* @ - O */
331b982e 2756 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, /* P - _ */
822a6eba 2757 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* ` - o */
2758 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, /* p - ^? */
2759 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2760 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2761 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2762 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2763 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2764 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2765 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2766 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2767};
2768
2769validate_chars(s)
2770register char *s;
2771{
2772 while (*s)
2773 if (illegalchars[*s++])
2774 return(SMS_BAD_CHAR);
2775 return(SMS_EXISTS);
2776}
2777
2778
05cdd922 2779validate_id(argv, vo)
2780 char *argv[];
2781 register struct valobj *vo;
2782##{
2783## char *name;
2784## char *table;
2785## char *namefield;
2786## char *idfield;
cc588c08 2787## int id, rowcount;
2788 int status;
122ec372 2789 register char *c;
05cdd922 2790
cc588c08 2791
05cdd922 2792 name = argv[vo->index];
2793 table = vo->table;
2794 namefield = vo->namefield;
2795 idfield = vo->idfield;
cc588c08 2796
2797 if ((!strcmp(table, "users") && !strcmp(namefield, "login")) ||
2798 !strcmp(table, "machine") ||
2799 !strcmp(table, "filesys") ||
2800 !strcmp(table, "list") ||
2801 !strcmp(table, "cluster") ||
2802 !strcmp(table, "string")) {
2803 if (!strcmp(table, "machine"))
2804 for (c = name; *c; c++) if (islower(*c)) *c = toupper(*c);
2805 status = name_to_id(name, table, &id);
2806 if (status == 0) {
2807 *(int *)argv[vo->index] = id;
2808 return(SMS_EXISTS);
2809 } else if (status == SMS_NO_MATCH || status == SMS_NOT_UNIQUE)
2810 return(vo->error);
2811 else
2812 return(status);
2813 }
2814
822a6eba 2815 if (!strcmp(namefield, "uid")) {
9119288e 2816## retrieve (id = table.idfield) where table.namefield = int4(name)
e1795ce1 2817 if (ingres_errno) return(sms_errcode);
9119288e 2818## inquire_equel (rowcount = "rowcount")
2819 } else {
2820## retrieve (id = table.idfield) where table.namefield = name
e1795ce1 2821 if (ingres_errno) return(sms_errcode);
9119288e 2822## inquire_equel (rowcount = "rowcount")
2823 }
05cdd922 2824 if (rowcount != 1) return(vo->error);
2825 *(int *)argv[vo->index] = id;
2826 return(SMS_EXISTS);
2827##}
2828
2829validate_name(argv, vo)
2830 char *argv[];
2831 register struct valobj *vo;
2832##{
2833## char *name;
2834## char *table;
2835## char *namefield;
2836## int rowcount;
44bd6f44 2837 register char *c;
05cdd922 2838
2839 name = argv[vo->index];
2840 table = vo->table;
2841 namefield = vo->namefield;
44bd6f44 2842 if (!strcmp(table, "servers") && !strcmp(namefield, "name")) {
2843 for (c = name; *c; c++)
2844 if (islower(*c))
2845 *c = toupper(*c);
2846 }
05cdd922 2847## retrieve (rowcount = countu(table.namefield
2848## where table.namefield = name))
e1795ce1 2849 if (ingres_errno) return(sms_errcode);
05cdd922 2850 return ((rowcount == 1) ? SMS_EXISTS : vo->error);
2851##}
2852
92a943d6 2853validate_date(argv, vo)
2854 char *argv[];
2855 struct valobj *vo;
2856##{
2857## char *idate;
2858## double dd;
2859## int errorno;
2860
2861 idate = argv[vo->index];
2862
2863## retrieve (dd = interval("years", date(idate) - date("today")))
2864## inquire_equel (errorno = "errorno")
2865 if (errorno != 0 || dd > 5.0) return(SMS_DATE);
44bd6f44 2866 return(SMS_EXISTS);
92a943d6 2867##}
2868
822a6eba 2869
2870validate_rename(argv, vo)
2871char *argv[];
2872struct valobj *vo;
2873##{
2874## char *name, *table, *namefield, *idfield;
2875## int id;
cc588c08 2876 int status;
822a6eba 2877 register char *c;
2878
2879 c = name = argv[vo->index];
2880 while (*c)
2881 if (illegalchars[*c++])
2882 return(SMS_BAD_CHAR);
2883 table = vo->table;
2884 /* minor kludge to upcasify machine names */
2885 if (!strcmp(table, "machine"))
2886 for (c = name; *c; c++) if (islower(*c)) *c = toupper(*c);
2887 namefield = vo->namefield;
2888 idfield = vo->idfield;
2889 id = -1;
2890 if (idfield == 0) {
2891 if (!strcmp(argv[vo->index], argv[vo->index - 1]))
2892 return(SMS_EXISTS);
2893## retrieve (id = any(table.namefield where table.namefield = name))
e1795ce1 2894 if (ingres_errno) return(sms_errcode);
822a6eba 2895 if (id)
2896 return(vo->error);
2897 else
2898 return(SMS_EXISTS);
2899 }
cc588c08 2900 status = name_to_id(name, table, &id);
2901 if (status == SMS_NO_MATCH || id == *(int *)argv[vo->index - 1])
822a6eba 2902 return(SMS_EXISTS);
2903 else
2904 return(vo->error);
2905##}
2906
2907
05cdd922 2908validate_type(argv, vo)
2909 char *argv[];
2910 register struct valobj *vo;
2911##{
2912## char *typename;
2913## char *value;
822a6eba 2914## int exists;
05cdd922 2915 register char *c;
2916
2917 typename = vo->table;
822a6eba 2918 c = value = argv[vo->index];
2919 while (*c)
2920 if (illegalchars[*c++])
2921 return(SMS_BAD_CHAR);
05cdd922 2922
2923 /* uppercase type fields */
2924 for (c = value; *c; c++) if (islower(*c)) *c = toupper(*c);
2925
cc588c08 2926## repeat retrieve (exists = any(alias.trans where alias.name = @typename and
2927## alias.type = "TYPE" and alias.trans = @value))
e1795ce1 2928 if (ingres_errno) return(sms_errcode);
822a6eba 2929 return (exists ? SMS_EXISTS : vo->error);
05cdd922 2930##}
2931
2932/* validate member or type-specific data field */
2933
2934validate_typedata(q, argv, vo)
2935 register struct query *q;
2936 register char *argv[];
2937 register struct valobj *vo;
2938##{
2939## char *name;
2940## char *field_type;
822a6eba 2941## char data_type[129];
cc588c08 2942## int id, rowcount;
2943 int status;
822a6eba 2944 char *index();
a6cb4d4c 2945 register char *c;
05cdd922 2946
2947 /* get named object */
2948 name = argv[vo->index];
2949
2950 /* get field type string (known to be at index-1) */
2951 field_type = argv[vo->index-1];
2952
2953 /* get corresponding data type associated with field type name */
2954## repeat retrieve (data_type = alias.trans)
2955## where alias.#name = @field_type and alias.type = "TYPEDATA"
e1795ce1 2956 if (ingres_errno) return(sms_errcode);
05cdd922 2957## inquire_equel (rowcount = "rowcount")
2958 if (rowcount != 1) return(SMS_TYPE);
2959
2960 /* now retrieve the record id corresponding to the named object */
822a6eba 2961 if (index(data_type, ' '))
2962 *index(data_type, ' ') = 0;
05cdd922 2963 if (!strcmp(data_type, "user")) {
2964 /* USER */
cc588c08 2965 status = name_to_id(name, data_type, &id);
2966 if (status && (status == SMS_NO_MATCH || status == SMS_NOT_UNIQUE))
2967 return(SMS_USER);
2968 if (status) return(status);
05cdd922 2969 } else if (!strcmp(data_type, "list")) {
2970 /* LIST */
cc588c08 2971 status = name_to_id(name, data_type, &id);
2972 if (status && status == SMS_NOT_UNIQUE)
2973 return(SMS_LIST);
2974 if (status == SMS_NO_MATCH) {
822a6eba 2975 /* if idfield is non-zero, then if argv[0] matches the string
2976 * that we're trying to resolve, we should get the value of
2977 * values.[idfield] for the id.
2978 */
2979 if (vo->idfield && !strcmp(argv[0], argv[vo->index])) {
4f16dc86 2980 set_next_object_id(q->validate->object_id, q->rtable);
822a6eba 2981 name = vo->idfield;
4f16dc86 2982## repeat retrieve (id = values.value) where values.#name = @name
822a6eba 2983## inquire_equel(rowcount = "rowcount")
2984 if (rowcount != 1) return(SMS_LIST);
2985 } else
2986 return(SMS_LIST);
cc588c08 2987 } else if (status) return(status);
05cdd922 2988 } else if (!strcmp(data_type, "machine")) {
2989 /* MACHINE */
a6cb4d4c 2990 for (c = name; *c; c++) if (islower(*c)) *c = toupper(*c);
cc588c08 2991 status = name_to_id(name, data_type, &id);
2992 if (status && (status == SMS_NO_MATCH || status == SMS_NOT_UNIQUE))
2993 return(SMS_MACHINE);
2994 if (status) return(status);
05cdd922 2995 } else if (!strcmp(data_type, "string")) {
2996 /* STRING */
cc588c08 2997 status = name_to_id(name, data_type, &id);
2998 if (status && status == SMS_NOT_UNIQUE)
2999 return(SMS_STRING);
3000 if (status == SMS_NO_MATCH) {
49189928 3001 if (q->type != APPEND && q->type != UPDATE) return(SMS_STRING);
cc588c08 3002## retrieve (id = values.value) where values.#name = "strings_id"
05cdd922 3003 id++;
cc588c08 3004## replace values (value = id) where values.#name = "strings_id"
822a6eba 3005## append to strings (string_id = id, string = name)
cc588c08 3006 } else if (status) return(status);
822a6eba 3007 } else if (!strcmp(data_type, "none")) {
3008 id = 0;
05cdd922 3009 } else {
3010 return(SMS_TYPE);
3011 }
3012
3013 /* now set value in argv */
3014 *(int *)argv[vo->index] = id;
3015
3016 return (SMS_EXISTS);
3017##}
3018
05cdd922 3019
e1795ce1 3020/* Lock the table named by the validation object */
3021
3022lock_table(vo)
3023struct valobj *vo;
3024##{
3025## char *table, *idfield;
3026## int rowcount;
3027
3028 table = vo->table;
3029 idfield = vo->idfield;
3030## replace table (modtime = "now") where table.idfield = 0
3031 if (ingres_errno) return(sms_errcode);
3032## inquire_equel (rowcount = "rowcount")
3033 if (rowcount != 1)
3034 return(vo->error);
3035 else
3036 return(SMS_EXISTS);
3037##}
3038
3039
822a6eba 3040/* Check the database at startup time. For now this just resets the
3041 * inprogress flags that the DCM uses.
3042 */
05cdd922 3043
822a6eba 3044sanity_check_database()
3045##{
05cdd922 3046##}
This page took 0.57617 seconds and 5 git commands to generate.