X-Git-Url: http://andersk.mit.edu/gitweb/moira.git/blobdiff_plain/453b99fe7430df1592afdf8e17f63b1b55358259..refs/heads/LOCKING:/server/qsupport.dc diff --git a/server/qsupport.dc b/server/qsupport.dc index 59c5c439..038e92a3 100644 --- a/server/qsupport.dc +++ b/server/qsupport.dc @@ -1,4 +1,3 @@ -/* #define GDSS */ /* * $Source$ * $Author$ @@ -28,1869 +27,13 @@ EXEC SQL INCLUDE sqlda; extern char *whoami, *strsave(); extern int ingres_errno, mr_errcode; -EXEC SQL BEGIN DECLARE SECTION; -int idummy; -extern char *cdummy, *stmt_buf; -EXEC SQL END DECLARE SECTION; +EXEC SQL BEGIN DECLARE SECTION; +extern char stmt_buf[]; +EXEC SQL END DECLARE SECTION; -/* Specialized Access Routines */ - -/* access_user - verify that client name equals specified login name - * - * - since field validation routines are called first, a users_id is - * now in argv[0] instead of the login name. - */ - -EXEC SQL WHENEVER SQLERROR CALL ingerr; - -access_user(q, argv, cl) - struct query *q; - char *argv[]; - client *cl; -{ - if (cl->users_id != *(int *)argv[0]) - return(MR_PERM); - else - return(MR_SUCCESS); -} - - - -/* access_login - verify that client name equals specified login name - * - * argv[0...n] contain search info. q-> - */ - -access_login(q, argv, cl) - struct query *q; - char *argv[]; - client *cl; -{ - EXEC SQL BEGIN DECLARE SECTION; - int id; - char qual[256]; - EXEC SQL END DECLARE SECTION; - - build_qual(q->qual, q->argc, argv, qual); - EXEC SQL SELECT users_id INTO :id FROM users WHERE :qual; - - if (sqlca.sqlerrd[2] != 1 || id != cl->users_id) - return(MR_PERM); - else - return(MR_SUCCESS); -} - - - -/* access_list - check access for most list operations - * - * Inputs: argv[0] - list_id - * q - query name - * argv[2] - member ID (only for queries "amtl" and "dmfl") - * argv[7] - group IID (only for query "ulis") - * cl - client name - * - * - check that client is a member of the access control list - * - OR, if the query is add_member_to_list or delete_member_from_list - * and the list is public, allow access if client = member - */ - -access_list(q, argv, cl) - struct query *q; - char *argv[]; - client *cl; -{ - EXEC SQL BEGIN DECLARE SECTION; - int list_id, acl_id, flags, gid; - char acl_type[9]; - EXEC SQL END DECLARE SECTION; - char *client_type; - int client_id, status; - - list_id = *(int *)argv[0]; - EXEC SQL SELECT acl_id, acl_type, gid, public - INTO :acl_id, :acl_type, :gid, :flags - FROM list - WHERE list_id = :list_id; - - if (sqlca.sqlerrd[2] != 1) - return(MR_INTERNAL); - - /* parse client structure */ - if ((status = get_client(cl, &client_type, &client_id)) != MR_SUCCESS) - return(status); - - /* if amtl or dmfl and list is public allow client to add or delete self */ - if (((!strcmp("amtl", q->shortname) && flags) || - (!strcmp("dmfl", q->shortname))) && - (!strcmp("USER", argv[1]))) { - if (*(int *)argv[2] == client_id) return(MR_SUCCESS); - /* if update_list, don't allow them to change the GID */ - } else if (!strcmp("ulis", q->shortname)) { - if ((!strcmp(argv[7], UNIQUE_GID) && (gid != -1)) || - (strcmp(argv[7], UNIQUE_GID) && (gid != atoi(argv[7])))) - return(MR_PERM); - } - - /* check for client in access control list */ - status = find_member(acl_type, acl_id, client_type, client_id, 0); - if (!status) return(MR_PERM); - - return(MR_SUCCESS); -} - - -/* access_visible_list - allow access to list only if it is not hidden, - * or if the client is on the ACL - * - * Inputs: argv[0] - list_id - * cl - client identifier - */ - -access_visible_list(q, argv, cl) - struct query *q; - char *argv[]; - client *cl; -{ - EXEC SQL BEGIN DECLARE SECTION; - int list_id, acl_id, flags ; - char acl_type[9]; - EXEC SQL END DECLARE SECTION; - char *client_type; - int client_id, status; - - list_id = *(int *)argv[0]; - EXEC SQL SELECT hidden, acl_id, acl_type - INTO :flags, :acl_id, :acl_type - FROM list - WHERE list_id = :list_id; - if (sqlca.sqlerrd[2] != 1) - return(MR_INTERNAL); - if (!flags) - return(MR_SUCCESS); - - /* parse client structure */ - if ((status = get_client(cl, &client_type, &client_id)) != MR_SUCCESS) - return(status); - - /* check for client in access control list */ - status = find_member(acl_type, acl_id, client_type, client_id, 0); - if (!status) - return(MR_PERM); - - return(MR_SUCCESS); -} - - -/* access_vis_list_by_name - allow access to list only if it is not hidden, - * or if the client is on the ACL - * - * Inputs: argv[0] - list name - * cl - client identifier - */ - -access_vis_list_by_name(q, argv, cl) - struct query *q; - char *argv[]; - client *cl; -{ - EXEC SQL BEGIN DECLARE SECTION; - int acl_id, flags, rowcount; - char acl_type[9], *listname; - EXEC SQL END DECLARE SECTION; - char *client_type; - int client_id, status; - - listname = argv[0]; - EXEC SQL SELECT hidden, acl_id, acl_type INTO :flags, :acl_id, :acl_type - FROM list WHERE name = :listname; - - rowcount=sqlca.sqlerrd[2]; - if (rowcount > 1) - return(MR_WILDCARD); - if (rowcount == 0) - return(MR_NO_MATCH); - if (!flags) - return(MR_SUCCESS); - - /* parse client structure */ - if ((status = get_client(cl, &client_type, &client_id)) != MR_SUCCESS) - return(status); - - /* check for client in access control list */ - status = find_member(acl_type, acl_id, client_type, client_id, 0); - if (!status) - return(MR_PERM); - - return(MR_SUCCESS); -} - - -/* access_member - allow user to access member of type "USER" and name matches - * username, or to access member of type "LIST" and list is one that user is - * on the acl of, or the list is visible. - */ - -access_member(q, argv, cl) - struct query *q; - char *argv[]; - client *cl; -{ - if (!strcmp(argv[0], "LIST") || !strcmp(argv[0], "RLIST")) - return(access_visible_list(q, &argv[1], cl)); - - if (!strcmp(argv[0], "USER") || !strcmp(argv[0], "RUSER")) { - if (cl->users_id == *(int *)argv[1]) - return(MR_SUCCESS); - } - - return(MR_PERM); -} - - -/* access_qgli - special access routine for Qualified_get_lists. Allows - * access iff argv[0] == "TRUE" and argv[2] == "FALSE". - */ - -access_qgli(q, argv, cl) - struct query *q; - char *argv[]; - client *cl; -{ - if (!strcmp(argv[0], "TRUE") && !strcmp(argv[2], "FALSE")) - return(MR_SUCCESS); - return(MR_PERM); -} - - -/* access_service - allow access if user is on ACL of service. Don't - * allow access if a wildcard is used. - */ - -access_service(q, argv, cl) - struct query *q; - char *argv[]; - client *cl; -{ - EXEC SQL BEGIN DECLARE SECTION; - int acl_id; - char *name, acl_type[9]; - EXEC SQL END DECLARE SECTION; - int client_id, status; - char *client_type, *c; - - name = argv[0]; - for(c=name;*c;c++) if(islower(*c)) *c = toupper(*c); /* uppercasify */ - EXEC SQL SELECT acl_id, acl_type INTO :acl_id, :acl_type FROM servers - WHERE name = :name; - if (sqlca.sqlerrd[2] > 1) - return(MR_PERM); - - /* parse client structure */ - if ((status = get_client(cl, &client_type, &client_id)) != MR_SUCCESS) - return(status); - - /* check for client in access control list */ - status = find_member(acl_type, acl_id, client_type, client_id, 0); - if (!status) return(MR_PERM); - - return(MR_SUCCESS); -} - - -/* access_filesys - verify that client is owner or on owners list of filesystem - * named by argv[0] - */ - -access_filesys(q, argv, cl) - struct query *q; - char *argv[]; - client *cl; -{ - EXEC SQL BEGIN DECLARE SECTION; - int users_id, list_id; - char *name; - EXEC SQL END DECLARE SECTION; - int status, client_id; - char *client_type; - - name = argv[0]; - EXEC SQL SELECT owner, owners INTO :users_id, :list_id FROM filesys - WHERE label = :name; - - if (sqlca.sqlerrd[2] != 1) - return(MR_PERM); - if (users_id == cl->users_id) - return(MR_SUCCESS); - if ((status = get_client(cl, &client_type, &client_id)) != MR_SUCCESS) - return(status); - status = find_member("LIST", list_id, client_type, client_id, 0); - if (status) - return(MR_SUCCESS); - else - return(MR_PERM); -} - - - -/* Setup Routines */ - -/* Setup routine for add_user - * - * Inputs: argv[0] - login - * argv[1] - uid - * - * Description: - * - * - if argv[1] == UNIQUE_UID then set argv[1] = next(uid) - * - if argv[0] == UNIQUE_LOGIN then set argv[0] = "#" - */ - -setup_ausr(q, argv, cl) - struct query *q; - register char *argv[]; - client *cl; -{ - int row; - EXEC SQL BEGIN DECLARE SECTION; - int nuid; - EXEC SQL END DECLARE SECTION; - - if (!strcmp(q->shortname, "uusr") || !strcmp(q->shortname, "uuac")) - row = 2; - else - row = 1; - if (!strcmp(argv[row], UNIQUE_UID) || atoi(argv[row]) == -1) { - if (set_next_object_id("uid", "users", 1)) - return(MR_INGRES_ERR); - EXEC SQL SELECT value INTO :nuid FROM numvalues WHERE name = 'uid'; - if (sqlca.sqlerrd[2] != 1) - return(MR_INTERNAL); - sprintf(argv[row], "%d", nuid); - } - - if (!strcmp(argv[0], UNIQUE_LOGIN) || atoi(argv[row]) == -1) { - sprintf(argv[0], "#%s", argv[row]); - } - - return(MR_SUCCESS); -} - - -/* setup_dusr - verify that the user is no longer being referenced - * and may safely be deleted. - */ - -int setup_dusr(q, argv) - struct query *q; - char **argv; -{ - EXEC SQL BEGIN DECLARE SECTION; - int flag, id; - EXEC SQL END DECLARE SECTION; - - id = *(int *)argv[0]; - - /*? Can this get wildcarded users? What happens then?! */ - /*? How does the REPEATED keyword work? */ - /* For now, only allow users to be deleted if their status is 0 */ - EXEC SQL REPEATED SELECT status INTO :flag FROM users - WHERE user_id = :id; - if (flag != 0 && flag != 4) - return(MR_IN_USE); - - EXEC SQL REPEATED DELETE FROM quota WHERE entity_id = :id AND type = 'USER'; - EXEC SQL REPEATED DELETE FROM krbmap WHERE users_id = :id; - EXEC SQL REPEATED SELECT member_id INTO :idummy FROM imembers - WHERE member_id = :id AND member_type = 'USER'; - if (sqlca.sqlerrd[2] > 0) - return(MR_IN_USE); - EXEC SQL REPEATED SELECT label INTO :cdummy FROM filesys WHERE owner = :id; - if (sqlca.sqlerrd[2]> 0) - return(MR_IN_USE); - EXEC SQL REPEATED SELECT name INTO :cdummy FROM list - WHERE acl_id = :id AND acl_type = 'USER'; - if (sqlca.sqlerrd[2] > 0) - return(MR_IN_USE); - EXEC SQL REPEATED SELECT name INTO :cdummy FROM servers - WHERE acl_id = :id AND acl_type = 'USER'; - if (sqlca.sqlerrd[2] > 0) - return(MR_IN_USE); - EXEC SQL REPEATED SELECT acl_id INTO :idummy FROM hostaccess - WHERE acl_d = :id AND acl_type = 'USER'; - if (sqlca.sqlerrd[2] > 0) - return(MR_IN_USE); - if (ingres_errno) - return(mr_errcode); - return(MR_SUCCESS); -} - - -/* setup_spop: verify that there is already a valid POP machine_id in the - * pop_id field. Also take care of keeping track of the post office usage. - */ -int setup_spop(q, argv) -struct query *q; -char **argv; -{ - EXEC SQL BEGIN DECLARE SECTION; - int id, mid, flag; - char type[9]; - EXEC SQL END DECLARE SECTION; - - id = *(int *)argv[0]; - EXEC SQL REPEATED SELECT potype, pop_id INTO :type, :mid FROM users - WHERE users_id = :id; - if(sqlca.sqlerrd[2] = 0) - return(MR_MACHINE); - EXEC SQL REPEATED SELECT mach_id INTO :mid FROM machine - WHERE mach_id = :mid; - if (sqlca.sqlerrd[2] = 0) - return(MR_MACHINE); - if (strcmp(strtrim(type), "POP")) - set_pop_usage(mid, 1); - return(MR_SUCCESS); -} - - -/* setup_dpob: Take care of keeping track of the post office usage. - */ -int setup_dpob(q, argv) - struct query *q; - char **argv; -{ - EXEC SQL BEGIN DECLARE SECTION; - int id, user; - char type[9]; - EXEC SQL END DECLARE SECTION; - - user = *(int *)argv[0]; - EXEC SQL REPEATED SELECT potype, pop_id INTO :type, :id FROM users - WHERE users_id = :user; - if (ingres_errno) return(mr_errcode); - - if (!strcmp(strtrim(type), "POP")) - set_pop_usage(id, -1); - return(MR_SUCCESS); -} - - -/* setup_dmac - verify that the machine is no longer being referenced - * and may safely be deleted. - */ - -int setup_dmac(q, argv) - struct query *q; - char **argv; -{ - EXEC SQL BEGIN DECLARE SECTION; - int flag, id; - EXEC SQL END DECLARE SECTION; - - id = *(int *)argv[0]; - EXEC SQL REPEATED SELECT login INTO :cdummy FROM users - WHERE potype='POP' AND pop_id = :id; - if (sqlca.sqlerrd[2] > 0) - return(MR_IN_USE); - EXEC SQL REPEATED SELECT mach_id INTO :idummy FROM serverhosts - WHERE mach_id = :id; - if (sqlca.sqlerrd[2] > 0) - return(MR_IN_USE); - EXEC SQL REPEATED SELECT mach_id INTO :idummy FROM nfsphys - WHERE mach_id = :id; - if (sqlca.sqlerrd[2] > 0) - return(MR_IN_USE); - EXEC SQL REPEATED SELECT mach_id INTO :idummy FROM hostaccess - WHERE mach_id = :id; - if (sqlca.sqlerrd[2] > 0) - return(MR_IN_USE); - EXEC SQL REPEATED SELECT mach_id INTO :idummy FROM printcap - WHERE mach_id = :id; - if (sqlca.sqlerrd[2] > 0) - return(MR_IN_USE); - EXEC SQL REPEATED SELECT quotaserver INTO :idummy FROM printcap - WHERE quotaserver = :id; - if (sqlca.sqlerrd[2] > 0) - return(MR_IN_USE); - EXEC SQL REPEATED SELECT mach_id INTO :idummy FROM palladium - WHERE mach_id = :id; - if (sqlca.sqlerrd[2] > 0) - return(MR_IN_USE); - - EXEC SQL REPEATED DELETE FROM mcmap WHERE mach_id = :id; - if (ingres_errno) return(mr_errcode); - return(MR_SUCCESS); -} - - -/* setup_dclu - verify that the cluster is no longer being referenced - * and may safely be deleted. - */ - -int setup_dclu(q, argv) - struct query *q; - char **argv; -{ - EXEC SQL BEGIN DECLARE SECTION; - int id; - EXEC SQL END DECLARE SECTION; - - id = *(int *)argv[0]; - EXEC SQL REPEATED SELECT mach_id INTO :idummy FROM mcmap - WHERE clu_id = :id; - if (sqlca.sqlerrd[2] > 0) - return(MR_IN_USE); - EXEC SQL REPEATED SELECT clu_id INTO :idummy FROM svc - WHERE clu_id = :id; - if (sqlca.sqlerrd[2] > 0) - return(MR_IN_USE); - if (ingres_errno) - return(mr_errcode); - return(MR_SUCCESS); -} - - -/* setup_alis - if argv[5] is non-zero and argv[6] is UNIQUE_ID, then allocate - * a new gid and put it in argv[6]. Otherwise if argv[6] is UNIQUE_ID but - * argv[5] is not, then remember that UNIQUE_ID is being stored by putting - * a -1 there. Remember that this is also used for ulis, with the indexes - * at 6 & 7. - */ - -int setup_alis(q, argv) - struct query *q; - char **argv; -{ - EXEC SQL BEGIN DECLARE SECTION; - int ngid; - EXEC SQL END DECLARE SECTION; - char *malloc(); - int idx; - - if (!strcmp(q->shortname, "alis")) - idx = 6; - else if (!strcmp(q->shortname, "ulis")) - idx = 7; - - if (!strcmp(argv[idx], UNIQUE_GID) || atoi(argv[idx]) == -1) { - if (atoi(argv[idx - 1])) { - if (set_next_object_id("gid", "list", 1)) - return(MR_INGRES_ERR); - EXEC SQL REPEATED SELECT value INTO :ngid FROM numvalues - WHERE name = 'gid'; - if (ingres_errno) return(mr_errcode); - sprintf(argv[idx], "%d", ngid); - } else { - strcpy(argv[idx], "-1"); - } - } - - return(MR_SUCCESS); -} - - -/* setup_dlist - verify that the list is no longer being referenced - * and may safely be deleted. - */ - -int setup_dlis(q, argv) - struct query *q; - char **argv; -{ - EXEC SQL BEGIN DECLARE SECTION; - int flag, id; - EXEC SQL END DECLARE SECTION; - - id = *(int *)argv[0]; - EXEC SQL REPEATED SELECT member_id INTO :idummy FROM imembers - WHERE member_id = :id AND member_type='LIST'; - if (sqlca.sqlerrd[2] > 0) - return(MR_IN_USE); - EXEC SQL REPEATED SELECT member_id INTO :idummy FROM imembers - WHERE list_id = :id; - if (sqlca.sqlerrd[2] > 0) - return(MR_IN_USE); - EXEC SQL REPEATED SELECT label INTO :cdummy FROM filesys - WHERE owners = :id; - if (sqlca.sqlerrd[2] > 0) - return(MR_IN_USE); - EXEC SQL REPEATED SELECT tag INTO :cdummy FROM capacls - WHERE list_id = :id; - if (sqlca.sqlerrd[2] > 0) - return(MR_IN_USE); - EXEC SQL REPEATED SELECT name INTO :cdummy FROM list - WHERE acl_id = :id AND acl_type='LIST' AND list_id = :id; - if (sqlca.sqlerrd[2] > 0) - return(MR_IN_USE); - EXEC SQL REPEATED SELECT name INTO :cdummy FROM servers - WHERE acl_id = :id AND acl_type='LIST'; - if (sqlca.sqlerrd[2] > 0) - return(MR_IN_USE); - EXEC SQL REPEATED SELECT entity_id INTO :idummy FROM quota - WHERE entity_id = :id AND type='GROUP'; - if (sqlca.sqlerrd[2] > 0) - return(MR_IN_USE); - EXEC SQL REPEATED SELECT acl_id INTO :idummy FROM hostaccess - WHERE acl_id = :id AND acl_type='LIST'; - if (sqlca.sqlerrd[2] > 0) - return(MR_IN_USE); - EXEC SQL REPEATED SELECT class INTO :cdummy FROM zephyr z - WHERE zephyr.xmt_type = 'LIST' AND z.xmt_id = :id - OR z.sub_type = 'LIST' AND z.sub_id = :id - OR z.iws_type = 'LIST' AND z.iws_id = :id - OR z.iui_type = 'LIST' AND z.iui_id = :id; - if (sqlca.sqlerrd[2] > 0) - return(MR_IN_USE); - if (ingres_errno) - return(mr_errcode); - return(MR_SUCCESS); -} - - -/* setup_dsin - verify that the service is no longer being referenced - * and may safely be deleted. - */ - -int setup_dsin(q, argv) - struct query *q; - char **argv; -{ - EXEC SQL BEGIN DECLARE SECTION; - char *name; - EXEC SQL END DECLARE SECTION; - char *c; - - name = argv[0]; - for(c=name;*c;c++) if(islower(*c)) *c = toupper(*c); - EXEC SQL REPEATED SELECT service INTO :cdummy FROM serverhosts - WHERE service = :name; - if (sqlca.sqlerrd[2] > 0) - return(MR_IN_USE); - EXEC SQL REPEATED SELECT inprogress INTO :idummy FROM servers - WHERE name = :name; - if (sqlca.sqlerrd[2] > 0) - return(MR_IN_USE); - if (ingres_errno) - return(mr_errcode); - return(MR_SUCCESS); -} - - -/* setup_dshi - verify that the service-host is no longer being referenced - * and may safely be deleted. - */ - -int setup_dshi(q, argv) - struct query *q; - char **argv; -{ - EXEC SQL BEGIN DECLARE SECTION; - int id; - char *name, *c; - EXEC SQL END DECLARE SECTION; - - name = argv[0]; - for(c=name;*c;c++) if(islower(*c)) *c = toupper(*c); /* to uppercase */ - id = *(int *)argv[1]; - EXEC SQL REPEATED SELECT inprogress INTO :idummy FROM serverhosts - WHERE service = :name AND mach_id = :id; - if (sqlca.sqlerrd[2] > 0) - return(MR_IN_USE); - if (ingres_errno) - return(mr_errcode); - return(MR_SUCCESS); -} - - -/** - ** setup_add_filesys - verify existance of referenced file systems - ** - ** Inputs: Add - ** argv[1] - type - ** argv[2] - mach_id - ** argv[3] - name - ** argv[5] - access - ** - ** Description: - ** - for type = RVD: - ** * allow anything - ** - for type = NFS: - ** * extract directory prefix from name - ** * verify mach_id/dir in nfsphys - ** * verify access in {r, w, R, W} - ** - ** Side effect: sets variable var_phys_id to the ID of the physical - ** filesystem (nfsphys_id for NFS, 0 for RVD) - ** - ** Errors: - ** MR_NFS - specified directory not exported - ** MR_FILESYS_ACCESS - invalid filesys access - ** - **/ - -EXEC SQL BEGIN DECLARE SECTION; -static int var_phys_id; -EXEC SQL END DECLARE SECTION; - -setup_afil(q, argv) - struct query *q; - char *argv[]; -{ - char *type, *name; - int mach_id; - EXEC SQL BEGIN DECLARE SECTION; - int ok; - char ftype[32], *access; - EXEC SQL END DECLARE SECTION; - - type = argv[1]; - mach_id = *(int *)argv[2]; - name = argv[3]; - access = argv[5]; - var_phys_id = 0; - - sprintf(ftype, "fs_access_%s", type); - EXEC SQL SELECT trans INTO :cdummy FROM alias - WHERE name = :ftype AND type = 'TYPE' and trans = :access; - if (ingres_errno) return(mr_errcode); - if (sqlca.sqlerrd[2] == 0) return(MR_FILESYS_ACCESS); - - if (!strcmp(type, "NFS")) - return (check_nfs(mach_id, name, access)); - else - return(MR_SUCCESS); -} - - -/* Verify the arguments, depending on the FStype. Also, if this is an - * NFS filesystem, then update any quotas for that filesystem to reflect - * the new phys_id. - */ - -setup_ufil(q, argv, cl) - struct query *q; - char *argv[]; - client *cl; -{ - int mach_id, status; - char *type, *name; - EXEC SQL BEGIN DECLARE SECTION; - int fid, total, who; - char *entity, ftype[32], *access; - int var_phys_id = 0; - EXEC SQL END DECLARE SECTION; - - type = argv[2]; - mach_id = *(int *)argv[3]; - name = argv[4]; - access = argv[6]; - fid = *(int *)argv[0]; - who = cl->client_id; - entity = cl->entity; - - sprintf(ftype, "fs_access_%s", type); - EXEC SQL SELECT trans INTO :cdummy FROM alias - WHERE name = :ftype AND type='TYPE' AND trans = :access; - if (ingres_errno) return(mr_errcode); - if (sqlca.sqlerrd[2] == 0) return(MR_FILESYS_ACCESS); - - if (!strcmp(type, "NFS")) { - status = check_nfs(mach_id, name, access); - EXEC SQL UPDATE quota SET phys_id = :var_phys_id - WHERE filsys_id = :fid; - if (ingres_errno) return(mr_errcode); - return(status); - } else if (!strcmp(type, "AFS")) { - total = 0; - EXEC SQL REPEATED DELETE FROM quota - WHERE type = 'ANY' AND filsys_id = :fid; - EXEC SQL SELECT SUM (quota) INTO :total FROM quota - WHERE filsys_id = :fid AND phys_id != 0; - if (ingres_errno) return(mr_errcode); - if (total != 0) { -/* - * append quota (quota = total, filsys_id = fid, - * phys_id = 0, entity_id = 0, type = "ANY", - * modtime = "now", modby = who, modwith = entity) - */ - EXEC SQL INSERT INTO quota (quota, filsys_id, phys_id, entity_id, - type, modtime, modby, modwith) - VALUES (:total, :fid, 0, 0, - 'ANY', 'now', :who, :entity) ; - if (ingres_errno) return(mr_errcode); - } - } else { - EXEC SQL UPDATE quota SET phys_id = 0 WHERE filsys_id = :fid; - if (ingres_errno) return(mr_errcode); - } - return(MR_SUCCESS); -} - - -/* Find the NFS physical partition that the named directory is on. - * This is done by comparing the dir against the mount point of the - * partition. To make sure we get the correct match when there is - * more than one, we sort the query in reverse order by dir name. - */ - -check_nfs(mach_id, name, access) - EXEC SQL BEGIN DECLARE SECTION; - int mach_id; - EXEC SQL END DECLARE SECTION; - char *name; - char *access; -{ - EXEC SQL BEGIN DECLARE SECTION; - char dir[81]; - EXEC SQL END DECLARE SECTION; - char caccess; - register int status; - register char *cp1; - register char *cp2; - - status = MR_NFS; - EXEC SQL DECLARE csr101 CURSOR FOR - SELECT nfsphys_id, TRIM (dir) FROM nfsphys - WHERE mach_id = :mach_id - ORDER BY 2 DESC; - EXEC SQL OPEN csr101; - while(1) { - EXEC SQL FETCH csr101 INTO :var_phys_id, :dir; - if(sqlca.sqlcode != 0) break; - cp1 = name; - cp2 = dir; - while (*cp2) { - if (*cp1++ != *cp2) break; - cp2++; - } - if (*cp2 == 0) { - status = MR_SUCCESS; - break; - } - } - EXEC SQL CLOSE csr101; - if (ingres_errno) - return(mr_errcode); - return(status); -} - - -/* setup_dfil: free any quota records and fsgroup info associated with - * a filesystem when it is deleted. Also adjust the allocation numbers. - */ - -setup_dfil(q, argv, cl) - struct query *q; - char **argv; - client *cl; -{ - EXEC SQL BEGIN DECLARE SECTION; - int id, total; - EXEC SQL END DECLARE SECTION; - - id = *(int *)argv[0]; - EXEC SQL REPEATED SELECT SUM (quota) INTO :total FROM quota - WHERE filsys_id = :id; - EXEC SQL REPEATED UPDATE nfsphys SET allocated = allocated - :total - WHERE nfsphys_id = filesys.phys_id AND filesys.filsys_id = :id; - /** Is SQL smart enough to do the PRODUCT above? */ - /** Or should we code it using another SELECT? */ - - EXEC SQL REPEATED DELETE FROM quota WHERE filsys_id = :id; - EXEC SQL REPEATED DELETE FROM fsgroup WHERE filsys_id = :id; - EXEC SQL REPEATED DELETE FROM fsgroup WHERE group_id = :id; - if (ingres_errno) return(mr_errcode); - return(MR_SUCCESS); -} - - -/* setup_dnfp: check to see that the nfs physical partition does not have - * any filesystems assigned to it before allowing it to be deleted. - */ - -setup_dnfp(q, argv, cl) - struct query *q; - char **argv; - client *cl; -{ - EXEC SQL BEGIN DECLARE SECTION; - int id; - char *dir; - EXEC SQL END DECLARE SECTION; - - id = *(int *)argv[0]; - dir = argv[1]; - EXEC SQL REPEATED SELECT label INTO :cdummy FROM filesys fs, nfsphys np - WHERE fs.mach_id = :id AND fs.phys_id = np.nfsphys_id - AND np.mach_id = :id AND np.dir = :dir; - if (sqlca.sqlerrd[2] > 0) - return(MR_IN_USE); - if (ingres_errno) - return(mr_errcode); - return(MR_SUCCESS); -} - - -/* setup_dqot: Remove allocation from nfsphys before deleting quota. - * argv[0] = filsys_id - * argv[1] = type if "update_quota" or "delete_quota" - * argv[2 or 1] = users_id or list_id - */ - -setup_dqot(q, argv, cl) - struct query *q; - char **argv; - client *cl; -{ - EXEC SQL BEGIN DECLARE SECTION; - int quota, fs, id; - char *qtype; - EXEC SQL END DECLARE SECTION; - - fs = *(int *)argv[0]; - if (!strcmp(q->name, "update_quota") || !strcmp(q->name, "delete_quota")) { - qtype = argv[1]; - id = *(int *)argv[2]; - } else { - qtype = "USER"; - id = *(int *)argv[1]; - } - - EXEC SQL REPEATED SELECT quota INTO :quota FROM quota - WHERE type = :qtype AND entity_id = :id AND filsys_id = :fs; - EXEC SQL REPEATED UPDATE nfsphys - SET allocated = nfsphys.allocated - :quota - WHERE nfsphys_id = filesys.physid AND filesys.filsys_id = :fs; - - if (ingres_errno) return(mr_errcode); - return(MR_SUCCESS); -} - - -/* setup_sshi: don't exclusive lock the machine table during - * set_server_host_internal. - */ - -setup_sshi(q, argv, cl) - struct query *q; - char **argv; - client *cl; -{ -#ifsql INGRES - EXEC SQL set lockmode session where readlock = system; -#endsql -} - - -/* setup add_kerberos_user_mapping: add the string to the string - * table if necessary. - */ - -setup_akum(q, argv, cl) -struct query *q; -char **argv; -client *cl; -{ - EXEC SQL BEGIN DECLARE SECTION; - int id, rowcount; - char *name; - EXEC SQL END DECLARE SECTION; - - name = argv[1]; - if (name_to_id(name, "STRING", &id) != MR_SUCCESS) { - if (q->type != APPEND) return(MR_STRING); - EXEC SQL SELECT value INTO :id FROM numvalues - WHERE name = 'strings_id'; - id++; - EXEC SQL UPDATE numvalues SET value = :id - WHERE name = 'strings_id'; - EXEC SQL INSERT INTO strings (string_id, string) VALUES (:id, :name); - cache_entry(name, "STRING", id); - } - if (ingres_errno) return(mr_errcode); - *(int *)argv[1] = id; - return(MR_SUCCESS); -} - - - -/* FOLLOWUP ROUTINES */ - -/* generic set_modtime routine. This takes the table name from the query, - * and will update the modtime, modby, and modwho fields in the entry in - * the table whose name field matches argv[0]. - */ - -set_modtime(q, argv, cl) - struct query *q; - char *argv[]; - client *cl; -{ - char *name, *entity, *table; - int who; - - entity = cl->entity; - who = cl->client_id; - table = q->rtable; - name = argv[0]; - - sprintf(stmt_buf,"UPDATE %s SET modtime = 'now', modby = %d, \ -modwith = '%s' WHERE %s.name = '%s'",table,who,entity,table,name); - EXEC SQL EXECUTE IMMEDIATE :stmt_buf; - - return(MR_SUCCESS); -} - -/* generic set_modtime_by_id routine. This takes the table name from - * the query, and the id name from the validate record, - * and will update the modtime, modby, and modwho fields in the entry in - * the table whose id matches argv[0]. - */ - -set_modtime_by_id(q, argv, cl) - struct query *q; - char **argv; - client *cl; -{ - char *entity, *table, *id_name; - int who, id; - - entity = cl->entity; - who = cl->client_id; - table = q->rtable; - id_name = q->validate->object_id; - - id = *(int *)argv[0]; - sprintf(stmt_buf,"UPDATE %s SET modtime = 'now', modby = %d, \ -modwith = '%s' WHERE %s.%s = %d",table,who,entity,table,id_name,id); - EXEC SQL EXECUTE IMMEDIATE :stmt_buf; - return(MR_SUCCESS); -} - - -/* Sets the finger modtime on a user record. The users_id will be in argv[0]. - */ - -set_finger_modtime(q, argv, cl) - struct query *q; - char *argv[]; - client *cl; -{ - EXEC SQL BEGIN DECLARE SECTION; - int users_id, who; - char *entity; - EXEC SQL END DECLARE SECTION; - - entity = cl->entity; - who = cl->client_id; - users_id = *(int *)argv[0]; - - EXEC SQL UPDATE users SET fmodtime='now', fmodby = :who, fmodwith = :entity - WHERE users.users_id = :users_id; - - return(MR_SUCCESS); -} - - -/* Sets the pobox modtime on a user record. The users_id will be in argv[0]. - */ - -set_pobox_modtime(q, argv, cl) - struct query *q; - char **argv; - client *cl; -{ - EXEC SQL BEGIN DECLARE SECTION; - int users_id, who; - char *entity; - EXEC SQL END DECLARE SECTION; - - entity = cl->entity; - who = cl->client_id; - users_id = *(int *)argv[0]; - - EXEC SQL UPDATE users SET pmodtime='now', pmodby = :who, pmodwith = entity - WHERE users.users_id = users_id; - - return(MR_SUCCESS); -} - - -/* Like set_modtime, but uppercases the name first. - */ - -set_uppercase_modtime(q, argv, cl) - struct query *q; - char **argv; - client *cl; -{ - char *name, *entity, *table, *c; - int who; - - entity = cl->entity; - who = cl->client_id; - table = q->rtable; - name = argv[0]; - for(c=name;*c;c++) if(islower(*c)) *c = toupper(*c); /** INGRES has an uppercase() functiuons, but it's not portable. */ - - sprintf(stmt_buf,"UPDATE %s SET modtime = 'now', modby = %d, \ -modwith = '%s' WHERE %s.name = '%s'",table,who,entity,table,name); - EXEC SQL EXECUTE IMMEDIATE :stmt_buf; - - return(MR_SUCCESS); -} - - -/* Sets the modtime on the machine whose mach_id is in argv[0]. This routine - * is necessary for add_machine_to_cluster becuase the table that query - * operates on is "mcm", not "machine". - */ - -set_mach_modtime_by_id(q, argv, cl) - struct query *q; - char **argv; - client *cl; -{ - EXEC SQL BEGIN DECLARE SECTION; - char *entity; - int who, id; - EXEC SQL END DECLARE SECTION; - - entity = cl->entity; - who = cl->client_id; - id = *(int *)argv[0]; - EXEC SQL UPDATE machine SET modtime='now', modby = :who, modwith = :entity - WHERE machine.mach_id = :id; - - return(MR_SUCCESS); -} - - -/* Sets the modtime on the cluster whose mach_id is in argv[0]. This routine - * is necessary for add_cluster_data and delete_cluster_data becuase the - * table that query operates on is "svc", not "cluster". - */ - -set_cluster_modtime_by_id(q, argv, cl) - struct query *q; - char **argv; - client *cl; -{ - EXEC SQL BEGIN DECLARE SECTION; - char *entity; - int who, id; - EXEC SQL END DECLARE SECTION; - - entity = cl->entity; - who = cl->client_id; - - id = *(int *)argv[0]; - EXEC SQL UPDATE cluster SET modtime='now', modby = :who, modwith = :entity - WHERE cluster.clu_id = :id; - return(MR_SUCCESS); -} - - -/* sets the modtime on the serverhost where the service name is in argv[0] - * and the mach_id is in argv[1]. - */ - -set_serverhost_modtime(q, argv, cl) - struct query *q; - char **argv; - client *cl; -{ - EXEC SQL BEGIN DECLARE SECTION; - char *entity, *serv; - int who, id; - EXEC SQL END DECLARE SECTION; - - entity = cl->entity; - who = cl->client_id; - - serv = argv[0]; - id = *(int *)argv[1]; - EXEC SQL UPDATE serverhosts - SET modtime = 'now', modby = :who, modwith = :entity - WHERE service = :serv AND mach_id = :id; - return(MR_SUCCESS); -} - - -/* sets the modtime on the nfsphys where the mach_id is in argv[0] and the - * directory name is in argv[1]. - */ - -set_nfsphys_modtime(q, argv, cl) - struct query *q; - char **argv; - client *cl; -{ - EXEC SQL BEGIN DECLARE SECTION; - char *entity, *dir; - int who, id; - EXEC SQL END DECLARE SECTION; - - entity = cl->entity; - who = cl->client_id; - - id = *(int *)argv[0]; - dir = argv[1]; - EXEC SQL UPDATE nfsphys SET modtime = 'now', modby = :who, modwith = :entity - WHERE dir = :dir AND mach_id = :id; - return(MR_SUCCESS); -} - - -/* sets the modtime on a filesystem, where argv[0] contains the filesys - * label. - */ - -set_filesys_modtime(q, argv, cl) - struct query *q; - char *argv[]; - client *cl; -{ - EXEC SQL BEGIN DECLARE SECTION; - char *label, *entity; - int who; - EXEC SQL END DECLARE SECTION; - - entity = cl->entity; - who = cl->client_id; - - label = argv[0]; - if (!strcmp(q->shortname, "ufil")) - label = argv[1]; - - EXEC SQL UPDATE filesys SET modtime = 'now', modby = :who, - modwith = :entity, phys_id = :var_phys_id - WHERE label = :label; - return(MR_SUCCESS); -} - - -/* sets the modtime on a zephyr class, where argv[0] contains the class - * name. - */ - -set_zephyr_modtime(q, argv, cl) - struct query *q; - char *argv[]; - client *cl; -{ - EXEC SQL BEGIN DECLARE SECTION; - char *class, *entity; - int who; - EXEC SQL END DECLARE SECTION; - - entity = cl->entity; - who = cl->client_id; - - class = argv[0]; - - EXEC SQL UPDATE zephyr SET modtime = 'now', modby = :who, modwith = :entity - WHERE class = :class; - - return(MR_SUCCESS); -} - - -/* fixes the modby field. This will be the second to last thing in the - * argv, the argv length is determined from the query structure. It is - * passed as a pointer to an integer. This will either turn it into a - * username, or # + the users_id. - */ -followup_fix_modby(q, sq, v, action, actarg, cl) - struct query *q; - register struct save_queue *sq; - struct validate *v; - register int (*action)(); - register int actarg; - client *cl; -{ - register int i, j; - char **argv, *malloc(); - int id, status; - - i = q->vcnt - 2; - while (sq_get_data(sq, &argv)) { - id = atoi(argv[i]); - if (id > 0) - status = id_to_name(id, "USER", &argv[i]); - else - status = id_to_name(-id, "STRING", &argv[i]); - if (status && status != MR_NO_MATCH) - return(status); - (*action)(q->vcnt, argv, actarg); - for (j = 0; j < q->vcnt; j++) - free(argv[j]); - free(argv); - } - sq_destroy(sq); - return(MR_SUCCESS); -} - - -/* After retrieving a user account, fix the modby field and signature. - * The modby field is the second to last thing in the - * argv, the argv length is determined from the query structure. It is - * passed as a pointer to an integer. This will either turn it into a - * username, or # + the users_id. Only "gua*" queries have a signature, - * these are ones with U_END return values. "gub*" queries also use this - * routine but don't have a signature. - */ -followup_guax(q, sq, v, action, actarg, cl) - struct query *q; - register struct save_queue *sq; - struct validate *v; - register int (*action)(); - register int actarg; - client *cl; -{ - register int i, j; - char **argv, *malloc(); -#ifdef GDSS - char sigbuf[256], *rawsig, *kname; - SigInfo si; -#endif /* GDSS */ - int id, status; - - i = q->vcnt - 2; - while (sq_get_data(sq, &argv)) { - id = atoi(argv[i]); - if (id > 0) - status = id_to_name(id, "USER", &argv[i]); - else - status = id_to_name(-id, "STRING", &argv[i]); - if (status && status != MR_NO_MATCH) - return(status); -#ifdef GDSS - if (q->vcnt == U_END) { - com_err(whoami, 0, "compressing signature"); - rawsig = argv[U_SIGNATURE]; - bcopy(&rawsig[0], &id, sizeof(int)); - id = ntohl(id); - status = id_to_name(id, "STRING", &kname); - bcopy(&rawsig[4], &si.timestamp, sizeof(int)); - si.timestamp = ntohl(si.timestamp); - si.SigInfoVersion = 0; /* XXXXX this isn't used */ - kname_parse(si.pname, si.pinst, si.prealm, kname); - si.rawsig = (unsigned char *)&rawsig[8]; - GDSS_Recompose(&si, sigbuf); - argv[U_SIGNATURE] = strsave(sigbuf); - } -#endif /* GDSS */ - (*action)(q->vcnt, argv, actarg); - for (j = 0; j < q->vcnt; j++) - free(argv[j]); - free(argv); - } - sq_destroy(sq); - return(MR_SUCCESS); -} - - -/** - ** followup_ausr - add finger and pobox entries, set_user_modtime - ** - ** Inputs: - ** argv[0] - login (add_user) - ** argv[3] - last name - ** argv[4] - first name - ** argv[5] - middle name - ** - **/ - -followup_ausr(q, argv, cl) - struct query *q; - char *argv[]; - client *cl; -{ - EXEC SQL BEGIN DECLARE SECTION; - int who, status, sigwho, id; - char *login, *entity, *src, *dst, *name; - char fullname[129]; - EXEC SQL END DECLARE SECTION; -#ifdef GDSS - char databuf[32], *kname_unparse(); - EXEC SQL BEGIN DECLARE SECTION; - char rawsig[128]; - EXEC SQL END DECLARE SECTION; - SigInfo si; -#endif /* GDSS */ - - /* build fullname */ - if (strlen(argv[4]) && strlen(argv[5])) - sprintf(fullname, "%s %s %s", argv[4], argv[5], argv[3]); - else if (strlen(argv[4])) - sprintf(fullname, "%s %s", argv[4], argv[3]); - else - sprintf(fullname, "%s", argv[3]); - -#ifdef GDSS - sprintf(databuf, "%s:%s", argv[U_NAME], argv[U_MITID]); - /* skip bytes for timestamp & kname */ - si.rawsig = (unsigned char *)&rawsig[8]; - status = GDSS_Verify(databuf, strlen(databuf), argv[U_SIGNATURE], &si); - if (status == 0) { - name = kname_unparse(si.pname, si.pinst, si.prealm); - status = name_to_id(name, "STRING", &sigwho); - if (status == MR_NO_MATCH) { - EXEC SQL REPEATED SELECT value INTO :sigwho FROM numvalues - WHERE name = 'strings_id'; - sigwho++; - EXEC SQL REPEATED UPDATE numvalues SET value = :sigwho - WHERE name = 'strings_id'; - EXEC SQL INSERT INTO strings (string_id, string) - VALUES (:sigwho, :name); - } else if (status) - return(status); - sigwho = htonl(sigwho); - bcopy(&sigwho, &rawsig[0], sizeof(int)); - si.timestamp = htonl(si.timestamp); - bcopy(&si.timestamp, &rawsig[4], sizeof(int)); - } else - return(status); -#endif /* GDSS */ - - login = argv[0]; - who = cl->client_id; - entity = cl->entity; - - /* create finger entry, pobox & set modtime on user */ -#ifdef GDSS - EXEC SQL REPEATED UPDATE users - SET modtime='now', modby=:who, modwith = :entity, - fullname = :fullname, mit_affil = mit_year, - signature = :rawsig, - fmodtime='now', fmodby = :who, fmodwith = :entity, - potype='NONE', pmodtime='now', pmodby = :who, pmodwith = :entity - WHERE login = :login; -#else /* GDSS */ - EXEC SQL REPEATED UPDATE users - SET modtime='now', modby=:who, modwith = :entity, - fullname = :fullname, mit_affil = mit_year, - fmodtime='now', fmodby = :who, fmodwith = :entity, - potype='NONE', pmodtime='now', pmodby = :who, pmodwith = :entity - WHERE login = :login; -#endif /* GDSS */ - - return(MR_SUCCESS); -} - - -/* followup_gpob: fixes argv[2] based on the IDs currently there and the - * type in argv[1]. Then completes the upcall to the user. - * - * argv[2] is of the form "123:234" where the first integer is the machine - * ID if it is a pop box, and the second is the string ID if it is an SMTP - * box. argv[1] should be "POP", "SMTP", or "NONE". Boxes of type NONE - * are skipped. - */ - -followup_gpob(q, sq, v, action, actarg, cl) - register struct query *q; - register struct save_queue *sq; - register struct validate *v; - register int (*action)(); - int actarg; - client *cl; -{ - char **argv, *index(); - char *ptype, *p; - int mid, sid, status; - - /* for each row */ - while (sq_get_data(sq, &argv)) { - mr_trim_args(2, argv); - ptype = argv[1]; - p = index(argv[2], ':'); - *p++ = 0; - mid = atoi(argv[2]); - sid = atoi(p); - - if (!strcmp(ptype, "POP")) { - status = id_to_name(mid, "MACHINE", &argv[2]); - if (status == MR_NO_MATCH) - return(MR_MACHINE); - } else if (!strcmp(ptype, "SMTP")) { - status = id_to_name(sid, "STRING", &argv[2]); - if (status == MR_NO_MATCH) - return(MR_STRING); - } else /* ptype == "NONE" */ { - goto skip; - } - if (status) return(status); - - if (!strcmp(q->shortname, "gpob")) { - sid = atoi(argv[4]); - if (sid > 0) - status = id_to_name(sid, "USER", &argv[4]); - else - status = id_to_name(-sid, "STRING", &argv[4]); - } - if (status && status != MR_NO_MATCH) return(status); - - (*action)(q->vcnt, argv, actarg); - skip: - /* free saved data */ - free(argv[0]); - free(argv[1]); - free(argv[4]); - free(argv); - } - - sq_destroy(sq); - return (MR_SUCCESS); -} - - -/* followup_glin: fix the ace_name in argv[8]. argv[7] will contain the - * ace_type: "LIST", "USER", or "NONE". Decode the id in argv[8] into the - * proper name based on the type, and repace that string in the argv. - * Also fixes the modby field by called followup_fix_modby. - */ - -followup_glin(q, sq, v, action, actarg, cl) - register struct query *q; - register struct save_queue *sq; - register struct validate *v; - register int (*action)(); - int actarg; - client *cl; -{ - char **argv, *malloc(), *realloc(), *type; - int id, i, idx, status; - - idx = 8; - if (!strcmp(q->shortname, "gsin")) - idx = 12; - - while (sq_get_data(sq, &argv)) { - mr_trim_args(q->vcnt, argv); - - id = atoi(argv[i = q->vcnt - 2]); - if (id > 0) - status = id_to_name(id, "USER", &argv[i]); - else - status = id_to_name(-id, "STRING", &argv[i]); - if (status && status != MR_NO_MATCH) - return(status); - - id = atoi(argv[idx]); - type = argv[idx - 1]; - - if (!strcmp(type, "LIST")) { - status = id_to_name(id, "LIST", &argv[idx]); - } else if (!strcmp(type, "USER")) { - status = id_to_name(id, "USER", &argv[idx]); - } else if (!strcmp(type, "KERBEROS")) { - status = id_to_name(id, "STRING", &argv[idx]); - } else if (!strcmp(type, "NONE")) { - status = 0; - free(argv[idx]); - argv[idx] = strsave("NONE"); - } else { - status = 0; - free(argv[idx]); - argv[idx] = strsave("???"); - } - if (status && status != MR_NO_MATCH) - return(status); - - if (!strcmp(q->shortname, "glin") && atoi(argv[6]) == -1) { - argv[6] = realloc(argv[6], strlen(UNIQUE_GID) + 1); - strcpy(argv[6], UNIQUE_GID); - } - - /* send the data */ - (*action)(q->vcnt, argv, actarg); - - /* free saved data */ - for (i = 0; i < q->vcnt; i++) - free(argv[i]); - free(argv); - } - - sq_destroy(sq); - return (MR_SUCCESS); -} - - -/* followup_gqot: Fix the entity name, directory name & modby fields - * argv[0] = filsys_id - * argv[1] = type - * argv[2] = entity_id - * argv[3] = ascii(quota) - */ - -followup_gqot(q, sq, v, action, actarg, cl) - struct query *q; - register struct save_queue *sq; - struct validate *v; - register int (*action)(); - register int actarg; - client *cl; -{ - register int j; - char **argv, *malloc(); - EXEC SQL BEGIN DECLARE SECTION; - int id; - char *name, *label; - EXEC SQL END DECLARE SECTION; - int status, idx; - - if (!strcmp(q->name, "get_quota") || - !strcmp(q->name, "get_quota_by_filesys")) - idx = 4; - else - idx = 3; - while (sq_get_data(sq, &argv)) { - if (idx == 4) { - switch (argv[1][0]) { - case 'U': - status = id_to_name(atoi(argv[2]), "USER", &argv[2]); - break; - case 'G': - case 'L': - status = id_to_name(atoi(argv[2]), "LIST", &argv[2]); - break; - case 'A': - free(argv[2]); - argv[2] = strsave("system:anyuser"); - break; - default: - id = atoi(argv[2]); - argv[2] = malloc(8); - sprintf(argv[2], "%d", id); - } - } - id = atoi(argv[idx]); - free(argv[idx]); - argv[idx] = malloc(256); - name = argv[idx]; - if (id == 0) { - label = argv[0]; - EXEC SQL REPEATED SELECT name INTO :name FROM filesys - WHERE label = :label; - } else { - EXEC SQL REPEATED SELECT dir INTO :name FROM nfsphys - WHERE nfsphys_id = :id; - } - if (sqlca.sqlerrd[2] != 1) { - sprintf(argv[idx], "#%d", id); - } - - id = atoi(argv[idx+3]); - if (id > 0) - status = id_to_name(id, "USER", &argv[idx+3]); - else - status = id_to_name(-id, "STRING", &argv[idx+3]); - if (status && status != MR_NO_MATCH) - return(status); - (*action)(q->vcnt, argv, actarg); - for (j = 0; j < q->vcnt; j++) - free(argv[j]); - free(argv); - } - sq_destroy(sq); - return(MR_SUCCESS); -} - - -/* followup_aqot: Add allocation to nfsphys after creating quota. - * argv[0] = filsys_id - * argv[1] = type if "add_quota" or "update_quota" - * argv[2 or 1] = id - * argv[3 or 2] = ascii(quota) - */ - -followup_aqot(q, argv, cl) - struct query *q; - char **argv; - client *cl; -{ - EXEC SQL BEGIN DECLARE SECTION; - int quota, id, fs, who; - char *entity, *qtype; - EXEC SQL END DECLARE SECTION; - - fs = *(int *)argv[0]; - if (!strcmp(q->name, "add_quota") || !strcmp(q->name, "update_quota")) { - qtype = argv[1]; - id = *(int *)argv[2]; - quota = atoi(argv[3]); - } else { - qtype = "USER"; - id = *(int *)argv[1]; - quota = atoi(argv[2]); - } - who = cl->client_id; - entity = cl->entity; - - EXEC SQL REPEATED UPDATE quota - SET modtime = 'now', modby = :who, modwith = :entity - WHERE filsys_id = :fs and type = :qtype and entity_id = :id; - EXEC SQL REPEATED UPDATE nfsphys - SET allocated = allocated + :quota - WHERE nfsphys_id = filesys.phys_id AND filesys.filsys_id = :fs; - if (ingres_errno) return(mr_errcode); - return(MR_SUCCESS); -} - - -followup_gpce(q, sq, v, action, actarg, cl) - struct query *q; - register struct save_queue *sq; - struct validate *v; - register int (*action)(); - register int actarg; - client *cl; -{ - register int i, j; - char **argv, *malloc(); - int id, status; - - i = q->vcnt - 2; - while (sq_get_data(sq, &argv)) { - id = atoi(argv[PCAP_QSERVER]); - status = id_to_name(id, "MACHINE", &argv[PCAP_QSERVER]); - if (status) return (status); - id = atoi(argv[i]); - if (id > 0) - status = id_to_name(id, "USER", &argv[i]); - else - status = id_to_name(-id, "STRING", &argv[i]); - if (status && status != MR_NO_MATCH) - return(status); - (*action)(q->vcnt, argv, actarg); - for (j = 0; j < q->vcnt; j++) - free(argv[j]); - free(argv); - } - sq_destroy(sq); - return(MR_SUCCESS); -} - - -/* followup_gzcl: - */ - -followup_gzcl(q, sq, v, action, actarg, cl) - register struct query *q; - register struct save_queue *sq; - register struct validate *v; - register int (*action)(); - int actarg; - client *cl; -{ - int id, i, status; - char **argv; - - while (sq_get_data(sq, &argv)) { - mr_trim_args(q->vcnt, argv); - - id = atoi(argv[i = q->vcnt - 2]); - if (id > 0) - status = id_to_name(id, "USER", &argv[i]); - else - status = id_to_name(-id, "STRING", &argv[i]); - if (status && status != MR_NO_MATCH) - return(status); - - for (i = 1; i < 8; i+=2) { - id = atoi(argv[i+1]); - if (!strcmp(argv[i], "LIST")) { - status = id_to_name(id, "LIST", &argv[i+1]); - } else if (!strcmp(argv[i], "USER")) { - status = id_to_name(id, "USER", &argv[i+1]); - } else if (!strcmp(argv[i], "KERBEROS")) { - status = id_to_name(id, "STRING", &argv[i+1]); - } else if (!strcmp(argv[i], "NONE")) { - status = 0; - free(argv[i+1]); - argv[i+1] = strsave("NONE"); - } else { - status = 0; - free(argv[i+1]); - argv[i+1] = strsave("???"); - } - if (status && status != MR_NO_MATCH) - return(status); - } - - /* send the data */ - (*action)(q->vcnt, argv, actarg); - - /* free saved data */ - for (i = 0; i < q->vcnt; i++) - free(argv[i]); - free(argv); - } - sq_destroy(sq); - return(MR_SUCCESS); -} - - -/* followup_gsha: - */ - -followup_gsha(q, sq, v, action, actarg, cl) - register struct query *q; - register struct save_queue *sq; - register struct validate *v; - register int (*action)(); - int actarg; - client *cl; -{ - char **argv; - int i, id, status; - - while (sq_get_data(sq, &argv)) { - mr_trim_args(q->vcnt, argv); - - id = atoi(argv[4]); - if (id > 0) - status = id_to_name(id, "USER", &argv[4]); - else - status = id_to_name(-id, "STRING", &argv[4]); - if (status && status != MR_NO_MATCH) - return(status); - - id = atoi(argv[2]); - if (!strcmp(argv[1], "LIST")) { - status = id_to_name(id, "LIST", &argv[2]); - } else if (!strcmp(argv[1], "USER")) { - status = id_to_name(id, "USER", &argv[2]); - } else if (!strcmp(argv[1], "KERBEROS")) { - status = id_to_name(id, "STRING", &argv[2]); - } else if (!strcmp(argv[1], "NONE")) { - status = 0; - free(argv[2]); - argv[2] = strsave("NONE"); - } else { - status = 0; - free(argv[2]); - argv[2] = strsave("???"); - } - if (status && status != MR_NO_MATCH) - return(status); - - /* send the data */ - (*action)(q->vcnt, argv, actarg); - - /* free saved data */ - for (i = 0; i < q->vcnt; i++) - free(argv[i]); - free(argv); - } - sq_destroy(sq); - return(MR_SUCCESS); -} +EXEC SQL WHENEVER SQLERROR CALL ingerr; - /* Special query routines */ /* set_pobox - this does all of the real work. @@ -1905,10 +48,10 @@ int set_pobox(q, argv, cl) char **argv; client *cl; { - EXEC SQL BEGIN DECLARE SECTION; + EXEC SQL BEGIN DECLARE SECTION; int user, id; char *box, potype[9]; - EXEC SQL END DECLARE SECTION; + EXEC SQL END DECLARE SECTION; int status; box = argv[2]; @@ -1934,13 +77,7 @@ int set_pobox(q, argv, cl) return(MR_BAD_CHAR); status = name_to_id(box, "STRING", &id); if (status == MR_NO_MATCH) { - EXEC SQL REPEATED SELECT value INTO :id FROM numvalues - WHERE name='strings_id'; - id++; - EXEC SQL REPEATED UPDATE numvalues SET value = :id - WHERE name='strings_id'; - EXEC SQL INSERT INTO strings (string_id, string) - VALUES (:id, :box); + id=add_string(box); } else if (status) return(status); EXEC SQL REPEATED UPDATE users SET potype='SMTP', box_id = :id @@ -1952,7 +89,7 @@ int set_pobox(q, argv, cl) set_pobox_modtime(q, argv, cl); EXEC SQL REPEATED UPDATE tblstats SET updates = updates+1, modtime='now' - WHERE tblstats.table_name='users'; + WHERE table_name='users'; if (ingres_errno) return(mr_errcode); return(MR_SUCCESS); } @@ -1970,23 +107,31 @@ get_list_info(q, aargv, cl, action, actarg) register int (*action)(); int actarg; { - char *argv[13], *malloc(), *realloc(); - EXEC SQL BEGIN DECLARE SECTION; + char *argv[13]; + EXEC SQL BEGIN DECLARE SECTION; char *name, acl_type[9], listname[33], active[5], public[5], hidden[5]; char maillist[5], grouplist[5], gid_str[6], acl_name[256], desc[256]; char modtime[27], modby[256], modwith[9]; int id, rowcount, acl_id, hid, modby_id; - EXEC SQL END DECLARE SECTION; + char qual[80]; + EXEC SQL END DECLARE SECTION; int returned, status; struct save_queue *sq, *sq_create(); returned = rowcount = 0; name = aargv[0]; + convert_wildcards(name); sq = sq_create(); - EXEC SQL DECLARE csr102 CURSOR FOR SELECT list_id FROM list - WHERE name = :name; + sprintf(qual,"name LIKE '%s' ESCAPE '*'",name); + optimize_sql_stmt(qual); + EXEC SQL DECLARE csr102 CURSOR FOR SELECT list_id FROM list + WHERE :qual; + if (ingres_errno) + return(mr_errcode); EXEC SQL OPEN csr102; + if (ingres_errno) + return(mr_errcode); while(1) { EXEC SQL FETCH csr102 INTO :id; @@ -2001,28 +146,18 @@ get_list_info(q, aargv, cl, action, actarg) return(MR_NO_MATCH); argv[0] = listname; argv[1] = active; argv[2] = public; argv[3] = hidden; - argv[4] = maillist; argv[5] = grouplist; argv[6] = gid_str; + argv[4] = maillist; argv[5] = grouplist; argv[6] = gid_str; argv[7] = acl_type; argv[9] = desc; argv[10] = modtime; argv[12] = modwith; while (sq_get_data(sq, &id)) { if (id == 0) continue; argv[6] = gid_str; -/* - * repeat retrieve (listname = l.#name, active = text(l.#active), - * public = text(l.#public), hidden = text(l.#hidden), - * hid = l.#hidden, maillist = text(l.#maillist), - * group = text(l.#group), gid = text(l.#gid), - * acl_type = trim(l.#acl_type), acl_id = l.#acl_id, - * desc = l.#desc, modtime = l.#modtime, modby_id = l.#modby, - * modwith =l.#modwith) - * where l.list_id = :id - */ - EXEC SQL REPEATED SELECT name, text(active), text(public), - text(hidden), hidden, text(maillist), text(grouplist), text(gid), - trim(acl_type), acl_id, desc, modtime, modby, modwith + EXEC SQL REPEATED SELECT name, CHAR(active), CHAR(publicflg), + CHAR(hidden), hidden, CHAR(maillist), CHAR(grouplist), CHAR(gid), + TRIM(acl_type), acl_id, description, CHAR(modtime), modby, modwith INTO :listname, :active, :public, :hidden, :hid, :maillist, - :grouplist, :gid_str, :acl_type, :acl_id, :desc, + :grouplist, :gid_str, :acl_type, :acl_id, :desc, :modtime, :modby_id, :modwith FROM list WHERE list_id = :id; @@ -2080,10 +215,10 @@ int add_member_to_list(q, argv, cl) char **argv; client *cl; { - EXEC SQL BEGIN DECLARE SECTION; - int id, lid, mid, error, who, ref; + EXEC SQL BEGIN DECLARE SECTION; + int id, lid, mid, error, who, ref, rowcnt; char *mtype, dtype[9], *entity; - EXEC SQL END DECLARE SECTION; + EXEC SQL END DECLARE SECTION; int ancestors[MAXLISTDEPTH], aref[MAXLISTDEPTH], acount, a; int descendants[MAXLISTDEPTH], dref[MAXLISTDEPTH], dcount, d; int status; @@ -2094,15 +229,10 @@ int add_member_to_list(q, argv, cl) mtype = argv[1]; mid = *(int *)argv[2]; /* if the member is already a direct member of the list, punt */ -/* - * repeat retrieve (exists = any(m.list_id where m.list_id=@lid and - * m.member_id = :mid and m.member_type = :mtype - * and m.direct = 1)) - */ - EXEC SQL REPEATED SELECT list_id INTO :idummy FROM imembers - WHERE list_id = :lid AND member_id = :mid + EXEC SQL REPEATED SELECT COUNT(list_id) INTO :rowcnt FROM imembers + WHERE list_id = :lid AND member_id = :mid AND member_type = :mtype AND direct = 1; - if (sqlca.sqlerrd[2] > 0) + if (rowcnt > 0) return(MR_EXISTS); if (!strcasecmp(mtype, "STRING")) { buf = malloc(0); @@ -2121,13 +251,17 @@ int add_member_to_list(q, argv, cl) EXEC SQL DECLARE csr103 CURSOR FOR SELECT list_id, ref_count FROM imembers WHERE member_id = :lid AND member_type='LIST'; + if (ingres_errno) + return(mr_errcode); EXEC SQL OPEN csr103; + if (ingres_errno) + return(mr_errcode); while(1) { EXEC SQL FETCH csr103 INTO :id, :ref; if(sqlca.sqlcode != 0) break; aref[acount] = ref; ancestors[acount++] = id; - if (acount >= MAXLISTDEPTH) break; + if (acount >= MAXLISTDEPTH) break; } EXEC SQL CLOSE csr103; if (ingres_errno) return(mr_errcode); @@ -2140,11 +274,15 @@ int add_member_to_list(q, argv, cl) dcount = 1; error = 0; if (!strcmp(mtype, "LIST")) { - EXEC SQL DECLARE csr104 CURSOR FOR + EXEC SQL DECLARE csr104 CURSOR FOR SELECT member_id, member_type, ref_count FROM imembers WHERE list_id = :mid; + if (ingres_errno) + return(mr_errcode); EXEC SQL OPEN csr104; + if (ingres_errno) + return(mr_errcode); while(1) { EXEC SQL FETCH csr104 INTO :id, :dtype, :ref; if(sqlca.sqlcode != 0) break; @@ -2185,31 +323,27 @@ int add_member_to_list(q, argv, cl) if (mid == lid && !strcmp(mtype, "LIST")) { return(MR_LISTLOOP); } -/* - * repeat retrieve (exists = any(m.ref_count where m.list_id = :lid - * and m.member_id = :mid - * and m.member_type = :mtype)) - */ - EXEC SQL REPEATED SELECT ref_count INTO :idummy FROM imembers - WHERE list_id = :lid AND member_id = :mid - AND m.member_type = :mtype; + EXEC SQL REPEATED SELECT COUNT(ref_count) INTO :rowcnt + FROM imembers + WHERE list_id = :lid AND member_id = :mid + AND member_type = :mtype; ref = aref[a] * dref[d]; - if (sqlca.sqlerrd[2] > 0) { + if (rowcnt > 0) { if (a == 0 && d == 0) { - EXEC SQL UPDATE imembers - SET ref_count = ref_count+ref, direct=1 + EXEC SQL UPDATE imembers + SET ref_count = ref_count+:ref, direct=1 WHERE list_id = :lid AND member_id = :mid AND member_type = :mtype; } else { EXEC SQL UPDATE imembers - SET ref_count = ref_count+ref + SET ref_count = ref_count+:ref WHERE list_id = :lid AND member_id = :mid AND member_type = :mtype; } } else { incremental_clear_before(); if (a == 0 && d == 0) { - EXEC SQL INSERT INTO imembers + EXEC SQL INSERT INTO imembers (list_id, member_id, direct, member_type, ref_count) VALUES (:lid, :mid, 1, :mtype, 1); } else { @@ -2227,7 +361,7 @@ int add_member_to_list(q, argv, cl) lid = *(int *)argv[0]; entity = cl->entity; who = cl->client_id; - EXEC SQL REPEATED UPDATE list + EXEC SQL REPEATED UPDATE list SET modtime='now', modby = :who, modwith = :entity WHERE list_id = :lid; if (ingres_errno) return(mr_errcode); @@ -2243,10 +377,10 @@ int delete_member_from_list(q, argv, cl) char **argv; client *cl; { - EXEC SQL BEGIN DECLARE SECTION; + EXEC SQL BEGIN DECLARE SECTION; int id, lid, mid, cnt, error, who, ref; char *mtype, dtype[9], *entity; - EXEC SQL END DECLARE SECTION; + EXEC SQL END DECLARE SECTION; int ancestors[MAXLISTDEPTH], aref[MAXLISTDEPTH], acount, a; int descendants[MAXLISTDEPTH], dref[MAXLISTDEPTH], dcount, d; char *dtypes[MAXLISTDEPTH]; @@ -2256,24 +390,23 @@ int delete_member_from_list(q, argv, cl) mtype = argv[1]; mid = *(int *)argv[2]; /* if the member is not a direct member of the list, punt */ -/* - * repeat retrieve (exists = any(m.list_id where m.list_id=@lid and - * m.member_id = :mid and m.member_type = :mtype - * and m.direct = 1)) - */ - EXEC SQL REPEATED SELECT list_id INTO :idummy FROM imembers - WHERE list_id = :lid AND member_id = :mid + EXEC SQL REPEATED SELECT COUNT(list_id) INTO :cnt FROM imembers + WHERE list_id = :lid AND member_id = :mid AND member_type = :mtype AND direct = 1; if (ingres_errno) return(mr_errcode); - if (sqlca.sqlcode == 100) + if (cnt == 0) return(MR_NO_MATCH); ancestors[0] = lid; aref[0] = 1; acount = 1; - EXEC SQL DECLARE csr105 CURSOR FOR + EXEC SQL DECLARE csr105 CURSOR FOR SELECT list_id, ref_count FROM imembers WHERE member_id = :lid AND member_type = 'LIST'; + if (ingres_errno) + return(mr_errcode); EXEC SQL OPEN csr105; + if (ingres_errno) + return(mr_errcode); while(1) { EXEC SQL FETCH csr105 INTO :id, :ref; if(sqlca.sqlcode!=0) break; @@ -2282,7 +415,7 @@ int delete_member_from_list(q, argv, cl) if (acount >= MAXLISTDEPTH) break; } EXEC SQL CLOSE csr105; - if (ingres_errno) + if (ingres_errno) return(mr_errcode); if (acount >= MAXLISTDEPTH) return(MR_INTERNAL); @@ -2292,10 +425,14 @@ int delete_member_from_list(q, argv, cl) dcount = 1; error = 0; if (!strcmp(mtype, "LIST")) { - EXEC SQL DECLARE csr106 CURSOR FOR + EXEC SQL DECLARE csr106 CURSOR FOR SELECT member_id, member_type, ref_count FROM imembers WHERE list_id = :mid; + if (ingres_errno) + return(mr_errcode); EXEC SQL OPEN csr106; + if (ingres_errno) + return(mr_errcode); while(1) { EXEC SQL FETCH csr106 INTO :id, :dtype, :ref; if(sqlca.sqlcode!=0) break; @@ -2321,7 +458,7 @@ int delete_member_from_list(q, argv, cl) if (dcount >= MAXLISTDEPTH) break; } EXEC SQL CLOSE csr106; - if (ingres_errno) + if (ingres_errno) return(mr_errcode); if (error) return(MR_INTERNAL); @@ -2342,19 +479,19 @@ int delete_member_from_list(q, argv, cl) iargv[1] = mtype; iargv[2] = (char *)mid; incremental_before("members", 0, iargv); - EXEC SQL DELETE FROM imembers - WHERE list_id = :lid AND member_id = :mid + EXEC SQL DELETE FROM imembers + WHERE list_id = :lid AND member_id = :mid AND member_type= :mtype; incremental_clear_after(); } else if (a == 0 && d == 0) { - EXEC SQL UPDATE imembers - SET ref_count = refcount - :ref, direct = 0 - WHERE list_id = :lid AND member_id = :mid + EXEC SQL UPDATE imembers + SET ref_count = ref_count - :ref, direct = 0 + WHERE list_id = :lid AND member_id = :mid AND member_type = :mtype; } else { - EXEC SQL UPDATE imembers - SET ref_count=refcount-:ref - WHERE list_id = :lid AND member_id = :mid + EXEC SQL UPDATE imembers + SET ref_count = ref_count - :ref + WHERE list_id = :lid AND member_id = :mid AND member_type = :mtype; } } @@ -2385,10 +522,10 @@ int get_ace_use(q, argv, cl, action, actarg) int actarg; { int found = 0; - EXEC SQL BEGIN DECLARE SECTION; + EXEC SQL BEGIN DECLARE SECTION; char *atype; int aid, listid, id; - EXEC SQL END DECLARE SECTION; + EXEC SQL END DECLARE SECTION; struct save_queue *sq, *sq_create(); atype = argv[0]; @@ -2402,10 +539,14 @@ int get_ace_use(q, argv, cl, action, actarg) if (!strcmp(atype, "RLIST")) { sq_save_data(sq, aid); /* get all the list_id's of containing lists */ - EXEC SQL DECLARE csr107 CURSOR FOR + EXEC SQL DECLARE csr107 CURSOR FOR SELECT list_id FROM imembers WHERE member_type='LIST' AND member_id = :aid; + if (ingres_errno) + return(mr_errcode); EXEC SQL OPEN csr107; + if (ingres_errno) + return(mr_errcode); while(1) { EXEC SQL FETCH csr107 INTO :listid; if(sqlca.sqlcode != 0) break; @@ -2420,10 +561,14 @@ int get_ace_use(q, argv, cl, action, actarg) } if (!strcmp(atype, "RUSER")) { - EXEC SQL DECLARE csr108 CURSOR FOR + EXEC SQL DECLARE csr108 CURSOR FOR SELECT list_id FROM imembers WHERE member_type='USER' AND member_id = :aid; + if (ingres_errno) + return(mr_errcode); EXEC SQL OPEN csr108; + if (ingres_errno) + return(mr_errcode); while(1) { EXEC SQL FETCH csr108 INTO :listid; if(sqlca.sqlcode != 0) break; @@ -2440,10 +585,14 @@ int get_ace_use(q, argv, cl, action, actarg) } if (!strcmp(atype, "RKERBERO")) { - EXEC SQL DECLARE csr109 CURSOR FOR + EXEC SQL DECLARE csr109 CURSOR FOR SELECT list_id FROM imembers WHERE member_type='KERBEROS' AND member_id = :aid; + if (ingres_errno) + return(mr_errcode); EXEC SQL OPEN csr109; + if (ingres_errno) + return(mr_errcode); while(1) { EXEC SQL FETCH csr109 INTO :listid; if(sqlca.sqlcode != 0) break; @@ -2459,7 +608,7 @@ int get_ace_use(q, argv, cl, action, actarg) found++; } - sq_destroy(sq); + sq_destroy(sq); if (ingres_errno) return(mr_errcode); if (!found) return(MR_NO_MATCH); return(MR_SUCCESS); @@ -2472,26 +621,30 @@ int get_ace_use(q, argv, cl, action, actarg) */ get_ace_internal(atype, aid, action, actarg) - EXEC SQL BEGIN DECLARE SECTION; + EXEC SQL BEGIN DECLARE SECTION; char *atype; int aid; - EXEC SQL END DECLARE SECTION; + EXEC SQL END DECLARE SECTION; int (*action)(); int actarg; { char *rargv[2]; int found = 0; - EXEC SQL BEGIN DECLARE SECTION; + EXEC SQL BEGIN DECLARE SECTION; char name[33]; - EXEC SQL END DECLARE SECTION; + EXEC SQL END DECLARE SECTION; rargv[1] = name; if (!strcmp(atype, "LIST")) { rargv[0] = "FILESYS"; - EXEC SQL DECLARE csr110 CURSOR FOR + EXEC SQL DECLARE csr110 CURSOR FOR SELECT label FROM filesys WHERE owners = :aid; + if (ingres_errno) + return(mr_errcode); EXEC SQL OPEN csr110; + if (ingres_errno) + return(mr_errcode); while(1) { EXEC SQL FETCH csr110 INTO :name; if(sqlca.sqlcode != 0) break; @@ -2501,12 +654,16 @@ get_ace_internal(atype, aid, action, actarg) EXEC SQL CLOSE csr110; rargv[0] = "QUERY"; - EXEC SQL DECLARE csr111 CURSOR FOR + EXEC SQL DECLARE csr111 CURSOR FOR SELECT capability FROM capacls WHERE list_id = :aid ; + if (ingres_errno) + return(mr_errcode); EXEC SQL OPEN csr111; + if (ingres_errno) + return(mr_errcode); while(1) { - EXEC SQL FETCH csr111 INTO :name ; + EXEC SQL FETCH csr111 INTO :name ; if(sqlca.sqlcode != 0) break; (*action)(2, rargv, actarg); found++; @@ -2514,51 +671,67 @@ get_ace_internal(atype, aid, action, actarg) EXEC SQL CLOSE csr111; } else if (!strcmp(atype, "USER")) { rargv[0] = "FILESYS"; - EXEC SQL DECLARE csr112 CURSOR FOR + EXEC SQL DECLARE csr112 CURSOR FOR SELECT label FROM filesys WHERE owner = :aid; + if (ingres_errno) + return(mr_errcode); EXEC SQL OPEN csr112; + if (ingres_errno) + return(mr_errcode); while(1) { EXEC SQL FETCH csr112 INTO :name ; if(sqlca.sqlcode != 0) break; (*action)(2, rargv, actarg); found++; } - EXEC SQL CLOSE csr112; + EXEC SQL CLOSE csr112; } - + rargv[0] = "LIST"; - EXEC SQL DECLARE csr113 CURSOR FOR + EXEC SQL DECLARE csr113 CURSOR FOR SELECT name FROM list WHERE acl_type = :atype AND acl_id = :aid; + if (ingres_errno) + return(mr_errcode); EXEC SQL OPEN csr113; + if (ingres_errno) + return(mr_errcode); while(1) { - EXEC SQL FETCH csr113 INTO :name; + EXEC SQL FETCH csr113 INTO :name; if(sqlca.sqlcode != 0) break; (*action)(2, rargv, actarg); found++; } EXEC SQL CLOSE csr113; - + rargv[0] = "SERVICE"; - EXEC SQL DECLARE csr114 CURSOR FOR + EXEC SQL DECLARE csr114 CURSOR FOR SELECT name FROM servers WHERE acl_type = :atype AND acl_id = :aid; + if (ingres_errno) + return(mr_errcode); EXEC SQL OPEN csr114; + if (ingres_errno) + return(mr_errcode); while(1) { EXEC SQL FETCH csr114 INTO :name; if(sqlca.sqlcode != 0) break; (*action)(2, rargv, actarg); found++; } - EXEC SQL CLOSE csr114; + EXEC SQL CLOSE csr114; rargv[0] = "HOSTACCESS"; - EXEC SQL DECLARE csr115 CURSOR FOR - SELECT name FROM machine, hostaccess - WHERE mach_id = hostaccess.mach_id AND hostaccess.acl_type = :atype - AND hostaccess.acl_id = :aid; + EXEC SQL DECLARE csr115 CURSOR FOR + SELECT name FROM machine m, hostaccess ha + WHERE m.mach_id = ha.mach_id AND ha.acl_type = :atype + AND ha.acl_id = :aid; + if (ingres_errno) + return(mr_errcode); EXEC SQL OPEN csr115; + if (ingres_errno) + return(mr_errcode); while(1) { EXEC SQL FETCH csr115 INTO :name; if(sqlca.sqlcode != 0) break; @@ -2568,15 +741,19 @@ get_ace_internal(atype, aid, action, actarg) EXEC SQL CLOSE csr115; rargv[0] = "ZEPHYR"; - EXEC SQL DECLARE csr116 CURSOR FOR - SELECT class FROM zephyr - WHERE zephyr.xmt_type = :atype AND zephyr.xmt_id = :aid - OR zephyr.sub_type = :atype AND zephyr.sub_id = :aid - OR zephyr.iws_type = :atype AND zephyr.iws_id = :aid - OR zephyr.iui_type = :atype AND zephyr.iui_id = :aid; + EXEC SQL DECLARE csr116 CURSOR FOR + SELECT class FROM zephyr z + WHERE z.xmt_type = :atype AND z.xmt_id = :aid + OR z.sub_type = :atype AND z.sub_id = :aid + OR z.iws_type = :atype AND z.iws_id = :aid + OR z.iui_type = :atype AND z.iui_id = :aid; + if (ingres_errno) + return(mr_errcode); EXEC SQL OPEN csr116; + if (ingres_errno) + return(mr_errcode); while(1) { - EXEC SQL FETCH csr116 INTO :name; + EXEC SQL FETCH csr116 INTO :name; if(sqlca.sqlcode != 0) break; (*action)(2, rargv, actarg); found++; @@ -2605,11 +782,11 @@ int get_lists_of_member(q, argv, cl, action, actarg) { int found = 0, direct = 1; char *rargv[6]; - EXEC SQL BEGIN DECLARE SECTION; + EXEC SQL BEGIN DECLARE SECTION; char *atype; int aid, listid, id; char name[33], active[5], public[5], hidden[5], maillist[5], grouplist[5]; - EXEC SQL END DECLARE SECTION; + EXEC SQL END DECLARE SECTION; atype = argv[0]; aid = *(int *)argv[1]; @@ -2637,40 +814,41 @@ int get_lists_of_member(q, argv, cl, action, actarg) rargv[4] = maillist; rargv[5] = grouplist; if (direct) { -/* - * repeat retrieve (name = list.#name, active = text(list.#active), - * public = text(list.#public), hidden = text(list.#hidden), - * maillist = text(list.#maillist), group = text(list.#group)) - * where list.list_id = m.list_id and m.direct = 1 and - * m.member_type = :atype and m.member_id = :aid - */ - EXEC SQL DECLARE csr117a CURSOR FOR - SELECT name, text(active), text(public), text(hidden), - text(maillist), text(grouplist) - FROM list l, imembers m - WHERE l.list_id = m.list_id AND m.direct = 1 - AND m.member_type = :atype AND m.member_id = :aid; + EXEC SQL DECLARE csr117a CURSOR FOR + SELECT l.name, CHAR(l.active), CHAR(l.publicflg), CHAR(l.hidden), + CHAR(l.maillist), CHAR(l.grouplist) + FROM list l, imembers im + WHERE l.list_id = im.list_id AND im.direct = 1 + AND im.member_type = :atype AND im.member_id = :aid; + if (ingres_errno) + return(mr_errcode); EXEC SQL OPEN csr117a; + if (ingres_errno) + return(mr_errcode); while(1) { - EXEC SQL FETCH csr117a + EXEC SQL FETCH csr117a INTO :name, :active, :public, :hidden, :maillist, :grouplist; - if(sqlca.sqlcode != 0) break; + if(sqlca.sqlcode != 0) break; (*action)(6, rargv, actarg); found++; } EXEC SQL CLOSE csr117a; } else { - EXEC SQL DECLARE csr117b CURSOR FOR - SELECT name, text(active), text(public), text(hidden), - text(maillist), text(grouplist) - FROM list l, imembers m - WHERE l.list_id = m.list_id - AND m.member_type = :atype AND m.member_id = :aid; + EXEC SQL DECLARE csr117b CURSOR FOR + SELECT l.name, CHAR(l.active), CHAR(l.publicflg), CHAR(l.hidden), + CHAR(l.maillist), CHAR(l.grouplist) + FROM list l, imembers im + WHERE l.list_id = im.list_id + AND im.member_type = :atype AND im.member_id = :aid; + if (ingres_errno) + return(mr_errcode); EXEC SQL OPEN csr117b; + if (ingres_errno) + return(mr_errcode); while(1) { - EXEC SQL FETCH csr117b + EXEC SQL FETCH csr117b INTO :name, :active, :public, :hidden, :maillist, :grouplist; - if(sqlca.sqlcode != 0) break; + if(sqlca.sqlcode != 0) break; (*action)(6, rargv, actarg); found++; } @@ -2689,7 +867,7 @@ int get_lists_of_member(q, argv, cl, action, actarg) * where clause based on the arguments, then doing a retrieve. */ -static char *lflags[5] = { "active", "public", "hidden", "maillist", "group" }; +static char *lflags[5] = { "active", "publicflg", "hidden", "maillist", "grouplist" }; int qualified_get_lists(q, argv, cl, action, actarg) struct query *q; @@ -2703,7 +881,32 @@ int qualified_get_lists(q, argv, cl, action, actarg) } -/** get_members_of_list - optimized query for retrieval of list members +/* get_members_of_list - this gets only direct members */ + +get_members_of_list(q, argv, cl, action, actarg) + struct query *q; + char *argv[]; + client *cl; + int (*action)(); + int actarg; +{ + return(gmol_internal(q, argv, cl, action, actarg, 1)); +} + +/* get_end_members_of_list - this gets direct or indirect members */ + +get_end_members_of_list(q, argv, cl, action, actarg) + struct query *q; + char *argv[]; + client *cl; + int (*action)(); + int actarg; +{ + return(gmol_internal(q, argv, cl, action, actarg, 0)); +} + +/** gmol_internal - optimized query for retrieval of list members + ** used by both get_members_of_list and get_end_members_of_list ** ** Inputs: ** argv[0] - list_id @@ -2712,33 +915,44 @@ int qualified_get_lists(q, argv, cl, action, actarg) ** - retrieve USER members, then LIST members, then STRING members **/ -get_members_of_list(q, argv, cl, action, actarg) +gmol_internal(q, argv, cl, action, actarg, flag) struct query *q; char *argv[]; client *cl; int (*action)(); int actarg; + int flag; { - EXEC SQL BEGIN DECLARE SECTION; - int list_id, member_id; + EXEC SQL BEGIN DECLARE SECTION; + int list_id, member_id, direct; char member_name[129], member_type[9]; - EXEC SQL END DECLARE SECTION; + EXEC SQL END DECLARE SECTION; char *targv[2]; int members; struct save_queue *sq; + /* true/false flag indicates whether to display only direct members. */ + if (flag) + direct = 0; + else + direct = -1; + list_id = *(int *)argv[0]; members = 0; sq = sq_create(); - EXEC SQL DECLARE csr118 CURSOR FOR + EXEC SQL DECLARE csr118 CURSOR FOR SELECT member_type, member_id FROM imembers - WHERE list_id = :list_id AND direct=1; + WHERE list_id = :list_id AND direct > :direct; + if (ingres_errno) + return(mr_errcode); EXEC SQL OPEN csr118; + if (ingres_errno) + return(mr_errcode); while(1) { - EXEC SQL FETCH csr118 INTO :member_type, :member_id; + EXEC SQL FETCH csr118 INTO :member_type, :member_id; if (sqlca.sqlcode != 0) break; - if (members++ > 49) + if (members++ > 49) break; sq_save_data(sq, ((int)member_type[0] << 24) | (member_id & 0xffffff)); } @@ -2781,12 +995,16 @@ get_members_of_list(q, argv, cl, action, actarg) targv[1] = member_name; targv[0] = "USER"; - EXEC SQL DECLARE csr119 CURSOR FOR - SELECT users.login FROM users, imembers - WHERE imembers.list_id = :list_id AND imembers.member_type = 'USER' - AND imembers.member_id = users.users_id AND imembers.direct=1 + EXEC SQL DECLARE csr119 CURSOR FOR + SELECT u.login FROM users u, imembers im + WHERE im.list_id = :list_id AND im.member_type = 'USER' + AND im.member_id = u.users_id AND im.direct > :direct ORDER BY 1; + if (ingres_errno) + return(mr_errcode); EXEC SQL OPEN csr119; + if (ingres_errno) + return(mr_errcode); while(1) { EXEC SQL FETCH csr119 INTO :member_name; if(sqlca.sqlcode != 0) break; @@ -2796,14 +1014,18 @@ get_members_of_list(q, argv, cl, action, actarg) if (ingres_errno) return(mr_errcode); targv[0] = "LIST"; - EXEC SQL DECLARE csr120 CURSOR FOR - SELECT list.name FROM list, imembers - WHERE imembers.list_id = :list_id AND imembers.member_type='LIST' - AND imembers.member_id = list.list_id AND imembers.direct=1 + EXEC SQL DECLARE csr120 CURSOR FOR + SELECT l.name FROM list l, imembers im + WHERE im.list_id = :list_id AND im.member_type='LIST' + AND im.member_id = l.list_id AND im.direct > :direct ORDER BY 1; + if (ingres_errno) + return(mr_errcode); EXEC SQL OPEN csr120; + if (ingres_errno) + return(mr_errcode); while(1) { - EXEC SQL FETCH csr120 INTO :member_name; + EXEC SQL FETCH csr120 INTO :member_name; if(sqlca.sqlcode != 0) break; (*action)(2, targv, actarg); } @@ -2811,14 +1033,18 @@ get_members_of_list(q, argv, cl, action, actarg) if (ingres_errno) return(mr_errcode); targv[0] = "STRING"; - EXEC SQL DECLARE csr121 CURSOR FOR - SELECT strings.string FROM strings, imembers - WHERE imembers.list_id = :list_id AND imembers.member_type='STRING' - AND imembers.member_id = strings.string_id AND imembers.direct=1 + EXEC SQL DECLARE csr121 CURSOR FOR + SELECT CHAR(str.string) FROM strings str, imembers im + WHERE im.list_id = :list_id AND im.member_type='STRING' + AND im.member_id = str.string_id AND im.direct > :direct ORDER BY 1; + if (ingres_errno) + return(mr_errcode); EXEC SQL OPEN csr121; + if (ingres_errno) + return(mr_errcode); while(1) { - EXEC SQL FETCH csr121 INTO :member_name; + EXEC SQL FETCH csr121 INTO :member_name; if(sqlca.sqlcode != 0) break; (*action)(2, targv, actarg); } @@ -2826,14 +1052,19 @@ get_members_of_list(q, argv, cl, action, actarg) if (ingres_errno) return(mr_errcode); targv[0] = "KERBEROS"; - EXEC SQL DECLARE csr122 CURSOR FOR - SELECT strings.string FROM strings, imembers - WHERE imembers.list_id = :list_id AND imembers.member_type='KERBEROS' - AND imembers.member_id = strings.string_id AND imembers.direct=1 + EXEC SQL DECLARE csr122 CURSOR FOR + SELECT CHAR(str.string) FROM strings str, imembers im + WHERE im.list_id = :list_id AND im.member_type='KERBEROS' + AND im.member_id = str.string_id + AND im.direct > :direct ORDER BY 1; + if (ingres_errno) + return(mr_errcode); EXEC SQL OPEN csr122; + if (ingres_errno) + return(mr_errcode); while(1) { - EXEC SQL FETCH csr122 INTO :member_name; + EXEC SQL FETCH csr122 INTO :member_name; if(sqlca.sqlcode != 0) break; (*action)(2, targv, actarg); } @@ -2855,9 +1086,9 @@ int count_members_of_list(q, argv, cl, action, actarg) int (*action)(); int actarg; { - EXEC SQL BEGIN DECLARE SECTION; + EXEC SQL BEGIN DECLARE SECTION; int list, ct = 0; - EXEC SQL END DECLARE SECTION; + EXEC SQL END DECLARE SECTION; char *rargv[1], countbuf[5]; list = *(int *)argv[0]; @@ -2917,25 +1148,24 @@ int qualified_get(q, argv, action, actarg, start, range, field, flags) strcpy(qual, start); for (i = 0; i < q->argc; i++) { if (!strcmp(argv[i], "TRUE")) { - sprintf(buf, " and %s.%s != 0", range, flags[i]); + sprintf(buf, " AND %s.%s != 0", range, flags[i]); (void) strcat(qual, buf); } else if (!strcmp(argv[i], "FALSE")) { - sprintf(buf, " and %s.%s = 0", range, flags[i]); + sprintf(buf, " AND %s.%s = 0", range, flags[i]); (void) strcat(qual, buf); } } - + rargv[0] = SQLDA->sqlvar[0].sqldata; - sprintf(stmt_buf,"SELECT %s.%s FROM %s WHERE %s",q->rtable,field,q->rtable,qual); - EXEC SQL PREPARE stmt INTO :SQLDA USING NAMES FROM :stmt_buf; - if((mr_errcode=mr_check_SQLDA(SQLDA)) != MR_SUCCESS) - return(mr_errcode); + sprintf(stmt_buf,"SELECT CHAR(%s.%s) FROM %s %s WHERE %s",range,field,q->rtable,range,qual); + EXEC SQL PREPARE stmt INTO :SQLDA USING NAMES FROM :stmt_buf; + if(sqlca.sqlcode) + return(MR_INTERNAL); EXEC SQL DECLARE csr123 CURSOR FOR stmt; EXEC SQL OPEN csr123; while(1) { EXEC SQL FETCH csr123 USING DESCRIPTOR :SQLDA; if(sqlca.sqlcode != 0) break; - mr_fix_nulls_in_SQLDA(SQLDA); rowcount++; (*action)(1, rargv, actarg); } @@ -2949,7 +1179,7 @@ int qualified_get(q, argv, action, actarg, start, range, field, flags) /* qualified_get_serverhost: passed "TRUE", "FALSE", or "DONTCARE" for each of * the five flags associated with each serverhost. It will return the name of - * each service and host that meets the quailifications. It does this by + * each service and host that meets the quailifications. It does this by * building a where clause based on the arguments, then doing a retrieve. */ @@ -2963,32 +1193,34 @@ int qualified_get_serverhost(q, argv, cl, action, actarg) int (*action)(); int actarg; { - EXEC SQL BEGIN DECLARE SECTION; + EXEC SQL BEGIN DECLARE SECTION; char sname[33], mname[33], qual[256]; - EXEC SQL END DECLARE SECTION; + EXEC SQL END DECLARE SECTION; char *rargv[2], buf[32]; int i, rowcount; - /** the uppercase() function is INGRES-specific */ - sprintf(qual, "machine.mach_id = serverhosts.mach_id AND \ -serverhosts.service = uppercase('%s')", + sprintf(qual, "m.mach_id = sh.mach_id AND sh.service = uppercase('%s')", argv[0]); for (i = 1; i < q->argc; i++) { if (!strcmp(argv[i], "TRUE")) { - sprintf(buf, " AND serverhosts.%s != 0", shflags[i]); + sprintf(buf, " AND sh.%s != 0", shflags[i]); strcat(qual, buf); } else if (!strcmp(argv[i], "FALSE")) { - sprintf(buf, " AND serverhosts.%s = 0", shflags[i]); + sprintf(buf, " AND sh.%s = 0", shflags[i]); strcat(qual, buf); } } - + rargv[0] = sname; rargv[1] = mname; - EXEC SQL DECLARE csr124 CURSOR FOR - SELECT serverhosts.service, machine.name FROM serverhosts, machine - WHERE :qual; + EXEC SQL DECLARE csr124 CURSOR FOR + SELECT sh.service, m.name FROM serverhosts sh, machine m + WHERE :qual; + if (ingres_errno) + return(mr_errcode); EXEC SQL OPEN csr124; + if (ingres_errno) + return(mr_errcode); while(1) { EXEC SQL FETCH csr124 INTO :sname, :mname; if(sqlca.sqlcode != 0) break; @@ -3007,7 +1239,7 @@ serverhosts.service = uppercase('%s')", /* register_user - change user's login name and allocate a pobox, group, * filesystem, and quota for them. The user's status must start out as 0, * and is left as 2. Arguments are: user's UID, new login name, and user's - * type for filesystem allocation (MR_FS_STUDENT, MR_FS_FACULTY, + * type for filesystem allocation (MR_FS_STUDENT, MR_FS_FACULTY, * MR_FS_STAFF, MR_FS_MISC). */ @@ -3016,13 +1248,13 @@ register_user(q, argv, cl) char **argv; client *cl; { - EXEC SQL BEGIN DECLARE SECTION; - char *login, dir[65], *entity, *directory, machname[33]; + EXEC SQL BEGIN DECLARE SECTION; + char *login, dir[65], *entity, directory[129], machname[33]; int who, rowcount, mid, uid, users_id, flag, utype, nid, list_id, quota; - int size, alloc, pid, m_id, ostatus, nstatus, gidval, fsidval; - EXEC SQL END DECLARE SECTION; + int size, alloc, pid, ostatus, nstatus, gidval, fsidval, npidval; + static int m_id = 0, def_quota = 0; + EXEC SQL END DECLARE SECTION; char buffer[256], *aargv[3]; - int maxsize; entity = cl->entity; who = cl->client_id; @@ -3042,32 +1274,44 @@ register_user(q, argv, cl) return(MR_NOT_UNIQUE); /* check new login name */ - EXEC SQL REPEATED SELECT login INTO :cdummy FROM users + EXEC SQL REPEATED SELECT COUNT(login) INTO :rowcount FROM users WHERE login = :login AND users_id != :users_id; if (ingres_errno) return(mr_errcode); - if (sqlca.sqlerrd[2] > 0) return(MR_IN_USE); - EXEC SQL REPEATED SELECT name INTO :cdummy FROM list + if (rowcount > 0) return(MR_IN_USE); + EXEC SQL REPEATED SELECT COUNT(name) INTO :rowcount FROM list WHERE name = :login; if (ingres_errno) return(mr_errcode); - if (sqlca.sqlerrd[2] > 0) return(MR_IN_USE); - EXEC SQL REPEATED SELECT label INTO :cdummy FROM filesys + if (rowcount > 0) return(MR_IN_USE); + EXEC SQL REPEATED SELECT COUNT(label) INTO :rowcount FROM filesys WHERE label = :login; if (ingres_errno) return(mr_errcode); - if (sqlca.sqlerrd[2] > 0) return(MR_IN_USE); + if (rowcount > 0) return(MR_IN_USE); com_err(whoami, 0, "login name OK"); /* choose place for pobox, put in mid */ - EXEC SQL REPEATED SELECT sh.mach_id, m.name - INTO :mid, :machname FROM serverhosts sh, machine m - WHERE sh.service='POP' AND sh.value2 - sh.value1 = - (SELECT MAX(value2 - value1) FROM serverhosts - WHERE service = 'POP'); - if (ingres_errno) return(mr_errcode); - if (sqlca.sqlerrd[2] == 0) - return(MR_NO_POBOX); + EXEC SQL DECLARE csr130 CURSOR FOR + SELECT sh.mach_id, m.name FROM serverhosts sh, machine m + WHERE sh.service='POP' AND sh.mach_id=m.mach_id + AND sh.value2 - sh.value1 = + (SELECT MAX(value2 - value1) FROM serverhosts + WHERE service = 'POP'); + if (ingres_errno) + return(mr_errcode); + EXEC SQL OPEN csr130; + if (ingres_errno) + return(mr_errcode); + EXEC SQL FETCH csr130 INTO :mid, :machname; + if (sqlca.sqlerrd[2] == 0) { + EXEC SQL CLOSE csr130; + if (ingres_errno) return(mr_errcode); + return(MR_NO_POBOX); + } else { + EXEC SQL CLOSE csr130; + if (ingres_errno) return(mr_errcode); + } /* change login name, set pobox */ - sprintf(buffer, "users.users_id = %d", users_id); + sprintf(buffer, "u.users_id = %d", users_id); incremental_before("users", buffer, 0); nstatus = 2; if (ostatus == 5 || ostatus == 6) @@ -3090,7 +1334,7 @@ register_user(q, argv, cl) return(MR_NO_ID); if (set_next_object_id("list_id", "list", 0)) return(MR_NO_ID); - EXEC SQL REPEATED SELECT value INTO :list_id FROM numvalues + EXEC SQL REPEATED SELECT value INTO :list_id FROM numvalues WHERE name='list_id'; if (ingres_errno) return(mr_errcode); if (sqlca.sqlerrd[2] != 1) @@ -3098,8 +1342,8 @@ register_user(q, argv, cl) incremental_clear_before(); EXEC SQL SELECT value INTO :gidval FROM numvalues WHERE name = 'gid'; EXEC SQL REPEATED INSERT INTO list - (name, list_id, active, public, hidden, maillist, grouplist, - gid, desc, acl_type, acl_id, + (name, list_id, active, publicflg, hidden, maillist, grouplist, + gid, description, acl_type, acl_id, modtime, modby, modwith) VALUES (:login, :list_id, 1, 0, 0, 0, 1, :gidval, 'User Group', 'USER', :users_id, @@ -3113,7 +1357,7 @@ register_user(q, argv, cl) aargv[1] = "USER"; aargv[2] = (char *) users_id; incremental_clear_before(); - EXEC SQL REPEATED INSERT INTO imembers + EXEC SQL REPEATED INSERT INTO imembers (list_id, member_type, member_id, ref_count, direct) VALUES (:list_id, 'USER', :users_id, 1, 1); if (ingres_errno) return(mr_errcode); @@ -3121,82 +1365,64 @@ register_user(q, argv, cl) return(MR_INTERNAL); incremental_after("members", 0, aargv); - /* decide where to put filesystem */ - maxsize = 0; - directory = NULL; - EXEC SQL DECLARE csr125 CURSOR FOR - SELECT mach_id, trim(nfsphys.dir), nfsphys_id, status, size, allocated - FROM nfsphys; - EXEC SQL OPEN csr125; - while(1) { - EXEC SQL FETCH csr125 INTO :mid, :dir, :nid, :flag, :size, :alloc; - if(sqlca.sqlcode != 0) break; - if ((flag & utype) && (size != 0) && (size - alloc > maxsize)) { - maxsize = size - alloc; - if (directory) - free(directory); - directory = strsave(dir); - pid = nid; - m_id = mid; - } + if (m_id == 0) { + /* Cell Name (I know, it shouldn't be hard coded...) */ + strcpy(machname, "ATHENA.MIT.EDU"); + EXEC SQL SELECT mach_id INTO :m_id FROM machine + WHERE name = :machname; } - EXEC SQL CLOSE csr125; - if (ingres_errno) return(mr_errcode); - if (maxsize == 0) - return(MR_NO_FILESYS); /* create filesystem */ if (set_next_object_id("filsys_id", "filesys", 0)) return(MR_NO_ID); - incremental_clear_before(); + incremental_clear_before(); + if (islower(login[0]) && islower(login[1])) { + sprintf(directory, "/afs/athena.mit.edu/user/%c/%c/%s", + login[0], login[1], login); + } else { + sprintf(directory, "/afs/athena.mit.edu/user/other/%s", login); + } + EXEC SQL SELECT value INTO :fsidval FROM numvalues WHERE numvalues.name='filsys_id'; EXEC SQL REPEATED INSERT INTO filesys - (filsys_id, phys_id, label, type, mach_id, name, - mount, access, comments, owner, owners, createflg, + (filsys_id, phys_id, label, type, mach_id, name, + mount, access, comments, owner, owners, createflg, lockertype, modtime, modby, modwith) VALUES - (:fsidval, :pid, :login, 'NFS', :m_id, :directory+'/'+:login, + (:fsidval, 0, :login, 'AFS', :m_id, :directory, '/mit/'+:login, 'w', 'User Locker', :users_id, :list_id, 1, - 'HOMEDIR', 'now', :who, :entity) ; + 'HOMEDIR', 'now', :who, :entity); + if (ingres_errno) return(mr_errcode); if (sqlca.sqlerrd[2] != 1) return(MR_INTERNAL); - incremental_after("filesys", - "fs.filsys_id = numvalues.value and numvalues.name = 'filsys_id'", - 0); - com_err(whoami, 0, "filesys on mach %d in %s/%s", m_id, - directory, login); + sprintf(buffer,"fs.filsys_id = %d",fsidval); + incremental_after("filesys", buffer, 0); /* set quota */ - EXEC SQL REPEATED SELECT value INTO :quota FROM numvalues - WHERE name='def_quota'; - if (ingres_errno) return(mr_errcode); - if (sqlca.sqlerrd[2] != 1) - return(MR_NO_QUOTA); + if (def_quota == 0) { + EXEC SQL REPEATED SELECT value INTO :def_quota FROM numvalues + WHERE name='def_quota'; + if (ingres_errno) return(mr_errcode); + if (sqlca.sqlerrd[2] != 1) + return(MR_NO_QUOTA); + + } incremental_clear_before(); - EXEC SQL SELECT value INTO :fsidval FROM numvalues - WHERE numvalues.name = 'filsys_id'; - EXEC SQL REPEATED INSERT INTO quota + EXEC SQL REPEATED INSERT INTO quota (entity_id, filsys_id, type, quota, phys_id, modtime, modby, modwith) VALUES - (:users_id, :fsidval, 'USER', :quota, :pid, 'now', :who, :entity); - if (ingres_errno) return(mr_errcode); - if (sqlca.sqlerrd[2] != 1) - return(MR_INTERNAL); - EXEC SQL REPEATED UPDATE nfsphys SET allocated=allocated + :quota - WHERE nfsphys_id = filesys.phys_id - AND filesys.filsys_id = numvalues.value - AND numvalues.name = 'filsys_id'; + (0, :fsidval, 'ANY', :def_quota, 0, 'now', :who, :entity); if (ingres_errno) return(mr_errcode); if (sqlca.sqlerrd[2] != 1) return(MR_INTERNAL); aargv[0] = login; - aargv[1] = "USER"; + aargv[1] = "ANY"; aargv[2] = login; - sprintf(buffer, "q.entity_id = %d and q.filsys_id = numvalues.value and q.type = 'USER' and numvalues.name = 'filsys_id'", users_id); + sprintf(buffer, "q.entity_id = 0 and q.filsys_id = %d and q.type = 'ANY'", fsidval); incremental_after("quota", buffer, aargv); - com_err(whoami, 0, "quota of %d assigned", quota); + com_err(whoami, 0, "quota of %d assigned", def_quota); if (ingres_errno) return(mr_errcode); cache_entry(login, "USER", users_id); @@ -3222,560 +1448,55 @@ register_user(q, argv, cl) ** **/ -static int set_pop_usage(id, cnt) - EXEC SQL BEGIN DECLARE SECTION; +int set_pop_usage(id, cnt) + EXEC SQL BEGIN DECLARE SECTION; int id; int cnt; - EXEC SQL END DECLARE SECTION; + EXEC SQL END DECLARE SECTION; { EXEC SQL REPEATED UPDATE serverhosts SET value1 = value1 + :cnt WHERE serverhosts.service = 'POP' AND serverhosts.mach_id = :id; - - if (ingres_errno) return(mr_errcode); - return(MR_SUCCESS); -} - - - -/* Validation Routines */ - -validate_row(q, argv, v) - register struct query *q; - char *argv[]; - register struct validate *v; -{ - EXEC SQL BEGIN DECLARE SECTION; - char *name; - char qual[128]; - int rowcount; - EXEC SQL END DECLARE SECTION; - - /* build where clause */ - build_qual(v->qual, v->argc, argv, qual); - -#ifdef NEVER - /** I'm pretty sure we don't need this now */ - /* setup ingres variables */ - name = v->field; -#endif - - if (log_flags & LOG_VALID) - /* tell the logfile what we're doing */ - com_err(whoami, 0, "validating row: %s", qual); - - /* look for the record */ -/* - * range of rvar is table - * retrieve (rowcount = count(rvar.name where qual)) - */ - sprintf(stmt_buf,"SELECT COUNT (*) FROM %s %s WHERE %s",q->rtable,q->rvar,qual); - EXEC SQL PREPARE stmt INTO :SQLDA USING NAMES FROM :stmt_buf; - EXEC SQL DECLARE csr126 CURSOR FOR stmt; - EXEC SQL OPEN csr126; - EXEC SQL FETCH csr126 USING DESCRIPTOR :SQLDA; - EXEC SQL CLOSE csr126; - rowcount=*(int *)SQLDA->[0].sqldata; - - if (ingres_errno) return(mr_errcode); - if (rowcount == 0) return(MR_NO_MATCH); - if (rowcount > 1) return(MR_NOT_UNIQUE); - return(MR_EXISTS); -} - -validate_fields(q, argv, vo, n) - struct query *q; - register char *argv[]; - register struct valobj *vo; - register int n; -{ - register int status; - - while (--n >= 0) { - switch (vo->type) { - case V_NAME: - if (log_flags & LOG_VALID) - com_err(whoami, 0, "validating %s in %s: %s", - vo->namefield, vo->table, argv[vo->index]); - status = validate_name(argv, vo); - break; - - case V_ID: - if (log_flags & LOG_VALID) - com_err(whoami, 0, "validating %s in %s: %s", - vo->idfield, vo->table, argv[vo->index]); - status = validate_id(q, argv, vo); - break; - - case V_DATE: - if (log_flags & LOG_VALID) - com_err(whoami, 0, "validating date: %s", argv[vo->index]); - status = validate_date(argv, vo); - break; - - case V_TYPE: - if (log_flags & LOG_VALID) - com_err(whoami, 0, "validating %s type: %s", - vo->table, argv[vo->index]); - status = validate_type(argv, vo); - break; - - case V_TYPEDATA: - if (log_flags & LOG_VALID) - com_err(whoami, 0, "validating typed data (%s): %s", - argv[vo->index - 1], argv[vo->index]); - status = validate_typedata(q, argv, vo); - break; - - case V_RENAME: - if (log_flags & LOG_VALID) - com_err(whoami, 0, "validating rename %s in %s", - argv[vo->index], vo->table); - status = validate_rename(argv, vo); - break; - - case V_CHAR: - if (log_flags & LOG_VALID) - com_err(whoami, 0, "validating chars: %s", argv[vo->index]); - status = validate_chars(argv[vo->index]); - break; - - case V_SORT: - status = MR_EXISTS; - break; - - case V_LOCK: - status = lock_table(vo); - break; - } - - if (status != MR_EXISTS) return(status); - vo++; - } if (ingres_errno) return(mr_errcode); return(MR_SUCCESS); } -/* validate_chars: verify that there are no illegal characters in - * the string. Legal characters are printing chars other than - * ", *, ?, \, [ and ]. - */ -static int illegalchars[] = { - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* ^@ - ^O */ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* ^P - ^_ */ - 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, /* SPACE - / */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, /* 0 - ? */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* : - O */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, /* P - _ */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* ` - o */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, /* p - ^? */ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -}; - -validate_chars(s) -register char *s; -{ - while (*s) - if (illegalchars[*s++]) - return(MR_BAD_CHAR); - return(MR_EXISTS); -} - +/* BEGIN KLUDGE + special-case `ghal "*" "name"' since Ingres does it slowly */ -validate_id(q, argv, vo) +int get_hostalias(q, argv, cl, action, actarg) struct query *q; char *argv[]; - register struct valobj *vo; -{ - EXEC SQL BEGIN DECLARE SECTION; - char *name, *tbl, *namefield, *idfield; - int id, rowcount; - EXEC SQL END DECLARE SECTION; - int status; - register char *c; - - name = argv[vo->index]; - tbl = vo->table; - namefield = vo->namefield; - idfield = vo->idfield; - - if ((!strcmp(tbl, "users") && !strcmp(namefield, "login")) || - !strcmp(tbl, "machine") || - !strcmp(tbl, "filesys") || - !strcmp(tbl, "list") || - !strcmp(tbl, "cluster") || - !strcmp(tbl, "strings")) { - if (!strcmp(tbl, "machine")) - for (c = name; *c; c++) if (islower(*c)) *c = toupper(*c); - status = name_to_id(name, tbl, &id); - if (status == 0) { - *(int *)argv[vo->index] = id; - return(MR_EXISTS); - } else if (status == MR_NO_MATCH && !strcmp(tbl, "strings") && - (q->type == APPEND || q->type == UPDATE)) { - EXEC SQL SELECT value INTO :id FROM numvalues - WHERE name = 'strings_id'; - id++; - EXEC SQL UPDATE numvalues SET value = :id WHERE name = 'string_id'; - EXEC SQL INSERT INTO strings (string_id, string) VALUES (:id, :name); - cache_entry(name, "STRING", id); - *(int *)argv[vo->index] = id; - return(MR_EXISTS); - } else if (status == MR_NO_MATCH || status == MR_NOT_UNIQUE) - return(vo->error); - else - return(status); - } - - if (!strcmp(namefield, "uid")) { -/* - * retrieve (id = table.idfield) where table.namefield = int4(name) - */ - sprintf(stmt_buf,"SELECT %s FROM %s WHERE %s.%s = %s",idfield,tbl,tbl,namefield,name); - if (ingres_errno) return(mr_errcode); - } else { -/* - * retrieve (id = table.idfield) where table.namefield = name - */ - sprintf(stmt_buf,"SELECT %s FROM %s WHERE %s.%s = '%s'",idfield,tbl,tbl,namefield,name); - if (ingres_errno) return(mr_errcode); - } - EXEC SQL PREPARE stmt INTO :SQLDA USING NAMES FROM :stmt_buf; - EXEC SQL DECLARE csr127 CURSOR FOR stmt; - EXEC SQL OPEN csr127; - rowcount=0; - EXEC SQL FETCH csr127 USING DESCRIPTOR :SQLDA; - if(sqlca.sqlcode == 0) { - rowcount++; - EXEC SQL FETCH csr127 USING DESCRIPTOR :SQLDA; - if(sqlca.sqlcode == 0) rowcount++ - } - EXEC SQL CLOSE csr127; - - if (rowcount != 1) return(vo->error); - *argv[vo->index] = *SQLDA->sqlvar[0]->sqldata; - return(MR_EXISTS); -} - -validate_name(argv, vo) - char *argv[]; - register struct valobj *vo; -{ - EXEC SQL BEGIN DECLARE SECTION; - char *name, *tbl, *namefield; - int rowcount; - EXEC SQL END DECLARE SECTION; - register char *c; - - name = argv[vo->index]; - tbl = vo->table; - namefield = vo->namefield; - if (!strcmp(tbl, "servers") && !strcmp(namefield, "name")) { - for (c = name; *c; c++) - if (islower(*c)) - *c = toupper(*c); - } -/* - * retrieve (rowcount = countu(table.namefield - * where table.namefield = name)) - */ - sprintf(stmt_buf,"SELECT COUNT (DISTINCT *) FROM %s WHERE %s.%s = '%s'", - tbl,tbl,namefield,name); - EXEC SQL PREPARE stmt INTO :SQLDA USING NAMES FROM :stmt_buf; - EXEC SQL DECLARE csr128 CURSOR FOR stmt; - EXEC SQL OPEN csr128; - EXEC SQL FETCH csr128 USING DESCRIPTOR :SQLDA; - rowcount=*(int *)SQLDA->sqlvar[0]->sqldata; - EXEC SQL CLOSE csr128; - - if (ingres_errno) return(mr_errcode); - return ((rowcount == 1) ? MR_EXISTS : vo->error); -} - -validate_date(argv, vo) - char *argv[]; - struct valobj *vo; -{ - EXEC SQL BEGIN DECLARE SECTION; - char *idate; - double dd; - int errorno; - EXEC SQL END DECLARE SECTION; - - idate = argv[vo->index]; -/* - * retrieve (dd = interval("years", date(idate) - date("today"))) - */ - EXEC SQL SELECT interval('years',date(:idate)-date('today')) INTO :dd; - - if (sqlca.sqlcode != 0 || dd > 5.0) return(MR_DATE); - return(MR_EXISTS); -} - - -validate_rename(argv, vo) -char *argv[]; -struct valobj *vo; -{ - EXEC SQL BEGIN DECLARE SECTION; - char *name, *tbl, *namefield, *idfield; - int id; - EXEC SQL END DECLARE SECTION; - int status; - register char *c; - - c = name = argv[vo->index]; - while (*c) - if (illegalchars[*c++]) - return(MR_BAD_CHAR); - tbl = vo->table; - /* minor kludge to upcasify machine names */ - if (!strcmp(tbl, "machine")) - for (c = name; *c; c++) if (islower(*c)) *c = toupper(*c); - namefield = vo->namefield; - idfield = vo->idfield; - id = -1; - if (idfield == 0) { - if (!strcmp(argv[vo->index], argv[vo->index - 1])) - return(MR_EXISTS); -/* - * retrieve (id = any(table.namefield where table.namefield = name)) - */ - sprintf(stmt_buf,"SELECT %s FROM %s WHERE %s.%s = '%s'", - namefield,tbl,tbl,namefield,name); - EXEC SQL PREPARE stmt INTO :SQLDA USING NAMES FROM :stmt_buf; - EXEC SQL DECLARE csr129 CURSOR FOR stmt; - EXEC SQL OPEN csr129; - EXEC SQL FETCH csr129 USING DESCRIPTOR :SQLDA; - if(sqlca.sqlcode == 0) id=1; else id=0; - EXEC SQL CLOSE csr129; - - if (ingres_errno) return(mr_errcode); - if (id) - return(vo->error); - else - return(MR_EXISTS); - } - status = name_to_id(name, tbl, &id); - if (status == MR_NO_MATCH || id == *(int *)argv[vo->index - 1]) - return(MR_EXISTS); - else - return(vo->error); -} - - -validate_type(argv, vo) - char *argv[]; - register struct valobj *vo; -{ - EXEC SQL BEGIN DECLARE SECTION; - char *typename; - char *value; - EXEC SQL END DECLARE SECTION; - register char *c; - - typename = vo->table; - c = value = argv[vo->index]; - while (*c) { - if (illegalchars[*c]) - return(MR_BAD_CHAR); - } - - /* uppercase type fields */ - for (c = value; *c; c++) if (islower(*c)) *c = toupper(*c); - - EXEC SQL SELECT trans INTO :cdummy FROM alias - WHERE name = :typename AND type='TYPE' AND trans = :value; - if (ingres_errno) return(mr_errcode); - return (sqlca.sqlerrd[2] ? MR_EXISTS : vo->error); -} - -/* validate member or type-specific data field */ - -validate_typedata(q, argv, vo) - register struct query *q; - register char *argv[]; - register struct valobj *vo; + client *cl; + int (*action)(); + int actarg; { - EXEC SQL BEGIN DECLARE SECTION; - char *name; - char *field_type; - char data_type[129]; + EXEC SQL BEGIN DECLARE SECTION; + char *alias=argv[0], *machine=argv[1], qual[BUFSIZ], *p; int id; - EXEC SQL END DECLARE SECTION; - int status; - char *index(); - register char *c; - - /* get named object */ - name = argv[vo->index]; - - /* get field type string (known to be at index-1) */ - field_type = argv[vo->index-1]; - - /* get corresponding data type associated with field type name */ - EXEC SQL SELECT trans INTO :data_type FROM alias - WHERE name = :field_type AND type='TYPEDATA'; - if (ingres_errno) return(mr_errcode); - if (sqlca.sqlerrd[2] != 1) return(MR_TYPE); - - /* now retrieve the record id corresponding to the named object */ - if (index(data_type, ' ')) - *index(data_type, ' ') = 0; - if (!strcmp(data_type, "user")) { - /* USER */ - status = name_to_id(name, data_type, &id); - if (status && (status == MR_NO_MATCH || status == MR_NOT_UNIQUE)) - return(MR_USER); - if (status) return(status); - } else if (!strcmp(data_type, "list")) { - /* LIST */ - status = name_to_id(name, data_type, &id); - if (status && status == MR_NOT_UNIQUE) - return(MR_LIST); - if (status == MR_NO_MATCH) { - /* if idfield is non-zero, then if argv[0] matches the string - * that we're trying to resolve, we should get the value of - * numvalues.[idfield] for the id. - */ - if (vo->idfield && !strcmp(argv[0], argv[vo->index])) { - set_next_object_id(q->validate->object_id, q->rtable, 0); - name = vo->idfield; - EXEC SQL REPEATED SELECT value INTO :id FROM numvalues - WHERE name = :name; - if (sqlca.sqlerrd[2] != 1) return(MR_LIST); - } else - return(MR_LIST); - } else if (status) return(status); - } else if (!strcmp(data_type, "machine")) { - /* MACHINE */ - for (c = name; *c; c++) if (islower(*c)) *c = toupper(*c); - status = name_to_id(name, data_type, &id); - if (status && (status == MR_NO_MATCH || status == MR_NOT_UNIQUE)) - return(MR_MACHINE); - if (status) return(status); - } else if (!strcmp(data_type, "string")) { - /* STRING */ - status = name_to_id(name, data_type, &id); - if (status && status == MR_NOT_UNIQUE) - return(MR_STRING); - if (status == MR_NO_MATCH) { - if (q->type != APPEND && q->type != UPDATE) return(MR_STRING); - EXEC SQL SELECT value INTO :id FROM numvalues WHERE name = 'strings_id'; - id++; - EXEC SQL UPDATE numvalues SET value = :id WHERE name = 'strings_id'; - EXEC SQL INSERT INTO strings (string_id, string) VALUES (:id, :name); - cache_entry(name, "STRING", id); - } else if (status) return(status); - } else if (!strcmp(data_type, "none")) { - id = 0; - } else { - return(MR_TYPE); - } - - /* now set value in argv */ - *(int *)argv[vo->index] = id; - - return (MR_EXISTS); -} - - -/* Lock the table named by the validation object */ - -lock_table(vo) -struct valobj *vo; -{ - sprintf(stmt_buf,"UPDATE %s SET modtime='now' WHERE %s.%s = 0", - vo->table,vo->table,vo->idfield); - EXEC SQL EXECUTE IMMEDIATE :stmt_buf; - if (ingres_errno) return(mr_errcode); - if (sqlca.sqlerrd[2] != 1) - return(vo->error); - else - return(MR_EXISTS); -} - - -/* Check the database at startup time. For now this just resets the - * inprogress flags that the DCM uses. - */ - -sanity_check_database() -{ -} - - -/* Dynamic SQL support routines */ -MR_SQLDA_T *mr_alloc_SQLDA() -{ - MR_SQLDA_T *it; - short *null_indicators; - register int j; - - if((it=(MR_SQLDA_T *)malloc(sizeof(MR_SQLDA_T)))==NULL) { - com_err(whoami, MR_NO_MEM, "setting up SQLDA"); - exit(1); - } - - if((null_indicators=(short *)calloc(QMAXARGS,sizeof(short)))==NULL) { - com_err(whoami, MR_NO_MEM, "setting up SQLDA null indicators"); - exit(1); - } - - for(j=0; jsqlvar[j].sqldata=malloc(sizeof(short)+QMAXARGSIZE))==NULL) { - com_err(whoami, MR_NO_MEM, "setting up SQLDA variables"); - exit(1); - } - it->sqlvar[j].sqllen=QMAXARGSIZE; - it->sqlvar[j].sqlind=null_indicators+j; - null_indicators[j]=0; - } - it->sqln=QMAXARGS; - return it; -} - + EXEC SQL END DECLARE SECTION; -/* Use mr_check_SQLDA before OPEN CURSOR or EXECUTE */ -mr_check_SQLDA(da) - MR_SQLDA_T *da; -{ - if(da->sqld > da->sqln) { - com_err(whoami, MR_INTERNAL, - "Internal arg count error preparing for dynamic query"); - return(MR_INTERNAL); + for(p=machine; *p; p++) { + if(*p=='%' || *p=='_') break; + if(*p=='*') { + p++; + if(*p=='%') p++; + } + } + if(!*p) { + /* machine has no wildcards, so we can do it the fast way */ + EXEC SQL REPEATED SELECT mach_id INTO :id FROM machine + WHERE name=:machine; + if(ingres_errno) return(mr_errcode); + + sprintf(qual, "a.mach_id = %d AND m.mach_id = %d AND a.name LIKE '%s' ESCAPE '*'", id, id, alias); + return do_retrieve(q, qual, 0, action, actarg); } - return(MR_SUCCESS); + /* not the special case... do the normal query */ + build_qual(q->qual, q->argc, argv, qual); + return do_retrieve(q, qual, 0, action, actarg); } -mr_fix_nulls_in_SQLDA(da) - MR_SQLDA_T *da; -{ - register IISQLVAR *var; - register int j; - int *intp; - - for(j=0, var=da->sqlvar; jsqld; j++, var++) { - switch(var->sqltype) { - case -IISQ_CHA_TYPE: - if(*var->sqlind) - *var->sqldata='\0'; - break; - case -IISQ_INT_TYPE: - if(*var->sqlind) { - intp=(int *)var->sqldata; - *intp=0; - } - break; - } /** I believe that these two are the only types Moira encounters */ - } -} +/* END KLUDGE */