6 * Copyright (C) 1987 by the Massachusetts Institute of Technology
7 * For copying and distribution information, please see the file
13 static char *rcsid_qsupport_qc = "$Header$";
16 #include <mit-copyright.h>
18 #include "mr_server.h"
22 extern char *whoami, *strsave();
23 extern int ingres_errno, mr_errcode;
26 /* Specialized Access Routines */
28 /* access_user - verify that client name equals specified login name
30 * - since field validation routines are called first, a users_id is
31 * now in argv[0] instead of the login name.
34 access_user(q, argv, cl)
39 if (cl->users_id != *(int *)argv[0])
47 /* access_login - verify that client name equals specified login name
49 * argv[0...n] contain search info. q->
52 access_login(q, argv, cl)
60 build_qual(q->qual, q->argc, argv, qual);
61 ## range of u is users
62 ## retrieve (id = u.users_id) where qual
63 ## inquire_equel(rowcount = "rowcount")
64 if (rowcount != 1 || id != cl->users_id)
72 /* access_list - check access for most list operations
74 * Inputs: argv[0] - list_id
76 * argv[2] - member ID (only for queries "amtl" and "dmfl")
77 * argv[7] - group IID (only for query "ulis")
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
85 access_list(q, argv, cl)
90 ## int list_id, acl_id, flags, rowcount, gid;
93 int client_id, status;
95 list_id = *(int *)argv[0];
96 ## repeat retrieve (acl_id = list.#acl_id, acl_type = list.#acl_type,
97 ## gid = list.#gid, flags = list.#public)
98 ## where list.#list_id = @list_id
99 ## inquire_equel(rowcount = "rowcount")
103 /* parse client structure */
104 if ((status = get_client(cl, &client_type, &client_id)) != MR_SUCCESS)
107 /* if amtl or dmfl and list is public allow client to add or delete self */
108 if (((!strcmp("amtl", q->shortname) && flags) ||
109 (!strcmp("dmfl", q->shortname))) &&
110 (!strcmp("USER", argv[1]))) {
111 if (*(int *)argv[2] == client_id) return(MR_SUCCESS);
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]))))
119 /* check for client in access control list */
120 status = find_member(acl_type, acl_id, client_type, client_id, 0);
121 if (!status) return(MR_PERM);
127 /* access_visible_list - allow access to list only if it is not hidden,
128 * or if the client is on the ACL
130 * Inputs: argv[0] - list_id
131 * cl - client identifier
134 access_visible_list(q, argv, cl)
139 ## int list_id, acl_id, flags, rowcount;
142 int client_id, status;
144 list_id = *(int *)argv[0];
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")
154 /* parse client structure */
155 if ((status = get_client(cl, &client_type, &client_id)) != MR_SUCCESS)
158 /* check for client in access control list */
159 status = find_member(acl_type, acl_id, client_type, client_id, 0);
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
170 * Inputs: argv[0] - list name
171 * cl - client identifier
174 access_vis_list_by_name(q, argv, cl)
179 ## int acl_id, flags, rowcount;
180 ## char acl_type[9], *listname;
182 int client_id, status;
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");
195 /* parse client structure */
196 if ((status = get_client(cl, &client_type, &client_id)) != MR_SUCCESS)
199 /* check for client in access control list */
200 status = find_member(acl_type, acl_id, client_type, client_id, 0);
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.
213 access_member(q, argv, cl)
218 if (!strcmp(argv[0], "LIST") || !strcmp(argv[0], "RLIST"))
219 return(access_visible_list(q, &argv[1], cl));
221 if (!strcmp(argv[0], "USER") || !strcmp(argv[0], "RUSER")) {
222 if (cl->users_id == *(int *)argv[1])
230 /* access_qgli - special access routine for Qualified_get_lists. Allows
231 * access iff argv[0] == "TRUE" and argv[2] == "FALSE".
234 access_qgli(q, argv, cl)
239 if (!strcmp(argv[0], "TRUE") && !strcmp(argv[2], "FALSE"))
245 /* access_service - allow access if user is on ACL of service. Don't
246 * allow access if a wildcard is used.
249 access_service(q, argv, cl)
254 ## int acl_id, rowcount;
255 ## char *name, acl_type[9];
256 int client_id, status;
260 ## repeat retrieve (acl_id = servers.#acl_id, acl_type = servers.#acl_type)
261 ## where servers.#name = uppercase(@name)
262 ## inquire_equel(rowcount = "rowcount")
266 /* parse client structure */
267 if ((status = get_client(cl, &client_type, &client_id)) != MR_SUCCESS)
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(MR_PERM);
279 /* access_filesys - verify that client is owner or on owners list of filesystem
283 access_filesys(q, argv, cl)
288 ## int rowcount, users_id, list_id;
290 int status, client_id;
294 ## repeat retrieve (users_id = filesys.owner, list_id = filesys.owners)
295 ## where filesys.label = @name
296 ## inquire_equel(rowcount = "rowcount")
300 if (users_id == cl->users_id)
302 if ((status = get_client(cl, &client_type, &client_id)) != MR_SUCCESS)
304 status = find_member("LIST", list_id, client_type, client_id, 0);
315 /* Setup routine for add_user
317 * Inputs: argv[0] - login
322 * - if argv[1] == UNIQUE_UID then set argv[1] = next(uid)
323 * - if argv[0] == UNIQUE_LOGIN then set argv[0] = "#<uid>"
326 setup_ausr(q, argv, cl)
328 register char *argv[];
331 ## int nuid, rowcount;
334 mit_id = argv[U_MITID];
335 ## retrieve (rowcount = any(u.#mit_id where u.#mit_id = mit_id))
336 if (ingres_errno) return(mr_errcode);
337 if (rowcount) return(MR_EXISTS);
339 if (!strcmp(argv[1], UNIQUE_UID) || atoi(argv[1]) == -1) {
340 if (set_next_object_id("uid", "users"))
341 return(MR_INGRES_ERR);
342 ## repeat retrieve (nuid = values.value) where values.name = "uid"
343 ## inquire_equel(rowcount = "rowcount")
346 sprintf(argv[1], "%d", nuid);
349 if (!strcmp(argv[0], UNIQUE_LOGIN) || atoi(argv[1]) == -1) {
350 sprintf(argv[0], "#%s", argv[1]);
357 /* setup_dusr - verify that the user is no longer being referenced
358 * and may safely be deleted.
361 int setup_dusr(q, argv)
367 id = *(int *)argv[0];
369 /* For now, only allow users to be deleted if their status is 0 */
370 ## repeat retrieve (flag = u.status) where u.users_id = @id
371 if (flag != 0 && flag != 4)
374 ## repeat delete quota where quota.entity_id = @id and quota.type = "USER"
375 ## repeat delete krbmap where krbmap.users_id = @id
376 ## repeat retrieve (flag = any(imembers.member_id where imembers.member_id=@id
377 ## and imembers.member_type = "USER"))
380 ## repeat retrieve (flag = any(filesys.label where filesys.owner=@id))
383 ## repeat retrieve (flag = any(list.name where list.acl_id=@id and
384 ## list.acl_type = "USER"))
387 ## repeat retrieve (flag = any(servers.name where servers.acl_id=@id and
388 ## servers.acl_type = "USER"))
391 ## repeat retrieve (flag=any(hostaccess.acl_id where hostaccess.acl_id=@id and
392 ## hostaccess.acl_type = "USER"))
401 /* setup_spop: verify that there is already a valid POP machine_id in the
402 * pop_id field. Also take care of keeping track of the post office usage.
404 int setup_spop(q, argv)
408 ## int id, mid, flag;
411 id = *(int *)argv[0];
412 ## repeat retrieve (type = u.potype, mid = u.pop_id,
413 ## flag = any(machine.name where machine.mach_id = u.pop_id
414 ## and u.pop_id != 0 and u.users_id = @id))
415 ## where u.users_id = @id
418 if (strcmp(strtrim(type), "POP"))
419 set_pop_usage(mid, 1);
424 /* setup_dpob: Take care of keeping track of the post office usage.
426 int setup_dpob(q, argv)
433 user = *(int *)argv[0];
434 ## repeat retrieve (type = u.potype, id = u.pop_id)
435 ## where u.users_id = @user
436 if (ingres_errno) return(mr_errcode);
438 if (!strcmp(strtrim(type), "POP"))
439 set_pop_usage(id, -1);
444 /* setup_dmac - verify that the machine is no longer being referenced
445 * and may safely be deleted.
448 int setup_dmac(q, argv)
454 id = *(int *)argv[0];
455 ## repeat retrieve (flag = any(users.login where users.potype = "POP"
456 ## and users.pop_id=@id))
459 ## repeat retrieve (flag = any(serverhosts.mach_id
460 ## where serverhosts.mach_id=@id))
463 ## repeat retrieve (flag = any(nfsphys.mach_id where nfsphys.mach_id=@id))
466 ## repeat retrieve (flag = any(hostaccess.mach_id where hostaccess.mach_id=@id))
469 ## repeat retrieve (flag = any(printcap.mach_id where printcap.mach_id=@id))
472 ## repeat retrieve (flag = any(printcap.quotaserver where printcap.quotaserver=@id))
475 ## repeat retrieve (flag = any(palladium.mach_id where palladium.mach_id=@id))
479 ## repeat delete mcmap where mcmap.mach_id = @id
480 if (ingres_errno) return(mr_errcode);
485 /* setup_dclu - verify that the cluster is no longer being referenced
486 * and may safely be deleted.
489 int setup_dclu(q, argv)
495 id = *(int *)argv[0];
496 ## repeat retrieve (flag = any(mcmap.mach_id where mcmap.clu_id=@id))
499 ## repeat retrieve (flag = any(svc.clu_id where svc.clu_id=@id))
508 /* setup_alis - if argv[5] is non-zero and argv[6] is UNIQUE_ID, then allocate
509 * a new gid and put it in argv[6]. Otherwise if argv[6] is UNIQUE_ID but
510 * argv[5] is not, then remember that UNIQUE_ID is being stored by putting
511 * a -1 there. Remember that this is also used for ulis, with the indexes
515 int setup_alis(q, argv)
523 if (!strcmp(q->shortname, "alis"))
525 else if (!strcmp(q->shortname, "ulis"))
528 if (!strcmp(argv[idx], UNIQUE_GID) || atoi(argv[idx]) == -1) {
529 if (atoi(argv[idx - 1])) {
530 if (set_next_object_id("gid", "list"))
531 return(MR_INGRES_ERR);
532 ## repeat retrieve (ngid = values.value) where values.name = "gid"
533 if (ingres_errno) return(mr_errcode);
534 sprintf(argv[idx], "%d", ngid);
536 strcpy(argv[idx], "-1");
544 /* setup_dlist - verify that the list is no longer being referenced
545 * and may safely be deleted.
548 int setup_dlis(q, argv)
554 id = *(int *)argv[0];
555 ## repeat retrieve (flag = any(imembers.member_id where imembers.member_id=@id
556 ## and imembers.member_type = "LIST"))
559 ## repeat retrieve (flag = any(imembers.member_id where imembers.list_id=@id))
562 ## repeat retrieve (flag = any(filesys.label where filesys.owners=@id))
565 ## repeat retrieve (flag = any(capacls.tag where capacls.list_id=@id))
568 ## repeat retrieve (flag = any(list.name where list.acl_id=@id and
569 ## list.acl_type = "LIST" and list.list_id != @id))
572 ## repeat retrieve (flag = any(servers.name where servers.acl_id=@id and
573 ## servers.acl_type = "LIST"))
576 ## repeat retrieve (flag = any(quota.entity_id where quota.entity_id=@id and
577 ## quota.type = "GROUP"))
580 ## repeat retrieve (flag=any(hostaccess.acl_id where hostaccess.acl_id=@id and
581 ## hostaccess.acl_type = "LIST"))
584 ## repeat retrieve (flag = any(zephyr.class
585 ## where zephyr.xmt_type = "LIST" and zephyr.xmt_id = @id or
586 ## zephyr.sub_type = "LIST" and zephyr.sub_id = @id or
587 ## zephyr.iws_type = "LIST" and zephyr.iws_id = @id or
588 ## zephyr.iui_type = "LIST" and zephyr.iui_id = @id))
597 /* setup_dsin - verify that the service is no longer being referenced
598 * and may safely be deleted.
601 int setup_dsin(q, argv)
609 ## repeat retrieve (flag = any(serverhosts.service
610 ## where serverhosts.service=uppercase(@name)))
613 ## repeat retrieve (flag = servers.inprogress) where servers.#name = @name
622 /* setup_dshi - verify that the service-host is no longer being referenced
623 * and may safely be deleted.
626 int setup_dshi(q, argv)
634 id = *(int *)argv[1];
635 ## repeat retrieve (flag=serverhosts.inprogress)
636 ## where serverhosts.service=uppercase(@name) and serverhosts.mach_id=@id
646 ** setup_add_filesys - verify existance of referenced file systems
658 ** * extract directory prefix from name
659 ** * verify mach_id/dir in nfsphys
660 ** * verify access in {r, w, R, W}
662 ** Side effect: sets variable var_phys_id to the ID of the physical
663 ** filesystem (nfsphys_id for NFS, 0 for RVD)
666 ** MR_NFS - specified directory not exported
667 ** MR_FILESYS_ACCESS - invalid filesys access
671 ##static int var_phys_id;
680 ## char ftype[32], *access;
683 mach_id = *(int *)argv[2];
688 sprintf(ftype, "fs_access_%s", type);
689 ## retrieve (ok = any(alias.trans where alias.name = ftype and
690 ## alias.type = "TYPE" and alias.trans = access))
691 if (ingres_errno) return(mr_errcode);
692 if (ok == 0) return(MR_FILESYS_ACCESS);
694 if (!strcmp(type, "NFS"))
695 return (check_nfs(mach_id, name, access));
701 /* Verify the arguments, depending on the FStype. Also, if this is an
702 * NFS filesystem, then update any quotas for that filesystem to reflect
706 setup_ufil(q, argv, cl)
713 ## int fid, total, who;
714 ## char *entity, ftype[32], *access;
717 mach_id = *(int *)argv[3];
721 fid = *(int *)argv[0];
725 sprintf(ftype, "fs_access_%s", type);
726 ## retrieve (total = any(alias.trans where alias.name = ftype and
727 ## alias.type = "TYPE" and alias.trans = access))
728 if (ingres_errno) return(mr_errcode);
729 if (total == 0) return(MR_FILESYS_ACCESS);
731 if (!strcmp(type, "NFS")) {
732 status = check_nfs(mach_id, name, access);
733 ## replace quota (phys_id = var_phys_id) where quota.filsys_id = fid
734 if (ingres_errno) return(mr_errcode);
736 } else if (!strcmp(type, "AFS")) {
738 ## retrieve (total = sum(quota.quota where quota.filsys_id = fid
739 ## and quota.phys_id != 0))
740 if (ingres_errno) return(mr_errcode);
742 ## append quota (quota = total, filsys_id = fid,
743 ## phys_id = 0, entity_id = 0, type = "ANY",
744 ## modtime = "now", modby = who, modwith = entity)
745 if (ingres_errno) return(mr_errcode);
748 ## replace quota (phys_id = 0) where quota.filsys_id = fid
749 if (ingres_errno) return(mr_errcode);
755 /* Find the NFS physical partition that the named directory is on.
756 * This is done by comparing the dir against the mount point of the
757 * partition. To make sure we get the correct match when there is
758 * more than one, we sort the query in reverse order by dir name.
761 ##check_nfs(mach_id, name, access)
773 ## range of np is nfsphys
774 ## repeat retrieve (var_phys_id = np.#nfsphys_id, dir = trim(np.#dir))
775 ## where np.#mach_id = @mach_id sort by #dir:d {
779 if (*cp1++ != *cp2) break;
793 /* setup_dfil: free any quota records and fsgroup info associated with
794 * a filesystem when it is deleted. Also adjust the allocation numbers.
797 setup_dfil(q, argv, cl)
804 id = *(int *)argv[0];
805 ## range of q is quota
806 ## range of n is nfsphys
807 ## repeat replace n (allocated=n.allocated-sum(q.quota where q.filsys_id=@id))
808 ## where n.nfsphys_id = filesys.phys_id and filesys.filsys_id = @id
810 ## repeat delete q where q.filsys_id = @id
811 ## repeat delete fsgroup where fsgroup.filsys_id = @id
812 ## repeat delete fsgroup where fsgroup.group_id = @id
813 if (ingres_errno) return(mr_errcode);
818 /* setup_dnfp: check to see that the nfs physical partition does not have
819 * any filesystems assigned to it before allowing it to be deleted.
822 setup_dnfp(q, argv, cl)
829 id = *(int *)argv[0];
830 ## repeat retrieve (exists = any(filesys.label where filesys.phys_id = @id))
839 /* setup_dqot: Remove allocation from nfsphys before deleting quota.
840 * argv[0] = filsys_id
841 * argv[1] = type if "update_quota" or "delete_quota"
842 * argv[2 or 1] = users_id or list_id
845 setup_dqot(q, argv, cl)
850 ## int quota, fs, id;
853 fs = *(int *)argv[0];
854 if (!strcmp(q->name, "update_quota") || !strcmp(q->name, "delete_quota")) {
856 id = *(int *)argv[2];
859 id = *(int *)argv[1];
862 ## range of q is #quota
863 ## repeat retrieve (quota = q.#quota) where q.type = @qtype and
864 ## q.entity_id = @id and q.filsys_id = @fs
865 ## repeat replace nfsphys (allocated = nfsphys.allocated - @quota)
866 ## where nfsphys.nfsphys_id = filesys.#phys_id and filesys.filsys_id = @fs
867 if (ingres_errno) return(mr_errcode);
872 /* setup_sshi: don't exclusive lock the machine table during
873 * set_server_host_internal.
876 setup_sshi(q, argv, cl)
881 ## set lockmode session where readlock = system
885 /* setup add_kerberos_user_mapping: add the string to the string
886 * table if necessary.
889 setup_akum(q, argv, cl)
898 if (name_to_id(name, "STRING", &id) != MR_SUCCESS) {
899 if (q->type != APPEND) return(MR_STRING);
900 ## range of v is values
901 ## retrieve (id = v.value) where v.#name = "strings_id"
903 ## replace v (value = id) where v.#name = "strings_id"
904 ## append to strings (string_id = id, string = name)
905 cache_entry(name, "STRING", id);
907 if (ingres_errno) return(mr_errcode);
908 *(int *)argv[1] = id;
914 /* FOLLOWUP ROUTINES */
916 /* generic set_modtime routine. This takes the table name from the query,
917 * and will update the modtime, modby, and modwho fields in the entry in
918 * the table whose name field matches argv[0].
921 set_modtime(q, argv, cl)
926 ## char *name, *entity, *table;
934 ## replace table (modtime = "now", modby = who, modwith = entity)
935 ## where table.#name = name
939 /* generic set_modtime_by_id routine. This takes the table name from
940 * the query, and the id name from the validate record,
941 * and will update the modtime, modby, and modwho fields in the entry in
942 * the table whose id matches argv[0].
945 set_modtime_by_id(q, argv, cl)
950 ## char *entity, *table, *id_name;
956 id_name = q->validate->object_id;
958 id = *(int *)argv[0];
959 ## replace table (modtime = "now", modby = who, modwith = entity)
960 ## where table.id_name = id
965 /* Sets the finger modtime on a user record. The users_id will be in argv[0].
968 set_finger_modtime(q, argv, cl)
973 ## int users_id, who;
978 users_id = *(int *)argv[0];
980 ## repeat replace u (fmodtime = "now", fmodby = @who, fmodwith = @entity)
981 ## where u.#users_id = @users_id
986 /* Sets the pobox modtime on a user record. The users_id will be in argv[0].
989 set_pobox_modtime(q, argv, cl)
994 ## int users_id, who;
999 users_id = *(int *)argv[0];
1001 ## repeat replace users (pmodtime = "now", pmodby = @who, pmodwith = @entity)
1002 ## where users.#users_id = @users_id
1007 /* Like set_modtime, but uppercases the name first.
1010 set_uppercase_modtime(q, argv, cl)
1015 ## char *name, *entity, *table;
1018 entity = cl->entity;
1019 who = cl->client_id;
1023 ## replace table (modtime = "now", modby = who, modwith = entity)
1024 ## where table.#name = uppercase(name)
1029 /* Sets the modtime on the machine whose mach_id is in argv[0]. This routine
1030 * is necessary for add_machine_to_cluster becuase the table that query
1031 * operates on is "mcm", not "machine".
1034 set_mach_modtime_by_id(q, argv, cl)
1042 entity = cl->entity;
1043 who = cl->client_id;
1045 id = *(int *)argv[0];
1046 ## repeat replace machine (modtime = "now", modby = @who, modwith = @entity)
1047 ## where machine.mach_id = @id
1052 /* Sets the modtime on the cluster whose mach_id is in argv[0]. This routine
1053 * is necessary for add_cluster_data and delete_cluster_data becuase the
1054 * table that query operates on is "svc", not "cluster".
1057 set_cluster_modtime_by_id(q, argv, cl)
1065 entity = cl->entity;
1066 who = cl->client_id;
1068 id = *(int *)argv[0];
1069 ## repeat replace cluster (modtime = "now", modby = @who, modwith = @entity)
1070 ## where cluster.clu_id = @id
1075 /* sets the modtime on the serverhost where the service name is in argv[0]
1076 * and the mach_id is in argv[1].
1079 set_serverhost_modtime(q, argv, cl)
1084 ## char *entity, *serv;
1087 entity = cl->entity;
1088 who = cl->client_id;
1091 id = *(int *)argv[1];
1092 ## repeat replace sh (modtime = "now", modby = @who, modwith = @entity)
1093 ## where sh.service = uppercase(@serv) and sh.mach_id = @id
1098 /* sets the modtime on the nfsphys where the mach_id is in argv[0] and the
1099 * directory name is in argv[1].
1102 set_nfsphys_modtime(q, argv, cl)
1107 ## char *entity, *dir;
1110 entity = cl->entity;
1111 who = cl->client_id;
1113 id = *(int *)argv[0];
1115 ## repeat replace np (modtime = "now", modby = @who, modwith = @entity)
1116 ## where np.#dir = @dir and np.mach_id = @id
1121 /* sets the modtime on a filesystem, where argv[0] contains the filesys
1125 set_filesys_modtime(q, argv, cl)
1130 ## char *label, *entity;
1133 entity = cl->entity;
1134 who = cl->client_id;
1137 if (!strcmp(q->shortname, "ufil"))
1140 ## repeat replace fs (modtime = "now", modby = @who, modwith = @entity,
1141 ## #phys_id = @var_phys_id) where fs.#label = @label
1146 /* sets the modtime on a zephyr class, where argv[0] contains the class
1150 set_zephyr_modtime(q, argv, cl)
1155 ## char *class, *entity;
1158 entity = cl->entity;
1159 who = cl->client_id;
1163 ## repeat replace z (modtime = "now", modby = @who, modwith = @entity)
1164 ## where z.#class = @class
1169 /* fixes the modby field. This will be the second to last thing in the
1170 * argv, the argv length is determined from the query structure. It is
1171 * passed as a pointer to an integer. This will either turn it into a
1172 * username, or # + the users_id.
1174 followup_fix_modby(q, sq, v, action, actarg, cl)
1176 register struct save_queue *sq;
1178 register int (*action)();
1179 register int actarg;
1183 char **argv, *malloc();
1187 while (sq_get_data(sq, &argv)) {
1190 status = id_to_name(id, "USER", &argv[i]);
1192 status = id_to_name(-id, "STRING", &argv[i]);
1193 if (status && status != MR_NO_MATCH)
1195 (*action)(q->vcnt, argv, actarg);
1196 for (j = 0; j < q->vcnt; j++)
1206 ** followup_ausr - add finger and pobox entries, set_user_modtime
1209 ** argv[0] - login (add_user)
1210 ** argv[3] - last name
1211 ** argv[4] - first name
1212 ** argv[5] - middle name
1216 followup_ausr(q, argv, cl)
1222 ## char *login, *entity;
1223 ## char fullname[129];
1226 who = cl->client_id;
1227 entity = cl->entity;
1229 /* build fullname */
1230 if (strlen(argv[4]) && strlen(argv[5]))
1231 sprintf(fullname, "%s %s %s", argv[4], argv[5], argv[3]);
1232 else if (strlen(argv[4]))
1233 sprintf(fullname, "%s %s", argv[4], argv[3]);
1235 sprintf(fullname, "%s", argv[3]);
1237 /* create finger entry, pobox & set modtime on user */
1238 ## repeat replace u (modtime = "now", modby=@who, modwith=@entity,
1239 ## #fullname=@fullname, mit_affil = u.mit_year,
1240 ## fmodtime="now", fmodby=@who, fmodwith=@entity,
1241 ## potype="NONE", pmodtime="now", pmodby=@who, pmodwith=@entity)
1242 ## where u.#login = @login
1248 /* followup_gpob: fixes argv[2] based on the IDs currently there and the
1249 * type in argv[1]. Then completes the upcall to the user.
1251 * argv[2] is of the form "123:234" where the first integer is the machine
1252 * ID if it is a pop box, and the second is the string ID if it is an SMTP
1253 * box. argv[1] should be "POP", "SMTP", or "NONE". Boxes of type NONE
1257 followup_gpob(q, sq, v, action, actarg, cl)
1258 register struct query *q;
1259 register struct save_queue *sq;
1260 register struct validate *v;
1261 register int (*action)();
1265 char **argv, *index();
1267 int mid, sid, status;
1270 while (sq_get_data(sq, &argv)) {
1271 mr_trim_args(2, argv);
1273 p = index(argv[2], ':');
1275 mid = atoi(argv[2]);
1278 if (!strcmp(ptype, "POP")) {
1279 status = id_to_name(mid, "MACHINE", &argv[2]);
1280 if (status == MR_NO_MATCH)
1282 } else if (!strcmp(ptype, "SMTP")) {
1283 status = id_to_name(sid, "STRING", &argv[2]);
1284 if (status == MR_NO_MATCH)
1286 } else /* ptype == "NONE" */ {
1289 if (status) return(status);
1291 if (!strcmp(q->shortname, "gpob")) {
1292 sid = atoi(argv[4]);
1294 status = id_to_name(sid, "USER", &argv[4]);
1296 status = id_to_name(-sid, "STRING", &argv[4]);
1298 if (status && status != MR_NO_MATCH) return(status);
1300 (*action)(q->vcnt, argv, actarg);
1302 /* free saved data */
1310 return (MR_SUCCESS);
1314 /* followup_glin: fix the ace_name in argv[8]. argv[7] will contain the
1315 * ace_type: "LIST", "USER", or "NONE". Decode the id in argv[8] into the
1316 * proper name based on the type, and repace that string in the argv.
1317 * Also fixes the modby field by called followup_fix_modby.
1320 followup_glin(q, sq, v, action, actarg, cl)
1321 register struct query *q;
1322 register struct save_queue *sq;
1323 register struct validate *v;
1324 register int (*action)();
1328 char **argv, *malloc(), *realloc(), *type;
1329 int id, i, idx, status;
1332 if (!strcmp(q->shortname, "gsin"))
1335 while (sq_get_data(sq, &argv)) {
1336 mr_trim_args(q->vcnt, argv);
1338 id = atoi(argv[i = q->vcnt - 2]);
1340 status = id_to_name(id, "USER", &argv[i]);
1342 status = id_to_name(-id, "STRING", &argv[i]);
1343 if (status && status != MR_NO_MATCH)
1346 id = atoi(argv[idx]);
1347 type = argv[idx - 1];
1349 if (!strcmp(type, "LIST")) {
1350 status = id_to_name(id, "LIST", &argv[idx]);
1351 } else if (!strcmp(type, "USER")) {
1352 status = id_to_name(id, "USER", &argv[idx]);
1353 } else if (!strcmp(type, "KERBEROS")) {
1354 status = id_to_name(id, "STRING", &argv[idx]);
1355 } else if (!strcmp(type, "NONE")) {
1358 argv[idx] = strsave("NONE");
1362 argv[idx] = strsave("???");
1364 if (status && status != MR_NO_MATCH)
1367 if (!strcmp(q->shortname, "glin") && atoi(argv[6]) == -1) {
1368 argv[6] = realloc(argv[6], strlen(UNIQUE_GID) + 1);
1369 strcpy(argv[6], UNIQUE_GID);
1373 (*action)(q->vcnt, argv, actarg);
1375 /* free saved data */
1376 for (i = 0; i < q->vcnt; i++)
1382 return (MR_SUCCESS);
1386 /* followup_gqot: Fix the entity name, directory name & modby fields
1387 * argv[0] = filsys_id
1389 * argv[2] = entity_id
1390 * argv[3] = ascii(quota)
1393 followup_gqot(q, sq, v, action, actarg, cl)
1395 register struct save_queue *sq;
1397 register int (*action)();
1398 register int actarg;
1402 char **argv, *malloc();
1403 ## int id, rowcount;
1404 ## char *name, *label;
1407 if (!strcmp(q->name, "get_quota") ||
1408 !strcmp(q->name, "get_quota_by_filesys"))
1412 while (sq_get_data(sq, &argv)) {
1414 switch (argv[1][0]) {
1416 status = id_to_name(atoi(argv[2]), "USER", &argv[2]);
1420 status = id_to_name(atoi(argv[2]), "LIST", &argv[2]);
1424 argv[2] = strsave("system:anyuser");
1428 argv[2] = malloc(8);
1429 sprintf(argv[2], "%d", id);
1432 id = atoi(argv[idx]);
1434 argv[idx] = malloc(256);
1438 ## repeat retrieve (name = filesys.#name) where filesys.#label = @label
1440 ## repeat retrieve (name = nfsphys.dir) where nfsphys.nfsphys_id = @id
1442 ## inquire_equel(rowcount = "rowcount")
1443 if (rowcount != 1) {
1444 sprintf(argv[idx], "#%d", id);
1447 id = atoi(argv[idx+3]);
1449 status = id_to_name(id, "USER", &argv[idx+3]);
1451 status = id_to_name(-id, "STRING", &argv[idx+3]);
1452 if (status && status != MR_NO_MATCH)
1454 (*action)(q->vcnt, argv, actarg);
1455 for (j = 0; j < q->vcnt; j++)
1464 /* followup_aqot: Add allocation to nfsphys after creating quota.
1465 * argv[0] = filsys_id
1466 * argv[1] = type if "add_quota" or "update_quota"
1468 * argv[3 or 2] = ascii(quota)
1471 followup_aqot(q, argv, cl)
1476 ## int quota, id, fs, who;
1477 ## char *entity, *qtype;
1479 fs = *(int *)argv[0];
1480 if (!strcmp(q->name, "add_quota") || !strcmp(q->name, "update_quota")) {
1482 id = *(int *)argv[2];
1483 quota = atoi(argv[3]);
1486 id = *(int *)argv[1];
1487 quota = atoi(argv[2]);
1489 who = cl->client_id;
1490 entity = cl->entity;
1492 ## repeat replace q (modtime = "now", modby = @who, modwith = @entity)
1493 ## where q.filsys_id = @fs and q.type = @qtype and q.entity_id = @id
1494 ## repeat replace nfsphys (allocated = nfsphys.allocated + @quota)
1495 ## where nfsphys.nfsphys_id = filesys.#phys_id and filesys.filsys_id = @fs
1496 if (ingres_errno) return(mr_errcode);
1501 followup_gpce(q, sq, v, action, actarg, cl)
1503 register struct save_queue *sq;
1505 register int (*action)();
1506 register int actarg;
1510 char **argv, *malloc();
1514 while (sq_get_data(sq, &argv)) {
1515 id = atoi(argv[PCAP_QSERVER]);
1516 status = id_to_name(id, "MACHINE", &argv[PCAP_QSERVER]);
1517 if (status) return (status);
1520 status = id_to_name(id, "USER", &argv[i]);
1522 status = id_to_name(-id, "STRING", &argv[i]);
1523 if (status && status != MR_NO_MATCH)
1525 (*action)(q->vcnt, argv, actarg);
1526 for (j = 0; j < q->vcnt; j++)
1538 followup_gzcl(q, sq, v, action, actarg, cl)
1539 register struct query *q;
1540 register struct save_queue *sq;
1541 register struct validate *v;
1542 register int (*action)();
1549 while (sq_get_data(sq, &argv)) {
1550 mr_trim_args(q->vcnt, argv);
1552 id = atoi(argv[i = q->vcnt - 2]);
1554 status = id_to_name(id, "USER", &argv[i]);
1556 status = id_to_name(-id, "STRING", &argv[i]);
1557 if (status && status != MR_NO_MATCH)
1560 for (i = 1; i < 8; i+=2) {
1561 id = atoi(argv[i+1]);
1562 if (!strcmp(argv[i], "LIST")) {
1563 status = id_to_name(id, "LIST", &argv[i+1]);
1564 } else if (!strcmp(argv[i], "USER")) {
1565 status = id_to_name(id, "USER", &argv[i+1]);
1566 } else if (!strcmp(argv[i], "KERBEROS")) {
1567 status = id_to_name(id, "STRING", &argv[i+1]);
1568 } else if (!strcmp(argv[i], "NONE")) {
1571 argv[i+1] = strsave("NONE");
1575 argv[i+1] = strsave("???");
1577 if (status && status != MR_NO_MATCH)
1582 (*action)(q->vcnt, argv, actarg);
1584 /* free saved data */
1585 for (i = 0; i < q->vcnt; i++)
1597 followup_gsha(q, sq, v, action, actarg, cl)
1598 register struct query *q;
1599 register struct save_queue *sq;
1600 register struct validate *v;
1601 register int (*action)();
1608 while (sq_get_data(sq, &argv)) {
1609 mr_trim_args(q->vcnt, argv);
1613 status = id_to_name(id, "USER", &argv[4]);
1615 status = id_to_name(-id, "STRING", &argv[4]);
1616 if (status && status != MR_NO_MATCH)
1620 if (!strcmp(argv[1], "LIST")) {
1621 status = id_to_name(id, "LIST", &argv[2]);
1622 } else if (!strcmp(argv[1], "USER")) {
1623 status = id_to_name(id, "USER", &argv[2]);
1624 } else if (!strcmp(argv[1], "KERBEROS")) {
1625 status = id_to_name(id, "STRING", &argv[2]);
1626 } else if (!strcmp(argv[1], "NONE")) {
1629 argv[2] = strsave("NONE");
1633 argv[2] = strsave("???");
1635 if (status && status != MR_NO_MATCH)
1639 (*action)(q->vcnt, argv, actarg);
1641 /* free saved data */
1642 for (i = 0; i < q->vcnt; i++)
1652 /* Special query routines */
1654 /* set_pobox - this does all of the real work.
1655 * argv = user_id, type, box
1656 * if type is POP, then box should be a machine, and its ID should be put in
1657 * pop_id. If type is SMTP, then box should be a string and its ID should
1658 * be put in box_id. If type is NONE, then box doesn't matter.
1661 int set_pobox(q, argv, cl)
1666 ## int user, id, rowcount;
1667 ## char *box, potype[9];
1671 user = *(int *)argv[0];
1673 ## repeat retrieve (id = users.pop_id, potype = users.#potype)
1674 ## where users.users_id = @user
1675 if (ingres_errno) return(mr_errcode);
1676 if (!strcmp(strtrim(potype), "POP"))
1677 set_pop_usage(id, -1);
1679 if (!strcmp(argv[1], "POP")) {
1680 status = name_to_id(box, "MACHINE", &id);
1681 if (status == MR_NO_MATCH)
1685 ## repeat replace users (#potype = "POP", pop_id = @id)
1686 ## where users.users_id = @user
1687 set_pop_usage(id, 1);
1688 } else if (!strcmp(argv[1], "SMTP")) {
1689 if (index(box, '/') || index(box, '|'))
1690 return(MR_BAD_CHAR);
1691 status = name_to_id(box, "STRING", &id);
1692 if (status == MR_NO_MATCH) {
1693 ## repeat retrieve (id = values.value) where values.name = "strings_id"
1695 ## repeat replace values (value = @id) where values.name = "strings_id"
1696 ## append to strings (string_id = id, string = box)
1699 ## repeat replace users (#potype = "SMTP", box_id = @id)
1700 ## where users.users_id = @user
1701 } else /* argv[1] == "NONE" */ {
1702 ## repeat replace users (#potype = "NONE") where users.users_id = @user
1705 set_pobox_modtime(q, argv, cl);
1706 ## repeat replace tblstats (updates = tblstats.updates + 1, modtime = "now")
1707 ## where tblstats.#table = "users"
1708 if (ingres_errno) return(mr_errcode);
1713 /* get_list_info: passed a wildcard list name, returns lots of stuff about
1714 * each list. This is tricky: first build a queue of all requested
1715 * data. Rest of processing consists of fixing gid, ace_name, and modby.
1718 get_list_info(q, aargv, cl, action, actarg)
1719 register struct query *q;
1722 register int (*action)();
1725 char *argv[13], *malloc(), *realloc();
1726 ## char *name, acl_type[9], listname[33], active[5], public[5], hidden[5];
1727 ## char maillist[5], group[5], gid[6], acl_name[256], desc[256], modtime[27];
1728 ## char modby[256], modwith[9];
1729 ## int id, rowcount, acl_id, hid, modby_id;
1730 int returned, status;
1731 struct save_queue *sq, *sq_create();
1733 returned = rowcount = 0;
1737 ## range of l is list
1738 ## repeat retrieve (id = l.list_id) where l.#name = @name {
1739 sq_save_data(sq, id);
1742 if (ingres_errno) return(mr_errcode);
1744 return(MR_NO_MATCH);
1746 argv[0] = listname; argv[1] = active; argv[2] = public; argv[3] = hidden;
1747 argv[4] = maillist; argv[5] = group; argv[6] = gid; argv[7] = acl_type;
1748 argv[9] = desc; argv[10] = modtime; argv[12] = modwith;
1750 while (sq_get_data(sq, &id)) {
1754 ## repeat retrieve (listname = l.#name, active = text(l.#active),
1755 ## public = text(l.#public), hidden = text(l.#hidden),
1756 ## hid = l.#hidden, maillist = text(l.#maillist),
1757 ## group = text(l.#group), gid = text(l.#gid),
1758 ## acl_type = trim(l.#acl_type), acl_id = l.#acl_id,
1759 ## desc = l.#desc, modtime = l.#modtime, modby_id = l.#modby,
1760 ## modwith =l.#modwith)
1761 ## where l.list_id = @id
1762 if (ingres_errno) return(mr_errcode);
1764 if (atoi(gid) == -1)
1765 argv[6] = UNIQUE_GID;
1767 argv[8] = malloc(0);
1768 if (!strcmp(acl_type, "LIST")) {
1769 status = id_to_name(acl_id, "LIST", &argv[8]);
1770 } else if (!strcmp(acl_type, "USER")) {
1771 status = id_to_name(acl_id, "USER", &argv[8]);
1772 } else if (!strcmp(acl_type, "KERBEROS")) {
1773 status = id_to_name(acl_id, "STRING", &argv[8]);
1774 } else if (!strcmp(acl_type, "NONE")) {
1777 argv[8] = strsave("NONE");
1781 argv[8] = strsave("???");
1783 if (status && status != MR_NO_MATCH) return(status);
1785 argv[11] = malloc(0);
1787 status = id_to_name(modby_id, "USER", &argv[11]);
1789 status = id_to_name(-modby_id, "STRING", &argv[11]);
1790 if (status && status != MR_NO_MATCH) return(status);
1792 mr_trim_args(q->vcnt, argv);
1794 (*action)(q->vcnt, argv, actarg);
1800 if (ingres_errno) return(mr_errcode);
1801 return (MR_SUCCESS);
1805 /* Add_member_to_list: do list flattening as we go! MAXLISTDEPTH is
1806 * how many different ancestors a member is allowed to have.
1809 #define MAXLISTDEPTH 100
1811 int add_member_to_list(q, argv, cl)
1816 ## int id, lid, mid, exists, error, who, ref;
1817 ## char *mtype, dtype[9], *entity;
1818 int ancestors[MAXLISTDEPTH], aref[MAXLISTDEPTH], acount, a;
1819 int descendants[MAXLISTDEPTH], dref[MAXLISTDEPTH], dcount, d;
1821 char *dtypes[MAXLISTDEPTH];
1822 char *iargv[3], *buf;
1824 ## range of m is imembers
1825 lid = *(int *)argv[0];
1827 mid = *(int *)argv[2];
1828 /* if the member is already a direct member of the list, punt */
1829 ## repeat retrieve (exists = any(m.list_id where m.list_id=@lid and
1830 ## m.member_id = @mid and m.member_type = @mtype
1831 ## and m.direct = 1))
1834 if (!strcasecmp(mtype, "STRING")) {
1836 status = id_to_name(mid, "STRING", &buf);
1837 if (status) return(status);
1838 if (index(buf, '/') || index(buf, '|')) {
1840 return(MR_BAD_CHAR);
1848 ## repeat retrieve (id = m.list_id, ref = m.ref_count)
1849 ## where m.member_id = @lid and m.member_type = "LIST" {
1851 ancestors[acount++] = id;
1852 if (acount >= MAXLISTDEPTH) {
1856 if (ingres_errno) return(mr_errcode);
1857 if (acount >= MAXLISTDEPTH) {
1858 return(MR_INTERNAL);
1860 descendants[0] = mid;
1865 if (!strcmp(mtype, "LIST")) {
1866 ## repeat retrieve (id = m.member_id, dtype = m.member_type,
1867 ## ref = m.ref_count)
1868 ## where m.list_id = @mid {
1871 dtypes[dcount] = "LIST";
1874 dtypes[dcount] = "USER";
1877 dtypes[dcount] = "STRING";
1880 dtypes[dcount] = "KERBEROS";
1887 descendants[dcount++] = id;
1888 if (dcount >= MAXLISTDEPTH) {
1893 if (ingres_errno) return(mr_errcode);
1895 return(MR_INTERNAL);
1897 for (a = 0; a < acount; a++) {
1899 for (d = 0; d < dcount; d++) {
1900 mid = descendants[d];
1902 if (mid == lid && !strcmp(mtype, "LIST")) {
1903 return(MR_LISTLOOP);
1905 ## repeat retrieve (exists = any(m.ref_count where m.list_id = @lid
1906 ## and m.member_id = @mid
1907 ## and m.member_type = @mtype))
1908 ref = aref[a] * dref[d];
1910 if (a == 0 && d == 0)
1911 ## replace m (ref_count = m.ref_count+ref, direct = 1)
1912 ## where m.list_id = lid and m.member_id = mid and
1913 ## m.member_type = mtype
1915 ## replace m (ref_count = m.ref_count+ref)
1916 ## where m.list_id = lid and m.member_id = mid and
1917 ## m.member_type = mtype
1919 incremental_clear_before();
1920 if (a == 0 && d == 0)
1921 ## append imembers (list_id=lid, member_id = mid, direct = 1,
1922 ## member_type=mtype, ref_count = 1)
1924 ## append imembers (list_id=lid, member_id = mid,
1925 ## member_type=mtype, ref_count = ref)
1926 iargv[0] = (char *)lid;
1928 iargv[2] = (char *)mid;
1929 incremental_after("members", 0, iargv);
1933 lid = *(int *)argv[0];
1934 entity = cl->entity;
1935 who = cl->client_id;
1936 ## repeat replace list (modtime = "now", modby = @who, modwith = @entity)
1937 ## where list.#list_id = @lid
1938 if (ingres_errno) return(mr_errcode);
1943 /* Delete_member_from_list: do list flattening as we go!
1946 int delete_member_from_list(q, argv, cl)
1951 ## int id, lid, mid, cnt, exists, error, who, ref;
1952 ## char *mtype, dtype[9], *entity;
1953 int ancestors[MAXLISTDEPTH], aref[MAXLISTDEPTH], acount, a;
1954 int descendants[MAXLISTDEPTH], dref[MAXLISTDEPTH], dcount, d;
1955 char *dtypes[MAXLISTDEPTH];
1958 ## range of m is imembers
1959 lid = *(int *)argv[0];
1961 mid = *(int *)argv[2];
1962 /* if the member is not a direct member of the list, punt */
1963 ## repeat retrieve (exists = any(m.list_id where m.list_id=@lid and
1964 ## m.member_id = @mid and m.member_type = @mtype
1965 ## and m.direct = 1))
1966 if (ingres_errno) return(mr_errcode);
1968 return(MR_NO_MATCH);
1972 ## repeat retrieve (id = m.list_id, ref = m.ref_count)
1973 ## where m.member_id = @lid and m.member_type = "LIST" {
1975 ancestors[acount++] = id;
1976 if (acount >= MAXLISTDEPTH)
1979 if (ingres_errno) return(mr_errcode);
1980 if (acount >= MAXLISTDEPTH)
1981 return(MR_INTERNAL);
1982 descendants[0] = mid;
1987 if (!strcmp(mtype, "LIST")) {
1988 ## repeat retrieve (id = m.member_id, dtype = m.member_type,
1989 ## ref = m.ref_count)
1990 ## where m.list_id = @mid {
1993 dtypes[dcount] = "LIST";
1996 dtypes[dcount] = "USER";
1999 dtypes[dcount] = "STRING";
2002 dtypes[dcount] = "KERBEROS";
2009 descendants[dcount++] = id;
2010 if (dcount >= MAXLISTDEPTH)
2013 if (ingres_errno) return(mr_errcode);
2015 return(MR_INTERNAL);
2017 for (a = 0; a < acount; a++) {
2019 for (d = 0; d < dcount; d++) {
2020 mid = descendants[d];
2022 if (mid == lid && !strcmp(mtype, "LIST")) {
2023 return(MR_LISTLOOP);
2025 ## repeat retrieve (cnt = m.ref_count)
2026 ## where m.list_id = @lid and m.member_id = @mid
2027 ## and m.member_type = @mtype
2028 ref = aref[a] * dref[d];
2030 iargv[0] = (char *)lid;
2032 iargv[2] = (char *)mid;
2033 incremental_before("members", 0, iargv);
2034 ## delete m where m.list_id = lid and m.member_id = mid and
2035 ## m.member_type = mtype
2036 incremental_clear_after();
2037 } else if (a == 0 && d == 0) {
2038 ## replace m (ref_count = m.ref_count-ref, direct = 0)
2039 ## where m.list_id = lid and m.member_id = mid and
2040 ## m.member_type = mtype
2042 ## replace m (ref_count = m.ref_count-ref)
2043 ## where m.list_id = lid and m.member_id = mid and
2044 ## m.member_type = mtype
2048 lid = *(int *)argv[0];
2049 entity = cl->entity;
2050 who = cl->client_id;
2051 ## repeat replace list (modtime = "now", modby = @who, modwith = @entity)
2052 ## where list.#list_id = @lid
2053 if (ingres_errno) return(mr_errcode);
2058 /* get_ace_use - given a type and a name, return a type and a name.
2059 * The ace_type is one of "LIST", "USER", "RLIST", or "RUSER" in argv[0],
2060 * and argv[1] will contain the ID of the entity in question. The R*
2061 * types mean to recursively look at every containing list, not just
2062 * when the object in question is a direct member. On return, the
2063 * usage type will be one of LIST, SERVICE, FILESYS, QUOTA, QUERY, or ZEPHYR.
2066 int get_ace_use(q, argv, cl, action, actarg)
2075 ## int aid, listid, id;
2076 struct save_queue *sq, *sq_create();
2078 ## range of m is imembers
2080 aid = *(int *)argv[1];
2081 if (!strcmp(atype, "LIST") || !strcmp(atype, "USER") ||
2082 !strcmp(atype, "KERBEROS")) {
2083 return(get_ace_internal(atype, aid, action, actarg));
2087 if (!strcmp(atype, "RLIST")) {
2088 sq_save_data(sq, aid);
2089 /* get all the list_id's of containing lists */
2090 ## repeat retrieve (listid = m.list_id)
2091 ## where m.member_type = "LIST" and m.member_id = @id {
2092 sq_save_unique_data(sq, listid);
2094 /* now process each one */
2095 while (sq_get_data(sq, &id)) {
2096 if (get_ace_internal("LIST", id, action, actarg) == MR_SUCCESS)
2101 if (!strcmp(atype, "RUSER")) {
2102 ## repeat retrieve (listid = m.list_id)
2103 ## where m.member_type = "USER" and m.member_id = @aid {
2104 sq_save_data(sq, listid);
2106 /* now process each one */
2107 while (sq_get_data(sq, &id)) {
2108 if (get_ace_internal("LIST", id, action, actarg) == MR_SUCCESS)
2111 if (get_ace_internal("USER", aid, action, actarg) == MR_SUCCESS)
2115 if (!strcmp(atype, "RKERBERO")) {
2116 ## repeat retrieve (listid = m.list_id)
2117 ## where m.member_type = "KERBEROS" and m.member_id = @aid {
2118 sq_save_data(sq, listid);
2120 /* now process each one */
2121 while (sq_get_data(sq, &id)) {
2122 if (get_ace_internal("LIST", id, action, actarg) == MR_SUCCESS)
2125 if (get_ace_internal("KERBEROS", aid, action, actarg) == MR_SUCCESS)
2130 if (ingres_errno) return(mr_errcode);
2131 if (!found) return(MR_NO_MATCH);
2136 /* This looks up a single list or user for ace use. atype must be "USER"
2137 * or "LIST", and aid is the ID of the corresponding object. This is used
2138 * by get_ace_use above.
2141 ##get_ace_internal(atype, aid, action, actarg)
2152 if (!strcmp(atype, "LIST")) {
2153 rargv[0] = "FILESYS";
2154 ## repeat retrieve (name = filesys.label)
2155 ## where filesys.owners = @aid {
2156 (*action)(2, rargv, actarg);
2161 ## repeat retrieve (name = capacls.capability)
2162 ## where capacls.list_id = @aid {
2163 (*action)(2, rargv, actarg);
2166 } else if (!strcmp(atype, "USER")) {
2167 rargv[0] = "FILESYS";
2168 ## repeat retrieve (name = filesys.label)
2169 ## where filesys.owner = @aid {
2170 (*action)(2, rargv, actarg);
2176 ## repeat retrieve (name = list.#name)
2177 ## where list.acl_type = @atype and list.acl_id = @aid {
2178 (*action)(2, rargv, actarg);
2182 rargv[0] = "SERVICE";
2183 ## repeat retrieve (name = servers.#name)
2184 ## where servers.acl_type = @atype and servers.acl_id = @aid {
2185 (*action)(2, rargv, actarg);
2189 rargv[0] = "HOSTACCESS";
2190 ## repeat retrieve (name = machine.#name)
2191 ## where machine.mach_id = hostaccess.mach_id and
2192 ## hostaccess.acl_type = @atype and hostaccess.acl_id = @aid {
2193 (*action)(2, rargv, actarg);
2196 rargv[0] = "ZEPHYR";
2197 ## repeat retrieve (name = zephyr.class)
2198 ## where zephyr.xmt_type = @atype and zephyr.xmt_id = @aid or
2199 ## zephyr.sub_type = @atype and zephyr.sub_id = @aid or
2200 ## zephyr.iws_type = @atype and zephyr.iws_id = @aid or
2201 ## zephyr.iui_type = @atype and zephyr.iui_id = @aid {
2202 (*action)(2, rargv, actarg);
2206 if (!found) return(MR_NO_MATCH);
2211 /* get_lists_of_member - given a type and a name, return the name and flags
2212 * of all of the lists of the given member. The member_type is one of
2213 * "LIST", "USER", "STRING", "RLIST", "RUSER", or "RSTRING" in argv[0],
2214 * and argv[1] will contain the ID of the entity in question. The R*
2215 * types mean to recursively look at every containing list, not just
2216 * when the object in question is a direct member.
2219 int get_lists_of_member(q, argv, cl, action, actarg)
2226 int found = 0, direct = 1;
2229 ## int aid, listid, id;
2230 ## char name[33], active[5], public[5], hidden[5], maillist[5], group[5];
2233 aid = *(int *)argv[1];
2234 if (!strcmp(atype, "RLIST")) {
2238 if (!strcmp(atype, "RUSER")) {
2242 if (!strcmp(atype, "RSTRING")) {
2246 if (!strcmp(atype, "RKERBEROS")) {
2255 rargv[4] = maillist;
2257 ## range of m is imembers
2259 ## repeat retrieve (name = list.#name, active = text(list.#active),
2260 ## public = text(list.#public), hidden = text(list.#hidden),
2261 ## maillist = text(list.#maillist), group = text(list.#group))
2262 ## where list.list_id = m.list_id and m.direct = 1 and
2263 ## m.member_type = @atype and m.member_id = @aid {
2264 (*action)(6, rargv, actarg);
2268 ## repeat retrieve (name = list.#name, active = text(list.#active),
2269 ## public = text(list.#public), hidden = text(list.#hidden),
2270 ## maillist = text(list.#maillist), group = text(list.#group))
2271 ## where list.list_id = m.list_id and
2272 ## m.member_type = @atype and m.member_id = @aid {
2273 (*action)(6, rargv, actarg);
2278 if (ingres_errno) return(mr_errcode);
2279 if (!found) return(MR_NO_MATCH);
2284 /* qualified_get_lists: passed "TRUE", "FALSE", or "DONTCARE" for each of
2285 * the five flags associated with each list. It will return the name of
2286 * each list that meets the quailifications. It does this by building a
2287 * where clause based on the arguments, then doing a retrieve.
2290 static char *lflags[5] = { "active", "public", "hidden", "maillist", "group" };
2292 int qualified_get_lists(q, argv, cl, action, actarg)
2299 return(qualified_get(q, argv, action, actarg, "l.list_id != 0",
2300 "l", "name", lflags));
2304 /** get_members_of_list - optimized query for retrieval of list members
2307 ** argv[0] - list_id
2310 ** - retrieve USER members, then LIST members, then STRING members
2313 get_members_of_list(q, argv, cl, action, actarg)
2320 ## int list_id, member_id;
2321 ## char member_name[129], member_type[9];
2324 struct save_queue *sq;
2326 list_id = *(int *)argv[0];
2330 ## repeat retrieve (member_type = imembers.#member_type,
2331 ## member_id = imembers.#member_id)
2332 ## where imembers.#list_id = @list_id and imembers.direct = 1 {
2335 sq_save_data(sq, (member_type[0] << 24) | (member_id & 0xffffff));
2337 if (members <= 49) {
2338 targv[1] = malloc(0);
2339 while (sq_remove_data(sq, &member_id)) {
2340 switch (member_id >> 24) {
2343 id_to_name(member_id & 0xffffff, "USER", &targv[1]);
2344 (*action)(2, targv, actarg);
2348 id_to_name(member_id & 0xffffff, "LIST", &targv[1]);
2349 (*action)(2, targv, actarg);
2352 targv[0] = "STRING";
2353 id_to_name(member_id & 0xffffff, "STRING", &targv[1]);
2354 (*action)(2, targv, actarg);
2357 targv[0] = "KERBEROS";
2358 id_to_name(member_id & 0xffffff, "STRING", &targv[1]);
2359 (*action)(2, targv, actarg);
2363 return(MR_INTERNAL);
2372 targv[1] = member_name;
2374 ## range of m is imembers
2375 ## repeat retrieve (member_name = users.login)
2376 ## where m.#list_id = @list_id and m.#member_type = "USER"
2377 ## and m.#member_id = users.users_id and m.direct = 1
2378 ## sort by #member_name
2380 (*action)(2, targv, actarg);
2382 if (ingres_errno) return(mr_errcode);
2385 ## repeat retrieve (member_name = list.name)
2386 ## where m.#list_id = @list_id and m.#member_type = "LIST"
2387 ## and m.#member_id = list.#list_id and m.direct = 1
2388 ## sort by #member_name
2390 (*action)(2, targv, actarg);
2392 if (ingres_errno) return(mr_errcode);
2394 targv[0] = "STRING";
2395 ## repeat retrieve (member_name = strings.string)
2396 ## where m.#list_id = @list_id and m.#member_type = "STRING"
2397 ## and m.#member_id = strings.string_id and m.direct = 1
2398 ## sort by #member_name
2400 (*action)(2, targv, actarg);
2402 if (ingres_errno) return(mr_errcode);
2404 targv[0] = "KERBEROS";
2405 ## repeat retrieve (member_name = strings.string)
2406 ## where m.#list_id = @list_id and m.#member_type = "KERBEROS"
2407 ## and m.#member_id = strings.string_id and m.direct = 1
2408 ## sort by #member_name
2410 (*action)(2, targv, actarg);
2412 if (ingres_errno) return(mr_errcode);
2418 /* count_members_of_list: this is a simple query, but it cannot be done
2419 * through the dispatch table.
2422 int count_members_of_list(q, argv, cl, action, actarg)
2429 ## int list, ct = 0;
2430 char *rargv[1], countbuf[5];
2432 list = *(int *)argv[0];
2433 rargv[0] = countbuf;
2434 ## repeat retrieve (ct = count(imembers.list_id
2435 ## where imembers.list_id = @list and
2436 ## imembers.direct = 1))
2437 if (ingres_errno) return(mr_errcode);
2438 sprintf(countbuf, "%d", ct);
2439 (*action)(1, rargv, actarg);
2444 /* qualified_get_server: passed "TRUE", "FALSE", or "DONTCARE" for each of
2445 * the three flags associated with each service. It will return the name of
2446 * each service that meets the quailifications. It does this by building a
2447 * where clause based on the arguments, then doing a retrieve.
2450 static char *sflags[3] = { "enable", "inprogress", "harderror" };
2452 int qualified_get_server(q, argv, cl, action, actarg)
2459 return(qualified_get(q, argv, action, actarg, "s.name != \"\"",
2460 "s", "name", sflags));
2464 /* generic qualified get routine, used by qualified_get_lists,
2465 * qualified_get_server, and qualified_get_serverhost.
2467 * start - a simple where clause, must not be empty
2468 * range - the name of the range variable
2469 * field - the field to return
2470 * flags - an array of strings, names of the flag variables
2473 int qualified_get(q, argv, action, actarg, start, range, field, flags)
2483 ## char name[33], qual[256], *rvar, *rtbl, *rfield;
2484 char *rargv[1], buf[32];
2487 strcpy(qual, start);
2488 for (i = 0; i < q->argc; i++) {
2489 if (!strcmp(argv[i], "TRUE")) {
2490 sprintf(buf, " and %s.%s != 0", range, flags[i]);
2491 (void) strcat(qual, buf);
2492 } else if (!strcmp(argv[i], "FALSE")) {
2493 sprintf(buf, " and %s.%s = 0", range, flags[i]);
2494 (void) strcat(qual, buf);
2502 ## range of rvar is rtbl
2503 ## retrieve (name = rvar.rfield) where qual {
2504 (*action)(1, rargv, actarg);
2506 if (ingres_errno) return(mr_errcode);
2507 ## inquire_equel(rowcount = "rowcount")
2509 return(MR_NO_MATCH);
2514 /* qualified_get_serverhost: passed "TRUE", "FALSE", or "DONTCARE" for each of
2515 * the five flags associated with each serverhost. It will return the name of
2516 * each service and host that meets the quailifications. It does this by
2517 * building a where clause based on the arguments, then doing a retrieve.
2520 static char *shflags[6] = { "service", "enable", "override", "success",
2521 "inprogress", "hosterror" };
2523 int qualified_get_serverhost(q, argv, cl, action, actarg)
2530 ## char sname[33], mname[33], qual[256];
2531 char *rargv[2], buf[32];
2534 sprintf(qual, "machine.mach_id = sh.mach_id and sh.service = uppercase(\"%s\")",
2536 for (i = 1; i < q->argc; i++) {
2537 if (!strcmp(argv[i], "TRUE")) {
2538 sprintf(buf, " and sh.%s != 0", shflags[i]);
2540 } else if (!strcmp(argv[i], "FALSE")) {
2541 sprintf(buf, " and sh.%s = 0", shflags[i]);
2548 ## range of sh is serverhosts
2549 ## retrieve (sname = sh.service, mname = machine.name) where qual {
2550 (*action)(2, rargv, actarg);
2552 if (ingres_errno) return(mr_errcode);
2553 ## inquire_equel(rowcount = "rowcount")
2555 return(MR_NO_MATCH);
2560 /* register_user - change user's login name and allocate a pobox, group,
2561 * filesystem, and quota for them. The user's status must start out as 0,
2562 * and is left as 2. Arguments are: user's UID, new login name, and user's
2563 * type for filesystem allocation (MR_FS_STUDENT, MR_FS_FACULTY,
2564 * MR_FS_STAFF, MR_FS_MISC).
2567 register_user(q, argv, cl)
2572 ## char *login, dir[65], *entity, *directory, machname[33];
2573 ## int who, rowcount, mid, uid, users_id, flag, utype, nid, list_id, quota;
2574 ## int size, alloc, pid, m_id;
2575 char buffer[256], *aargv[3];
2578 entity = cl->entity;
2579 who = cl->client_id;
2581 uid = atoi(argv[0]);
2583 utype = atoi(argv[2]);
2585 ## range of u is users
2586 ## range of l is list
2587 ## range of sh is serverhosts
2588 ## range of n is nfsphys
2589 ## range of m is machine
2592 ## repeat retrieve (users_id = u.#users_id)
2593 ## where u.#uid = @uid and (u.status = 0 or u.status = 5 or u.status = 6)
2594 ## inquire_equel(rowcount = "rowcount");
2596 return(MR_NO_MATCH);
2598 return(MR_NOT_UNIQUE);
2600 /* check new login name */
2601 ## repeat retrieve (flag = any(u.#login where u.#login = @login and
2602 ## u.#users_id != users_id))
2603 if (ingres_errno) return(mr_errcode);
2604 if (flag) return(MR_IN_USE);
2605 ## repeat retrieve (flag = any(l.#name where l.#name = @login))
2606 if (ingres_errno) return(mr_errcode);
2607 if (flag) return(MR_IN_USE);
2608 ## repeat retrieve (flag = any(filesys.#label where filesys.#label = @login))
2609 if (ingres_errno) return(mr_errcode);
2610 if (flag) return(MR_IN_USE);
2611 com_err(whoami, 0, "new login name OK");
2613 /* choose place for pobox, put in mid */
2614 ## repeat retrieve (mid = sh.mach_id, machname = m.name)
2615 ## where sh.service = "POP" and m.mach_id = sh.mach_id and
2616 ## sh.value2 - sh.value1 = max(sh.value2-sh.value1 where sh.service="POP")
2617 if (ingres_errno) return(mr_errcode);
2618 ## inquire_equel(rowcount = "rowcount");
2620 return(MR_NO_POBOX);
2622 /* change login name, set pobox */
2623 sprintf(buffer, "u.users_id = %d", users_id);
2624 incremental_before("users", buffer, 0);
2625 ## repeat replace u (#login = @login, status = 2, modtime = "now",
2626 ## modby = @who, modwith = @entity, potype="POP",
2627 ## pop_id = @mid, pmodtime="now", pmodby=@who,
2628 ## pmodwith=@entity)
2629 ## where u.#users_id = @users_id
2630 ## inquire_equel(rowcount = "rowcount");
2631 if (ingres_errno) return(mr_errcode);
2633 return(MR_INTERNAL);
2634 set_pop_usage(mid, 1);
2635 com_err(whoami, 0, "set login name to %s and pobox to %s", login,
2637 incremental_after("users", buffer, 0);
2639 /* create group list */
2640 if (set_next_object_id("gid", "list"))
2642 if (set_next_object_id("list_id", "list"))
2644 ## repeat retrieve (list_id = values.value) where values.name = "list_id"
2645 if (ingres_errno) return(mr_errcode);
2646 ## inquire_equel(rowcount = "rowcount");
2648 return(MR_INTERNAL);
2649 incremental_clear_before();
2650 ## repeat append list (name = @login, #list_id = @list_id, active = 1,
2651 ## public = 0, hidden = 0, maillist = 0, group = 1,
2652 ## #gid = values.value, desc = "User Group",
2653 ## acl_type = "USER", acl_id = @users_id, modtime = "now",
2654 ## modby = @who, modwith = @entity)
2655 ## where values.name = "gid"
2656 if (ingres_errno) return(mr_errcode);
2657 ## inquire_equel(rowcount = "rowcount");
2659 return(MR_INTERNAL);
2660 sprintf(buffer, "l.list_id = %d", list_id);
2661 incremental_after("list", buffer, 0);
2662 aargv[0] = (char *) list_id;
2664 aargv[2] = (char *) users_id;
2665 incremental_clear_before();
2666 ## repeat append imembers (#list_id = @list_id, member_type = "USER",
2667 ## member_id = @users_id, ref_count = 1, direct = 1)
2668 if (ingres_errno) return(mr_errcode);
2669 ## inquire_equel(rowcount = "rowcount");
2671 return(MR_INTERNAL);
2672 incremental_after("members", 0, aargv);
2673 com_err(whoami, 0, "group list created");
2675 /* decide where to put filesystem */
2678 ## repeat retrieve (mid = n.mach_id, dir = trim(n.#dir), nid = n.nfsphys_id,
2679 ## flag = n.status, size = n.#size, alloc = n.allocated) {
2680 if ((flag & utype) && (size != 0) && (size - alloc > maxsize)) {
2681 maxsize = size - alloc;
2684 directory = strsave(dir);
2689 if (ingres_errno) return(mr_errcode);
2691 return(MR_NO_FILESYS);
2693 /* create filesystem */
2694 if (set_next_object_id("filsys_id", "filesys"))
2696 incremental_clear_before();
2697 ## repeat append filesys (filsys_id = values.value, phys_id = @pid,
2698 ## label = @login, type = "NFS", mach_id = @m_id,
2699 ## name = @directory + "/" + @login,
2700 ## mount = "/mit/" + @login,
2701 ## access = "w", comments = "User Locker",
2702 ## owner = @users_id, owners = @list_id, createflg = 1,
2703 ## lockertype = "HOMEDIR", modtime = "now",
2704 ## modby = @who, modwith = @entity)
2705 ## where values.name = "filsys_id"
2706 if (ingres_errno) return(mr_errcode);
2707 ## inquire_equel(rowcount = "rowcount");
2709 return(MR_INTERNAL);
2710 incremental_after("filesys",
2711 "fs.filsys_id = values.value and values.name = \"filsys_id\"",
2713 com_err(whoami, 0, "filesys created on mach %d in %s/%s", m_id,
2717 ## repeat retrieve (quota = values.value) where values.name = "def_quota"
2718 if (ingres_errno) return(mr_errcode);
2719 ## inquire_equel(rowcount = "rowcount");
2721 return(MR_NO_QUOTA);
2722 incremental_clear_before();
2723 ## repeat append #quota (entity_id = @users_id, filsys_id = values.value,
2725 ## #quota = @quota, phys_id = @pid, modtime = "now",
2726 ## modby = @who, modwith = @entity)
2727 ## where values.name = "filsys_id"
2728 if (ingres_errno) return(mr_errcode);
2729 ## inquire_equel(rowcount = "rowcount");
2731 return(MR_INTERNAL);
2732 ## repeat replace nfsphys (allocated = nfsphys.allocated + @quota)
2733 ## where nfsphys.nfsphys_id = filesys.#phys_id and
2734 ## filesys.filsys_id = values.value and values.name = "filsys_id"
2735 if (ingres_errno) return(mr_errcode);
2736 ## inquire_equel(rowcount = "rowcount");
2738 return(MR_INTERNAL);
2742 sprintf(buffer, "q.entity_id = %d and q.filsys_id = values.value and q.type = \"USER\" and values.name = \"filsys_id\"", users_id);
2743 incremental_after("quota", buffer, aargv);
2744 com_err(whoami, 0, "quota of %d assigned", quota);
2745 if (ingres_errno) return(mr_errcode);
2747 cache_entry(login, "USER", users_id);
2749 ## repeat replace tblstats (updates = tblstats.updates + 1, modtime = "now")
2750 ## where tblstats.table = "users"
2751 ## repeat replace tblstats (appends = tblstats.appends + 1, modtime = "now")
2752 ## where tblstats.table = "list" or tblstats.table = "filesys" or
2753 ## tblstats.table = "quota"
2754 if (ingres_errno) return(mr_errcode);
2760 /** set_pop_usage - incr/decr usage count for pop server in serverhosts talbe
2764 ** delta (will be +/- 1)
2767 ** - incr/decr value field in serverhosts table for pop/mach_id
2771 static int set_pop_usage(id, count)
2775 ## int mach_id = id;
2778 ## repeat replace serverhosts (value1 = serverhosts.value1 + @n)
2779 ## where serverhosts.service = "POP" and serverhosts.#mach_id = @mach_id
2781 if (ingres_errno) return(mr_errcode);
2787 /* Validation Routines */
2789 validate_row(q, argv, v)
2790 register struct query *q;
2792 register struct validate *v;
2800 /* build where clause */
2801 build_qual(v->qual, v->argc, argv, qual);
2803 /* setup ingres variables */
2808 if (log_flags & LOG_VALID)
2809 /* tell the logfile what we're doing */
2810 com_err(whoami, 0, "validating row: %s", qual);
2812 /* look for the record */
2813 ## range of rvar is table
2814 ## retrieve (rowcount = count(rvar.name where qual))
2815 if (ingres_errno) return(mr_errcode);
2816 if (rowcount == 0) return(MR_NO_MATCH);
2817 if (rowcount > 1) return(MR_NOT_UNIQUE);
2821 validate_fields(q, argv, vo, n)
2823 register char *argv[];
2824 register struct valobj *vo;
2827 register int status;
2832 if (log_flags & LOG_VALID)
2833 com_err(whoami, 0, "validating %s in %s: %s",
2834 vo->namefield, vo->table, argv[vo->index]);
2835 status = validate_name(argv, vo);
2839 if (log_flags & LOG_VALID)
2840 com_err(whoami, 0, "validating %s in %s: %s",
2841 vo->idfield, vo->table, argv[vo->index]);
2842 status = validate_id(argv, vo);
2846 if (log_flags & LOG_VALID)
2847 com_err(whoami, 0, "validating date: %s", argv[vo->index]);
2848 status = validate_date(argv, vo);
2852 if (log_flags & LOG_VALID)
2853 com_err(whoami, 0, "validating %s type: %s",
2854 vo->table, argv[vo->index]);
2855 status = validate_type(argv, vo);
2859 if (log_flags & LOG_VALID)
2860 com_err(whoami, 0, "validating typed data (%s): %s",
2861 argv[vo->index - 1], argv[vo->index]);
2862 status = validate_typedata(q, argv, vo);
2866 if (log_flags & LOG_VALID)
2867 com_err(whoami, 0, "validating rename %s in %s",
2868 argv[vo->index], vo->table);
2869 status = validate_rename(argv, vo);
2873 if (log_flags & LOG_VALID)
2874 com_err(whoami, 0, "validating chars: %s", argv[vo->index]);
2875 status = validate_chars(argv[vo->index]);
2883 status = lock_table(vo);
2887 if (status != MR_EXISTS) return(status);
2891 if (ingres_errno) return(mr_errcode);
2896 /* validate_chars: verify that there are no illegal characters in
2897 * the string. Legal characters are printing chars other than
2898 * ", *, ?, \, [ and ].
2900 static int illegalchars[] = {
2901 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* ^@ - ^O */
2902 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* ^P - ^_ */
2903 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, /* SPACE - / */
2904 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, /* 0 - ? */
2905 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* @ - O */
2906 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, /* P - _ */
2907 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* ` - o */
2908 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, /* p - ^? */
2909 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2910 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2911 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2912 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2913 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2914 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2915 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2916 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2923 if (illegalchars[*s++])
2924 return(MR_BAD_CHAR);
2929 validate_id(argv, vo)
2931 register struct valobj *vo;
2937 ## int id, rowcount;
2942 name = argv[vo->index];
2944 namefield = vo->namefield;
2945 idfield = vo->idfield;
2947 if ((!strcmp(table, "users") && !strcmp(namefield, "login")) ||
2948 !strcmp(table, "machine") ||
2949 !strcmp(table, "filesys") ||
2950 !strcmp(table, "list") ||
2951 !strcmp(table, "cluster") ||
2952 !strcmp(table, "string")) {
2953 if (!strcmp(table, "machine"))
2954 for (c = name; *c; c++) if (islower(*c)) *c = toupper(*c);
2955 status = name_to_id(name, table, &id);
2957 *(int *)argv[vo->index] = id;
2959 } else if (status == MR_NO_MATCH || status == MR_NOT_UNIQUE)
2965 if (!strcmp(namefield, "uid")) {
2966 ## retrieve (id = table.idfield) where table.namefield = int4(name)
2967 if (ingres_errno) return(mr_errcode);
2968 ## inquire_equel (rowcount = "rowcount")
2970 ## retrieve (id = table.idfield) where table.namefield = name
2971 if (ingres_errno) return(mr_errcode);
2972 ## inquire_equel (rowcount = "rowcount")
2974 if (rowcount != 1) return(vo->error);
2975 *(int *)argv[vo->index] = id;
2979 validate_name(argv, vo)
2981 register struct valobj *vo;
2989 name = argv[vo->index];
2991 namefield = vo->namefield;
2992 if (!strcmp(table, "servers") && !strcmp(namefield, "name")) {
2993 for (c = name; *c; c++)
2997 ## retrieve (rowcount = countu(table.namefield
2998 ## where table.namefield = name))
2999 if (ingres_errno) return(mr_errcode);
3000 return ((rowcount == 1) ? MR_EXISTS : vo->error);
3003 validate_date(argv, vo)
3011 idate = argv[vo->index];
3013 ## retrieve (dd = interval("years", date(idate) - date("today")))
3014 ## inquire_equel (errorno = "errorno")
3015 if (errorno != 0 || dd > 5.0) return(MR_DATE);
3020 validate_rename(argv, vo)
3024 ## char *name, *table, *namefield, *idfield;
3029 c = name = argv[vo->index];
3031 if (illegalchars[*c++])
3032 return(MR_BAD_CHAR);
3034 /* minor kludge to upcasify machine names */
3035 if (!strcmp(table, "machine"))
3036 for (c = name; *c; c++) if (islower(*c)) *c = toupper(*c);
3037 namefield = vo->namefield;
3038 idfield = vo->idfield;
3041 if (!strcmp(argv[vo->index], argv[vo->index - 1]))
3043 ## retrieve (id = any(table.namefield where table.namefield = name))
3044 if (ingres_errno) return(mr_errcode);
3050 status = name_to_id(name, table, &id);
3051 if (status == MR_NO_MATCH || id == *(int *)argv[vo->index - 1])
3058 validate_type(argv, vo)
3060 register struct valobj *vo;
3067 typename = vo->table;
3068 c = value = argv[vo->index];
3070 if (illegalchars[*c++])
3071 return(MR_BAD_CHAR);
3073 /* uppercase type fields */
3074 for (c = value; *c; c++) if (islower(*c)) *c = toupper(*c);
3076 ## repeat retrieve (exists = any(alias.trans where alias.name = @typename and
3077 ## alias.type = "TYPE" and alias.trans = @value))
3078 if (ingres_errno) return(mr_errcode);
3079 return (exists ? MR_EXISTS : vo->error);
3082 /* validate member or type-specific data field */
3084 validate_typedata(q, argv, vo)
3085 register struct query *q;
3086 register char *argv[];
3087 register struct valobj *vo;
3090 ## char *field_type;
3091 ## char data_type[129];
3092 ## int id, rowcount;
3097 /* get named object */
3098 name = argv[vo->index];
3100 /* get field type string (known to be at index-1) */
3101 field_type = argv[vo->index-1];
3103 /* get corresponding data type associated with field type name */
3104 ## repeat retrieve (data_type = alias.trans)
3105 ## where alias.#name = @field_type and alias.type = "TYPEDATA"
3106 if (ingres_errno) return(mr_errcode);
3107 ## inquire_equel (rowcount = "rowcount")
3108 if (rowcount != 1) return(MR_TYPE);
3110 /* now retrieve the record id corresponding to the named object */
3111 if (index(data_type, ' '))
3112 *index(data_type, ' ') = 0;
3113 if (!strcmp(data_type, "user")) {
3115 status = name_to_id(name, data_type, &id);
3116 if (status && (status == MR_NO_MATCH || status == MR_NOT_UNIQUE))
3118 if (status) return(status);
3119 } else if (!strcmp(data_type, "list")) {
3121 status = name_to_id(name, data_type, &id);
3122 if (status && status == MR_NOT_UNIQUE)
3124 if (status == MR_NO_MATCH) {
3125 /* if idfield is non-zero, then if argv[0] matches the string
3126 * that we're trying to resolve, we should get the value of
3127 * values.[idfield] for the id.
3129 if (vo->idfield && !strcmp(argv[0], argv[vo->index])) {
3130 set_next_object_id(q->validate->object_id, q->rtable);
3132 ## repeat retrieve (id = values.value) where values.#name = @name
3133 ## inquire_equel(rowcount = "rowcount")
3134 if (rowcount != 1) return(MR_LIST);
3137 } else if (status) return(status);
3138 } else if (!strcmp(data_type, "machine")) {
3140 for (c = name; *c; c++) if (islower(*c)) *c = toupper(*c);
3141 status = name_to_id(name, data_type, &id);
3142 if (status && (status == MR_NO_MATCH || status == MR_NOT_UNIQUE))
3144 if (status) return(status);
3145 } else if (!strcmp(data_type, "string")) {
3147 status = name_to_id(name, data_type, &id);
3148 if (status && status == MR_NOT_UNIQUE)
3150 if (status == MR_NO_MATCH) {
3151 if (q->type != APPEND && q->type != UPDATE) return(MR_STRING);
3152 ## retrieve (id = values.value) where values.#name = "strings_id"
3154 ## replace values (value = id) where values.#name = "strings_id"
3155 ## append to strings (string_id = id, string = name)
3156 } else if (status) return(status);
3157 } else if (!strcmp(data_type, "none")) {
3163 /* now set value in argv */
3164 *(int *)argv[vo->index] = id;
3170 /* Lock the table named by the validation object */
3175 ## char *table, *idfield;
3179 idfield = vo->idfield;
3180 ## replace table (modtime = "now") where table.idfield = 0
3181 if (ingres_errno) return(mr_errcode);
3182 ## inquire_equel (rowcount = "rowcount")
3190 /* Check the database at startup time. For now this just resets the
3191 * inprogress flags that the DCM uses.
3194 sanity_check_database()