6 * Copyright (C) 1987 by the Massachusetts Institute of Technology
9 * Revision 1.12 1987-08-29 00:05:54 mike
10 * Fixed bug in check_nfs.
11 * Added code to upcasify machine names in validate_id.
13 Revision 1.11 87/08/28 14:55:45 mike
14 Modified delete_locker to require only one argument, the login name.
15 Modified get_groups_of_all_users and get_all_poboxes to disable INGRES
18 Revision 1.10 87/08/25 15:56:54 mike
19 - Fixed bugs in get_groups_of_all_users
20 - Added tblstats updates to add_user_group
21 - Added routines: add_hostaccess (ashi), delete_hostaccess (dshi),
22 followup_ushp, and followup_usha
24 Revision 1.9 87/08/22 17:41:34 wesommer
25 More of Mike's changes.
27 Revision 1.8 87/08/18 15:05:20 wesommer
28 Fixed definition of add_locker.
30 Revision 1.7 87/08/04 01:49:41 wesommer
33 Revision 1.6 87/08/04 01:10:02 wesommer
34 Changes by mike; checked in prior to my hacking.
36 Revision 1.5 87/07/30 14:54:13 wesommer
37 Added debugging code in an attempt to catch a flakey problem.
39 Revision 1.4 87/07/30 00:30:21 wesommer
40 replaced appends = appends+1 with appends = tbs.appends+1
42 Revision 1.3 87/07/30 00:26:11 wesommer
43 Changes by mike prior to "appends" fix.
45 Revision 1.2 87/07/29 16:00:39 wesommer
48 Revision 1.1 87/07/29 15:13:57 wesommer
54 static char *rcsid_qsupport_qc = "$Header$";
58 #include "sms_server.h"
65 /* Specialized Access Routines */
68 ** access_user - verify that client name equals specified login name
70 ** Used by: update_user_shell
71 ** update_finger_by_login
73 ** - since field validation routines are called first, a users_id is
74 ** now in argv[0] instead of the login name. Therefore, we must
75 ** convert the client name to a users_id.
78 access_user(q, argv, cl)
83 register struct krbname *krb;
88 client_name = cl->kname.name;
89 ## repeat retrieve (client_id = users.users_id)
90 ## where users.login = @client_name
91 ## inquire_equel (rowcount = "rowcount")
92 if (rowcount != 1) return(SMS_PERM);
93 if (client_id != *(int *)argv[0]) return(SMS_PERM);
99 ** access_pop - same as access_user plus verifies that a user has only one
100 ** mailbox of type "POP"
103 ** argv[0] - users_id
109 ** - if q->name = "add_pobox" and type = "POP",
110 ** verify that no POP box already exists for user
111 ** - call access_user
115 access_pop(q, argv, cl)
125 if (!bcmp(q->name, "add_pobox", 10) && !bcmp(argv[1], "POP", 4)) {
126 users_id = *(int *)argv[0];
127 mach_id = *(int *)argv[2];
129 ## range of p is pobox
130 ## repeat retrieve (exists = any(p.#box where p.#users_id = @users_id
131 ## and p.type = "POP"
132 ## and p.#mach_id = @mach_id
133 ## and p.#box = @box))
134 if (exists) return(SMS_EXISTS);
137 return(access_user(q, argv, cl));
141 ** access_list - check access for adding or deleting list members
143 ** Inputs: argv[0] - list_id
144 ** cl->krb.name - client name
146 ** - check that client is a member of the access control list
147 ** - OR, if q->shortname == {amtl | dfml} and
148 ** if list.flags & LF_PUBLIC, allow access if client = member
152 access_list(q, argv, cl)
166 list_id = *(int *)argv[0];
167 ## repeat retrieve (acl_id = list.#acl_id, flags = list.#flags)
168 ## where list.#list_id = @list_id
170 /* parse client structure */
171 status = get_client(cl, &client_type, &client_id);
172 if (status != SMS_SUCCESS) return(status);
174 /* if amtl or dmfl and list is public allow client to add or delete self */
175 if (!bcmp("amtl", q->shortname, 4) || !bcmp("dmfl", q->shortname, 4)) {
176 if ((flags & LF_PUBLIC) && !bcmp("USER", argv[1], 4)) {
177 member_id = *(int *)argv[2];
178 if (member_id == client_id) return(SMS_SUCCESS);
182 /* check for client in access control list */
183 exists = find_member(acl_id, client_type, client_id, 0);
184 if (!exists) return(SMS_PERM);
190 ** access_maillist - access_list + disallow adding user-group to maillists
197 access_maillist(q, argv, cl)
204 ## char list_name[32];
207 status = access_list(q, argv, cl);
208 if (status != SMS_SUCCESS) return(status);
209 if (bcmp(q->name, "add_maillist", 12)) return(status);
211 list_id = *(int *)argv[0];
212 ## range of g is groups
213 ## repeat retrieve (exists = any(g.#list_id where g.#list_id = @list_id))
214 if (!exists) return(SMS_SUCCESS);
215 ## repeat retrieve (list_name = list.name) where list.#list_id = @list_id
216 ## repeat retrieve (exists = any(users.login where users.login = @list_name))
217 return ((exists) ? SMS_USER_GROUP : SMS_SUCCESS);
221 ** Setup routine for add_group
225 ** Description: allocate next gid and store in values table
229 setup_add_group(q, argv, cl, access_check)
239 status = access_list(q, argv, cl);
241 if (status != SMS_SUCCESS || access_check) return(status);
243 ## range of g is groups
244 ## range of v is values
245 ## repeat retrieve (ngid = v.value) where v.name = "gid"
249 ## repeat retrieve (exists = any(g.#gid where g.#gid = @ngid))
252 ## repeat replace v (value = @ngid) where v.name = "gid"
257 ** Setup routine for add_user
259 ** Inputs: argv[0] - login
264 ** - if argv[1] == "#" then set argv[1] = next(uid)
265 ** - if argv[0] == "#" then set argv[0] = "#<uid>"
269 setup_add_user(q, argv, cl, access_check)
271 register char *argv[];
278 if (access_check) return(SMS_SUCCESS);
280 if (!bcmp(argv[1], "#", 2)) {
281 ## range of u is users
282 ## range of v is values
283 ## repeat retrieve (nuid = v.value) where v.name = "uid"
287 ## repeat retrieve (exists = any(u.#uid where u.#uid = @nuid))
289 ## repeat replace v (value = @nuid) where v.name = "uid"
290 sprintf(argv[1], "%d", nuid);
293 if (!bcmp(argv[0], "#", 2)) {
294 sprintf(argv[0], "#%s", argv[1]);
301 ** followup_add_user - add finger entry, set_user_modtime
302 ** followup_delete_user - delete finger entry
305 ** argv[0] - login (add_user)
306 ** argv[0] - users_id (delete_user)
310 followup_add_user(q, argv)
319 ## char fullname[128];
325 /* get user information */
326 ## range of u is users
327 ## repeat retrieve (users_id = u.#users_id, last = u.#last,
328 ## first = u.#first, middle = u.#middle)
329 ## where u.#login = @login
334 while (*cp1) *cp2++ = *cp1++;
337 if (*cp1 == 0) cp2--;
338 while (*cp1) *cp2++ = *cp1++;
341 while (*cp2++ = *cp1++) ;
343 /* create a finger entry */
344 ## repeat append finger (#users_id = @users_id, #fullname = @fullname)
346 /* set modtime (creation time) on user */
347 ## repeat replace u (modtime = "now") where u.#users_id = @users_id
352 followup_delete_user(q, argv)
358 users_id = *(int *)argv[0];
359 ## repeat delete finger where finger.#users_id = @users_id
364 ** setup_add_filesys - verify existance of referenced file systems
365 ** setup_update_filesys - same, except argv[1..5] --> argv[2..6]
367 ** Inputs: Add Update
368 ** argv[0] - label label
369 ** argv[1] - type new label
370 ** argv[2] - mach_id type
371 ** argv[3] - name mach_id
372 ** argv[4] - mount name
373 ** argv[5] - access mount
378 ** * verify mach_id/name in rvdvirt
379 ** * verify access in {r, x, R, X}
381 ** * extract directory prefix from name
382 ** * verify mach_id/dir in nfsphys
383 ** * verify access in {r, w, R, W}
386 ** SMS_RVD - no such rvd
387 ** SMS_NFS - specified directory not exported
388 ** SMS_FILESYS_ACCESS - invalid filesys access
392 setup_add_filesys(q, argv)
402 mach_id = *(int *)argv[2];
406 if (!bcmp(type, "RVD", 3))
407 return (check_rvd(mach_id, name, access));
408 else if (!bcmp(type, "NFS", 3))
409 return (check_nfs(mach_id, name, access));
414 setup_update_filesys(q, argv)
424 mach_id = *(int *)argv[3];
428 if (!bcmp(type, "RVD", 3))
429 return (check_rvd(mach_id, name, access));
430 else if (!bcmp(type, "NFS", 3))
431 return (check_nfs(mach_id, name, access));
436 ##check_rvd(mach_id, name, access)
444 ## range of rv is rvdvirt
445 ## retrieve (rowcount = any(rv.#name where rv.#mach_id = mach_id and
447 if (rowcount == 0) return(SMS_RVD);
449 caccess = (isupper(*access)) ? tolower(*access) : *access;
450 if (caccess != 'r' && caccess != 'x') return(SMS_FILESYS_ACCESS);
455 ##check_nfs(mach_id, name, access)
467 caccess = (isupper(*access)) ? tolower(*access) : *access;
468 if (caccess != 'r' && caccess != 'w') return(SMS_FILESYS_ACCESS);
471 ## range of np is nfsphys
472 ## retrieve (dir = np.#dir) where np.#mach_id = mach_id
477 if (*cp1++ != *cp2) break;
481 status = SMS_SUCCESS;
489 /* Followup Routines */
491 set_user_modtime(q, argv)
498 ## repeat replace u (modtime = "now") where u.#login = @login
502 set_user_modtime_by_id(q, argv)
508 users_id = *(int *)argv[0];
509 ## repeat replace users (modtime = "now") where users.#users_id = @users_id
513 set_list_modtime(q, argv)
520 ## repeat replace list (modtime = "now") where list.name = @list_name
524 set_list_modtime_by_id(q, argv)
530 list_id = *(int *)argv[0];
531 ## repeat replace list (modtime = "now") where list.#list_id = @list_id
535 set_finger_modtime(q, argv)
541 users_id = *(int *)argv[0];
542 ## repeat replace f (modtime = "now") where f.#users_id = @users_id
547 ** followup_amtl - followup for amtl and dmfl; when adding a list
548 ** member to a maillist, add list to maillist table,
549 ** unless list is a user-group.
550 ** Then set_list_modtime_by_id.
554 ** argv[1] - member_type
555 ** argv[2] - member_id
559 followup_amtl(q, argv)
566 ## char list_name[33];
568 list_id = *(int *)argv[0];
570 ## repeat replace list (modtime = "now") where list.#list_id = @list_id
572 /* if query is not amtl or if member_type is not LIST then return */
573 if (bcmp(q->shortname, "amtl", 4) || bcmp(argv[1], "LIST", 4))
576 member_id = *(int *)argv[2];
577 ## range of l is list
578 ## range of ml is maillists
579 ## range of g is groups
581 /* is parent list a mailing list? */
582 ## repeat retrieve (exists = any(ml.#list_id where ml.#list_id=@list_id))
584 /* if not then return */
585 if (!exists) return(SMS_SUCCESS);
587 /* is member_list a user-group? */
589 ## repeat retrieve (exists = any(g.#list_id where g.#list_id = @member_id))
592 ## repeat retrieve (list_name = l.#name) where l.#list_id = @member_id
593 /* is list_name a username? */
594 ## repeat retrieve (exists = any(users.login
595 ## where users.login = @list_name))
596 /* yes, return error */
597 if (exists) return(SMS_USER_GROUP);
600 /* list is not a user-group; add list to maillist table */
601 ## repeat append maillists (#list_id = @member_id, ltid = l.tid)
602 ## where l.#list_id = @member_id
608 ** followup_add_pobox
609 ** followup_delete_pobox - followup routines for pobox queries
612 ** add_pobox: set pobox creation time
613 ** increment pop usage in serverhosts
615 ** delete_pobox: decrement pop usage in serverhosts
619 followup_add_pobox(q, argv)
623 set_pobox_creation(q, argv);
624 set_pop_usage(q, argv, 1);
628 followup_delete_pobox(q, argv)
632 set_pop_usage(q, argv, -1);
636 set_pobox_creation(q, argv)
645 users_id = *(int *)argv[0];
647 mach_id = *(int *)argv[2];
650 ## range of p is pobox
651 ## repeat replace p (created = "now")
652 ## where p.#users_id = @users_id and p.#type = @type and
653 ## p.#mach_id = @mach_id and p.#box = @box
655 return (SMS_SUCCESS);
659 ** set_pop_usage - incr/decr usage count for pop server in serverhosts talbe
662 ** q->name - "add_pobox" or "delete_pobox"
667 ** - incr/decr value field in serverhosts table for pop/mach_id
671 set_pop_usage(q, argv, count)
678 if (bcmp(argv[1], "POP", 3)) return(SMS_SUCCESS);
680 mach_id = *(int *)argv[2];
683 ## range of sh is serverhosts
684 ## repeat replace sh (value1 = sh.value1 + @n)
685 ## where sh.service = "pop" and sh.#mach_id = @mach_id
691 ** delete_user_poboxes - delete all poboxes for a user
694 ** argv[0] - users_id
698 delete_user_poboxes(q, argv)
708 users_id = *(int *)argv[0];
710 /* get machine ids for pop server(s) on which the user currently exists */
711 ## range of p is pobox
713 ## repeat retrieve (mach_id = p.#mach_id)
714 ## where p.#users_id = @users_id and p.type = "POP"
716 mach_ids[i++] = mach_id;
722 /* decrement counts on serverhost entries */
723 ## range of sh is serverhosts
725 mach_id = mach_ids[i];
726 ## repeat replace sh (value1 = sh.value1 - 1)
727 ## where sh.service = "pop" and sh.#mach_id = @mach_id
730 /* delete user's poboxes */
731 ## repeat delete p where p.#users_id = @users_id
739 ** delete_current_quota - adjust nfsphys values on xxx_quota queries.
744 ** argv[2] - users_id
745 ** argv[3] - quota (add_new_quota only)
748 ** delete_current_quota:
749 ** - find nfsquota entry
750 ** - decrement nfsphys.allocated by nfsquota.quota
752 ** - increment nfsphys.allocated by quota
756 add_new_quota(q, argv)
758 register char *argv[];
764 mach_id = *(int*)argv[0];
766 quota = *(int *)argv[3];
768 ## range of np is nfsphys
769 ## repeat replace np (allocated = np.allocated + @quota)
770 ## where np.#mach_id = @mach_id and np.#device = @device
775 delete_current_quota(q, argv, cl, access_check)
777 register char *argv[];
786 if (access_check) return(SMS_SUCCESS);
788 mach_id = *(int *)argv[0];
790 users_id = *(int *)argv[2];
792 ## range of np is nfsphys
793 ## range of nq is nfsquota
794 ## repeat retrieve (quota = nq.#quota)
795 ## where nq.#mach_id = @mach_id and nq.#device = @device and
796 ## nq.#users_id = @users_id
797 ## repeat replace np (allocated = np.allocated - @quota)
798 ## where np.#mach_id = @mach_id and np.#device = @device
804 ** add_hostaccess - create entry in hostaccess table upon adding a new
805 ** machine to the serverhosts table where service =
814 add_hostaccess(q, argv)
820 /* only work with service = "hostaccess" */
821 if (bcmp(argv[0], "hostaccess", 10)) return(SMS_SUCCESS);
823 mach_id = *(int *)argv[1];
824 ## repeat append hostaccess (#mach_id = @mach_id, status = 0)
825 ## repeat replace tblstats (modtime = "now", appends = tblstats.appends + 1)
826 ## where tblstats.table = "hostaccess"
830 /* followup to delete_server_host_info */
832 delete_hostaccess(q, argv)
838 /* only work with service = "hostaccess" */
839 if (bcmp(argv[0], "hostaccess", 10)) return(SMS_SUCCESS);
841 mach_id = *(int *)argv[1];
842 ## repeat delete hostaccess where hostaccess.#mach_id = @mach_id
843 ## repeat replace tblstats (modtime = "now", deletes = tblstats.deletes + 1)
844 ## where tblstats.table = "hostaccess"
848 followup_ushp(q, argv)
855 mach_id = *(int *)argv[0];
856 ## range of ha is hostaccess
857 ## repeat retrieve (status = ha.#status) where ha.#mach_id = @mach_id
859 ## repeat replace ha (#status = @status) where ha.#mach_id = @mach_id
863 followup_usha(q, argv)
870 mach_id = *(int *)argv[0];
871 ## range of ha is hostaccess
872 ## repeat retrieve (status = ha.#status) where ha.#mach_id = @mach_id
874 ## repeat replace ha (#status = @status) where ha.#mach_id = @mach_id
879 ** delete_list_members - called after the delete_list query to clean up
882 ** Inputs: argv[0] - list_id
885 ** - foreach string member: decr string refc; ifzero, delete string
886 ** - delete all members entries for this list_id
890 delete_list_members(q, argv)
892 register char *argv[];
898 struct save_queue *sq;
899 struct save_queue *sq_create();
901 list_id = *(int *)argv[0];
904 ## range of m is members
905 ## repeat retrieve (string_id = m.member_id)
906 ## where m.#list_id = @list_id and m.member_type = "STRING"
908 sq_save_data(sq, string_id);
911 while (sq_get_data(sq, &string_id)) {
912 ## range of s is strings
913 ## repeat retrieve (refc = s.#refc) where s.#string_id = @string_id
914 ## inquire_equel (rowcount = "rowcount")
915 if (rowcount == 0) continue;
917 ## repeat delete s where s.#string_id = @string_id
919 ## repeat replace s (#refc = @refc) where s.#string_id = @string_id
924 ## repeat delete m where m.#list_id = @list_id
930 ** followup_grvd - Support routine for get_rvd_servers query
933 ** q - grvd query structure
934 ** sq - save_queue struture: contains list of {machine, oper_acl_id,
935 ** admin_acl_id, shutdown_acl_id} records.
936 ** v - validate structure (not used)
937 ** action - action routine
938 ** actarg - action routine argument
941 ** - translate acl_ids to list names
945 followup_grvd(q, sq, v, action, actarg)
947 struct save_queue *sq;
956 ## char shutdown[33];
963 ## range of l is list
965 while (sq_get_data(sq, &argv)) {
966 sscanf(argv[0], "%d", &list_id);
967 ## repeat retrieve (oper = l.name) where l.#list_id = @list_id
968 sscanf(argv[1], "%d", &list_id);
969 ## repeat retrieve (admin = l.name) where l.#list_id = @list_id
970 sscanf(argv[2], "%d", &list_id);
971 ## repeat retrieve (shutdown = l.name) where l.#list_id = @list_id
973 (*action)(3, targv, actarg);
983 followup_gars(q, sq, v, action, actarg)
985 struct save_queue *sq;
994 ## char shutdown[33];
1001 ## range of l is list
1003 while (sq_get_data(sq, &argv)) {
1004 sscanf(argv[1], "%d", &list_id);
1005 ## repeat retrieve (oper = l.name) where l.#list_id = @list_id
1006 sscanf(argv[2], "%d", &list_id);
1007 ## repeat retrieve (admin = l.name) where l.#list_id = @list_id
1008 sscanf(argv[3], "%d", &list_id);
1009 ## repeat retrieve (shutdown = l.name) where l.#list_id = @list_id
1012 (*action)(4, targv, actarg);
1020 return(SMS_SUCCESS);
1024 ** set_next_object_id - set next object id in values table
1026 ** Inputs: object - object name in values table
1028 ** - called before an APPEND operation to set the next object id to
1029 ** be used for the new record
1033 set_next_object_id(object)
1039 ## range of v is values
1040 ## repeat replace v (value = v.value + 1) where v.#name = @name
1041 return(SMS_SUCCESS);
1045 ** get_query_need - check modtime of query's associated table against given
1046 ** time and return true if greater (false if not)
1049 ** argv[0] - query name
1050 ** argv[1] - time to compare against
1054 get_query_need(q, argv, action, actarg)
1056 register char *argv[];
1060 ## char *last_get_time;
1064 struct query *get_query_by_name();
1066 q1 = get_query_by_name(argv[0]);
1068 last_get_time = argv[1];
1071 if (q1->type != RETRIEVE) return(SMS_NO_MATCH);
1073 ## range of tbs is tblstats
1074 ## repeat retrieve (need = any(tbs.modtime where tbs.#table = @table and
1075 ## tbs.modtime > @last_get_time))
1077 result = (need) ? "true" : "false";
1078 (*action)(1, &result, actarg);
1079 return(SMS_SUCCESS);
1083 ** get_list_is_group
1084 ** get_list_is_maillist
1087 ** argv[0] - list_id
1094 get_list_is_group(q, argv, action, actarg)
1104 list_id = *(int *)argv[0];
1106 ## range of g is groups
1107 ## repeat retrieve (exists = any(g.#list_id where g.#list_id = @list_id))
1109 result = (exists) ? "true" : "false";
1110 (*action)(1, &result, actarg);
1111 return(SMS_SUCCESS);
1114 get_list_is_maillist(q, argv, action, actarg)
1124 list_id = *(int *)argv[0];
1126 ## range of ml is maillists
1127 ## repeat retrieve (exists = any(ml.#list_id where ml.#list_id = @list_id))
1129 result = (exists) ? "true" : "false";
1130 (*action)(1, &result, actarg);
1131 return(SMS_SUCCESS);
1136 ** add_locker - special query routine for creating a user locker
1139 ** argv[0] - users_id
1140 ** argv[1] - machine_id
1142 ** argv[3] - initial quota
1145 ** - get prefix directory (dir) for mount point on specified machine/device
1146 ** - create filesys entry (label=<login>, type=NFS, machine=<machine>,
1147 ** mount=<dir>/<login>, access=w, acl=dbadmin)
1148 ** - increment allocated in nfsphys by quota
1149 ** - create nfsquota entry
1152 ** - SMS_NFSPHYS - machine/device does not exist in nfsphys
1153 ** - SMS_FILESYS_EXISTS - file system already exists
1158 register struct query *q;
1173 /* copy arguments */
1174 users_id = *(int *)argv[0];
1175 mach_id = *(int *)argv[1];
1177 sscanf(argv[3], "%d", "a);
1179 ## range of u is users
1180 ## range of f is filesys
1181 ## range of np is nfsphys
1182 ## range of tbs is tblstats
1184 /* get login name */
1185 ## repeat retrieve (login = u.#login) where u.#users_id = @users_id
1187 /* get user's acl id */
1188 ## repeat retrieve (user_acl = list.list_id) where list.name = @login
1190 /* get filesystem directory prefix; give error if machine/device
1191 pair not in nfsphys table */
1192 printf("np.mach_id = %d and np.device = %s\n", mach_id, device);
1194 ## repeat retrieve (dir = np.#dir, allocated = np.#allocated)
1195 ## where np.#mach_id = @mach_id and np.#device = @device
1196 ## inquire_equel (rowcount = "rowcount")
1197 if (rowcount == 0) return(SMS_NFSPHYS);
1199 /* make sure a filesys with user's name does not already exist */
1200 ## repeat retrieve (rowcount = any(f.label where f.label = @login))
1201 if (rowcount != 0) return(SMS_FILESYS_EXISTS);
1203 /* create a new filesys */
1204 sprintf(locker, "%s/%s", dir, login);
1205 sprintf(mount, "/mit/%s", login);
1206 ## repeat append filesys
1207 ## (#label = @login, type = "NFS", #mach_id = @mach_id,
1208 ## name = @locker, access = "w", order = 1, #mount = @mount,
1209 ## acl_id = @user_acl)
1210 ## repeat replace tbs (appends = tbs.appends + 1, modtime = "now")
1211 ## where tbs.table = "filesys"
1213 /* increment usage count in nfsphys table */
1215 ## replace np (#allocated = allocated)
1216 ## where np.#mach_id = mach_id and np.#device = device
1217 ## repeat replace tbs (updates = tbs.updates + 1, modtime = "now")
1218 ## where tbs.table = "nfsphys"
1220 /* create nfsquota entry */
1221 ## append nfsquota (#users_id = users_id, #mach_id = mach_id,
1222 ## #device = device, #quota = quota)
1223 ## repeat replace tbs (appends = tbs.appends + 1, modtime = "now")
1224 ## where tbs.table = "nfsquota"
1226 return(SMS_SUCCESS);
1230 ** delete_locker - special query routine for deleting a user locker
1233 ** argv[0] - users_id
1236 ** - get login name from users_id
1237 ** - get filesys entry from login
1238 ** - use filesys.mach_id and filesys.name to determine machine/device
1239 ** pair for nfsphys and nfsquota
1240 ** - delete filesys entry (label=<login>)
1241 ** - decrement allocated in nfsphys by quota
1242 ** - delete nfsquota entry
1245 ** - SMS_FILESYS - no filesys exists for user
1249 delete_locker(q, argv)
1250 register struct query *q;
1251 register char *argv[];
1262 /* copy arguments */
1263 users_id = *(int *)argv[0];
1265 ## range of u is users
1266 ## range of f is filesys
1267 ## range of np is nfsphys
1268 ## range of nq is nfsquota
1269 ## range of tbs is tblstats
1271 /* get login name */
1272 ## repeat retrieve (login = u.#login) where u.#users_id = @users_id
1274 /* get mach_id and locker name from filesys entry; then delete it */
1275 ## repeat retrieve (mach_id = f.#mach_id, lname = f.#name)
1276 ## where f.#label = @login
1277 ## inquire_equel (rowcount = "rowcount")
1278 if (rowcount == 0) return(SMS_FILESYS);
1279 ## repeat delete f where f.#label = @login
1281 /* get prefix directory */
1282 c = (char *)rindex(lname, '/');
1285 /* get nfs device */
1286 ## repeat retrieve (ndev = np.device)
1287 ## where np.#mach_id = @mach_id and np.dir = @lname
1289 /* get quota from nfsquota entry; then delete entry */
1290 ## repeat retrieve (quota = nq.#quota)
1291 ## where nq.#mach_id = @mach_id and nq.#device = @ndev and
1292 ## nq.#users_id = @users_id
1293 ## repeat delete nq where nq.#mach_id = @mach_id and nq.#device = @ndev and
1294 ## nq.#users_id = @users_id
1296 /* decrement nfsphys.allocated */
1297 ## repeat replace np (allocated = np.allocated - @quota)
1298 ## where np.#mach_id = @mach_id and np.#device = @ndev
1300 /* adjust table statistics */
1301 ## repeat replace tbs (deletes = tbs.deletes + 1, modtime = "now")
1302 ## where tbs.table = "filesys"
1303 ## repeat replace tbs (updates = tbs.updates + 1, modtime = "now")
1304 ## where tbs.table = "nfsphys"
1305 ## repeat replace tbs (deletes = tbs.deletes + 1, modtime = "now")
1306 ## where tbs.table = "nfsquota"
1308 return(SMS_SUCCESS);
1312 ** add_user_group - create a group for a user and add user to group
1318 ** - verify specified user exists
1319 ** - create a list of same name as user
1320 ** - add user as a member of the list
1324 add_user_group(q, argv)
1336 /* verify user exists */
1337 ## repeat retrieve (users_id = users.#users_id) where users.#login = @login
1338 ## inquire_equel (exists = "rowcount")
1339 if (exists != 1) return(SMS_USER);
1341 /* verify list does not exist */
1342 ## repeat retrieve (exists = any(list.name where list.name = @login))
1343 if (exists) return(SMS_LIST);
1345 /* get new list_id */
1346 ## repeat retrieve (list_id = values.value) where values.name = "list_id"
1348 ## repeat replace values (value = @list_id) where values.name = "list_id"
1350 /* create the list */
1351 ## range of tbs is tblstats
1352 ## repeat append list (name = @login, #list_id = @list_id, flags = 1,
1353 ## desc = "User Group", acl_id = @list_id,
1354 ## expdate = "today" + "5 years", modtime = "now")
1355 ## repeat replace tbs (modtime = "now", appends = tbs.appends + 1)
1356 ## where tbs.table = "list"
1358 /* add user to list */
1359 ## repeat append members (#list_id = @list_id, member_type = "USER",
1360 ## member_id = @users_id)
1361 ## repeat replace tbs (modtime = "now", appends = tbs.appends + 1)
1362 ## where tbs.table = "members"
1365 ## range of g is groups
1366 ## range of v is values
1367 ## repeat retrieve (gid = v.value) where v.name = "gid"
1371 ## repeat retrieve (exists = any(g.#gid where g.#gid = @gid))
1373 ## repeat replace v (value = @gid) where v.name = "gid"
1375 /* add list to group table */
1376 ## repeat append groups (#list_id = @list_id, ltid = list.tid, #gid = @gid)
1377 ## where list.#list_id = @list_id
1378 ## repeat replace tbs (modtime = "now", appends = tbs.appends + 1)
1379 ## where tbs.table = "members"
1381 /* and we're done */
1382 return(SMS_SUCCESS);
1387 ** get_members_of_list - optimized query for retrieval of list members
1390 ** argv[0] - list_id
1393 ** - retrieve USER members, then LIST members, then STRING members
1397 get_members_of_list(q, argv, action, actarg)
1404 ## char member_name[129];
1407 list_id = *(int *)argv[0];
1409 targv[1] = member_name;
1411 ## range of m is members
1412 ## repeat retrieve (member_name = users.login)
1413 ## where m.#list_id = @list_id and m.member_type = "USER"
1414 ## and m.member_id = users.users_id
1415 ## sort by #member_name
1417 (*action)(2, targv, actarg);
1421 ## repeat retrieve (member_name = list.name)
1422 ## where m.#list_id = @list_id and m.member_type = "LIST"
1423 ## and m.member_id = list.#list_id
1424 ## sort by #member_name
1426 (*action)(2, targv, actarg);
1429 targv[0] = "STRING";
1430 ## repeat retrieve (member_name = strings.string)
1431 ## where m.#list_id = @list_id and m.member_type = "STRING"
1432 ## and m.member_id = strings.string_id
1433 ## sort by #member_name
1435 (*action)(2, targv, actarg);
1438 return(SMS_SUCCESS);
1442 ** get_groups_of_user - optimized query for retrieval of all groups to
1443 ** which a user belongs
1447 get_groups_of_user(q, argv, action, actarg)
1454 ## char list_name[33];
1459 users_id = *(int *)argv[0];
1460 targv[0] = list_name;
1463 ## range of m is members
1465 ## repeat retrieve (list_name = list.name, gid = text(groups.#gid))
1466 ## where m.member_id = @users_id and m.member_type = "USER" and
1467 ## m.list_id = groups.list_id and groups.ltid = list.tid
1468 ## sort by #list_name
1470 (*action)(2, targv, actarg);
1472 ## inquire_equel (rowcount = "rowcount")
1474 return ((rowcount = 0) ? SMS_NO_MATCH : SMS_SUCCESS);
1477 get_groups_of_all_users(q, argv, action, actarg)
1493 ## range of u is users
1494 ## range of l is list
1495 ## range of m is members
1496 ## range of g is groups
1498 ## set lockmode session where readlock = nolock
1500 ## repeat retrieve (login = u.#login, group = l.name, gid = text(g.#gid))
1501 ## where m.member_type = "USER" and m.member_id = u.users_id and
1502 ## u.status != 0 and m.list_id = g.list_id and
1504 ## sort by #login, #group
1506 (*action)(3, targv, actarg);
1509 ## inquire_equel (errorno = "errorno")
1510 ## set lockmode session where readlock = system
1512 return((errorno) ? SMS_INGRES_ERR : SMS_SUCCESS);
1516 ** get_all_poboxes - optimized query for retrieval of all poboxes
1519 ** - retrieve LOCAL boxes, then POP boxes, then FOREIGN boxes
1523 get_all_poboxes(q, argv, action, actarg)
1530 ## char machine[129];
1540 ## set lockmode session where readlock = nolock
1541 ## range of p is pobox
1542 ## repeat retrieve (login=users.#login, machine = #machine.name, box=p.#box)
1543 ## where p.type = "LOCAL" and p.users_id = users.users_id
1544 ## and p.mach_id = #machine.mach_id
1546 (*action)(4, targv, actarg);
1550 ## repeat retrieve (login=users.#login, machine = #machine.name, box=p.#box)
1551 ## where p.type = "POP" and p.users_id = users.users_id
1552 ## and p.mach_id = #machine.mach_id
1554 (*action)(4, targv, actarg);
1557 targv[1] = "FOREIGN";
1558 ## repeat retrieve (login=users.#login, machine=strings.string, box=p.#box)
1559 ## where p.type = "FOREIGN" and p.users_id = users.users_id
1560 ## and p.mach_id = strings.string_id
1562 (*action)(4, targv, actarg);
1564 ## set lockmode session where readlock = system
1566 return(SMS_SUCCESS);
1569 get_new_poboxes(q, argv, action, actarg)
1577 ## char machine[129];
1588 ## range of p is pobox
1589 ## repeat retrieve (login=users.#login, machine = #machine.name, box=p.#box)
1590 ## where p.type = "LOCAL" and p.users_id = users.users_id
1591 ## and p.mach_id = #machine.mach_id and
1592 ## p.#created > @created
1594 (*action)(4, targv, actarg);
1598 ## repeat retrieve (login=users.#login, machine = #machine.name, box=p.#box)
1599 ## where p.type = "POP" and p.users_id = users.users_id
1600 ## and p.mach_id = #machine.mach_id and
1601 ## p.#created > @created
1603 (*action)(4, targv, actarg);
1606 targv[1] = "FOREIGN";
1607 ## repeat retrieve (login=users.#login, machine=strings.string, box=p.#box)
1608 ## where p.type = "FOREIGN" and p.users_id = users.users_id
1609 ## and p.mach_id = strings.string_id and
1610 ## p.#created > @created
1612 (*action)(4, targv, actarg);
1615 return(SMS_SUCCESS);
1618 /* Validation Routines */
1620 validate_row(q, argv, v)
1621 register struct query *q;
1623 register struct validate *v;
1631 /* build where clause */
1632 build_qual(v->qual, v->argc, argv, qual);
1634 /* setup ingres variables */
1639 if (log_flags & LOG_RES)
1640 /* tell the logfile what we're doing */
1641 com_err(whoami, 0, "validating row: %s", qual);
1643 /* look for the record */
1644 ## range of rvar is table
1645 ## retrieve (rowcount = count(rvar.name where qual))
1646 if (rowcount == 0) return(SMS_NO_MATCH);
1647 if (rowcount > 1) return(SMS_NOT_UNIQUE);
1651 validate_fields(q, argv, vo, n)
1653 register char *argv[];
1654 register struct valobj *vo;
1657 register int status;
1662 if (log_flags & LOG_RES)
1663 com_err(whoami, 0, "validating %s in %s: %s",
1664 vo->namefield, vo->table, argv[vo->index]);
1665 status = validate_name(argv, vo);
1669 if (log_flags & LOG_RES)
1670 com_err(whoami, 0, "validating %s in %s: %s",
1671 vo->idfield, vo->table, argv[vo->index]);
1672 status = validate_id(argv, vo);
1676 if (log_flags & LOG_RES)
1677 com_err(whoami, 0, "validating date: %s", argv[vo->index]);
1678 status = validate_date(argv, vo);
1682 if (log_flags & LOG_RES)
1683 com_err(whoami, 0, "validating %s type: %s",
1684 vo->table, argv[vo->index]);
1685 status = validate_type(argv, vo);
1689 if (log_flags & LOG_RES)
1690 com_err(whoami, 0, "validating typed data (%s): %s",
1691 argv[vo->index - 1], argv[vo->index]);
1692 status = validate_typedata(q, argv, vo);
1696 status = SMS_EXISTS;
1700 status = SMS_EXISTS;
1705 if (status != SMS_EXISTS) return(status);
1709 return(SMS_SUCCESS);
1712 validate_id(argv, vo)
1714 register struct valobj *vo;
1724 name = argv[vo->index];
1726 /* minor kludge to upcasify machine names */
1727 if (!bcmp(table, "machine", 7))
1728 for (c = name; *c; c++) if (islower(*c)) *c = toupper(*c);
1729 namefield = vo->namefield;
1730 idfield = vo->idfield;
1731 ## retrieve (id = table.idfield) where table.namefield = name
1732 ## inquire_equel (rowcount = "rowcount")
1733 if (rowcount != 1) return(vo->error);
1734 *(int *)argv[vo->index] = id;
1738 validate_name(argv, vo)
1740 register struct valobj *vo;
1747 name = argv[vo->index];
1749 namefield = vo->namefield;
1750 ## retrieve (rowcount = countu(table.namefield
1751 ## where table.namefield = name))
1752 return ((rowcount == 1) ? SMS_EXISTS : vo->error);
1755 validate_date(argv, vo)
1763 idate = argv[vo->index];
1765 ## retrieve (dd = interval("years", date(idate) - date("today")))
1766 ## inquire_equel (errorno = "errorno")
1767 if (errorno != 0 || dd > 5.0) return(SMS_DATE);
1768 return(SMS_SUCCESS);
1771 validate_type(argv, vo)
1773 register struct valobj *vo;
1780 typename = vo->table;
1781 value = argv[vo->index];
1783 /* uppercase type fields */
1784 for (c = value; *c; c++) if (islower(*c)) *c = toupper(*c);
1786 ## range of a is alias
1787 ## repeat retrieve (rowcount = count(a.trans where a.name = @typename and
1788 ## a.type = "TYPE" and
1789 ## a.trans = @value))
1790 return ((rowcount == 1) ? SMS_EXISTS : vo->error);
1793 /* validate member or type-specific data field */
1795 validate_typedata(q, argv, vo)
1796 register struct query *q;
1797 register char *argv[];
1798 register struct valobj *vo;
1801 ## char *field_type;
1802 ## char data_type[17];
1808 /* get named object */
1809 name = argv[vo->index];
1811 /* get field type string (known to be at index-1) */
1812 field_type = argv[vo->index-1];
1814 /* get corresponding data type associated with field type name */
1815 ## repeat retrieve (data_type = alias.trans)
1816 ## where alias.#name = @field_type and alias.type = "TYPEDATA"
1817 ## inquire_equel (rowcount = "rowcount")
1818 if (rowcount != 1) return(SMS_TYPE);
1820 /* now retrieve the record id corresponding to the named object */
1822 if (!strcmp(data_type, "user")) {
1824 ## repeat retrieve (id = users.users_id) where users.login = @name
1825 ## inquire_equel (rowcount = "rowcount")
1826 if (rowcount != 1) return(SMS_USER);
1828 } else if (!strcmp(data_type, "list")) {
1830 ## repeat retrieve (id = list.list_id) where list.#name = @name
1831 ## inquire_equel (rowcount = "rowcount")
1832 if (rowcount != 1) return(SMS_LIST);
1834 } else if (!strcmp(data_type, "machine")) {
1836 for (c = name; *c; c++) if (islower(*c)) *c = toupper(*c);
1837 ## repeat retrieve (id = machine.mach_id) where machine.#name = @name
1838 ## inquire_equel (rowcount = "rowcount")
1839 if (rowcount != 1) return(SMS_MACHINE);
1841 } else if (!strcmp(data_type, "string")) {
1843 ## range of s is strings
1844 ## repeat retrieve (id = s.string_id, refc = s.#refc)
1845 ## where s.string = @name
1846 ## inquire_equel (rowcount = "rowcount")
1847 if (rowcount == 0) {
1848 if (q->type != APPEND) return(SMS_STRING);
1849 ## range of v is values
1850 ## retrieve (id = v.value) where v.#name = "strings_id"
1852 ## replace v (value = id) where v.#name = "strings_id"
1853 ## append to strings (string_id = id, string = name, #refc = 1)
1854 } else if (rowcount == 1) {
1855 if (q->type == APPEND || q->type == DELETE) {
1856 refc += (q->type == APPEND) ? 1 : -1;
1858 ## replace s (#refc = refc) where s.string_id = id
1860 ## delete s where s.string_id = id
1868 /* now set value in argv */
1869 *(int *)argv[vo->index] = id;
1871 return (SMS_EXISTS);
1875 translate_ids(q, sq, v, action, actarg)
1876 register struct query *q;
1877 register struct save_queue *sq;
1878 register struct validate *v;
1879 register int (*action)();
1883 ## char *field_type;
1884 ## char data_type[17];
1891 for (i = 0; i < v->objcnt; i++) {
1893 if (vo->type == V_FOLLOWUP) break;
1897 while (sq_get_data(sq, &argv)) {
1901 sscanf(argv[i], "%d", &id);
1903 name = (char *)malloc(129);
1906 /* get field type string (known to be at index-1) */
1907 field_type = argv[vo->index-1];
1909 /* get corresponding data type associated with field type name */
1910 ## repeat retrieve (data_type = alias.trans)
1911 ## where alias.#name = @field_type and alias.type = "TYPEDATA"
1912 ## inquire_equel (rowcount = "rowcount")
1913 if (rowcount != 1) {
1914 sprintf(name, "%d", id);
1915 (*action)(q->vcnt, argv, actarg);
1919 /* retrieve object name */
1921 if (!strcmp(data_type, "user")) {
1923 ## repeat retrieve (name = users.login) where users.users_id = @id
1924 ## inquire_equel (rowcount = "rowcount")
1926 } else if (!strcmp(data_type, "list")) {
1928 ## repeat retrieve (name = list.#name) where list.list_id = @id
1929 ## inquire_equel (rowcount = "rowcount")
1931 } else if (!strcmp(data_type, "machine")) {
1933 ## repeat retrieve (name = machine.#name) where machine.mach_id = @id
1934 ## inquire_equel (rowcount = "rowcount")
1936 } else if (!strcmp(data_type, "string")) {
1938 ## repeat retrieve (name = strings.string)
1939 ## where strings.string_id = @id
1940 ## inquire_equel (rowcount = "rowcount")
1946 /* if there wasn't a corresponding object name, then use the id */
1947 if (rowcount != 1) sprintf(name, "%d", id);
1950 (*action)(q->vcnt, argv, actarg);
1952 /* free saved data */
1953 for (i = 0; i < q->vcnt; i++)
1959 return (SMS_SUCCESS);
1966 * c-continued-statement-offset: 4
1967 * c-brace-offset: -4
1968 * c-argdecl-indent: 4
1969 * c-label-offset: -4