X-Git-Url: http://andersk.mit.edu/gitweb/moira.git/blobdiff_plain/4a5ff25624107addf436f49e3fe48a3fdf54ed2a..refs/heads/LOCKING:/server/qsupport.dc diff --git a/server/qsupport.dc b/server/qsupport.dc index dc75c5c5..038e92a3 100644 --- a/server/qsupport.dc +++ b/server/qsupport.dc @@ -31,2157 +31,9 @@ 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); - if (!strncmp(q->name,"get_user_account",strlen("get_user_account"))) { - EXEC SQL SELECT users_id INTO :id FROM users u, strings str WHERE :qual; - } else { - EXEC SQL SELECT users_id INTO :id FROM users u 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, publicflg - 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); - } - - if (!strcmp(argv[0], "KERBEROS") || !strcmp(argv[0], "RKERBERO")) { - if (cl->client_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]); - } - - if((mr_errcode=prefetch_value(q,argv,cl))!=MR_SUCCESS) - return(mr_errcode); - - 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, cnt; - EXEC SQL END DECLARE SECTION; - - id = *(int *)argv[0]; - - /* For now, only allow users to be deleted if their status is 0 */ - EXEC SQL REPEATED SELECT status INTO :flag FROM users - WHERE users_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 COUNT(member_id) INTO :cnt FROM imembers - WHERE member_id = :id AND member_type = 'USER'; - if (cnt > 0) - return(MR_IN_USE); - EXEC SQL REPEATED SELECT COUNT(label) INTO :cnt FROM filesys - WHERE owner = :id; - if (cnt > 0) - return(MR_IN_USE); - EXEC SQL REPEATED SELECT COUNT(name) INTO :cnt FROM list - WHERE acl_id = :id AND acl_type = 'USER'; - if (cnt > 0) - return(MR_IN_USE); - EXEC SQL REPEATED SELECT COUNT(name) INTO :cnt FROM servers - WHERE acl_id = :id AND acl_type = 'USER'; - if (cnt > 0) - return(MR_IN_USE); - EXEC SQL REPEATED SELECT COUNT(acl_id) INTO :cnt FROM hostaccess - WHERE acl_id = :id AND acl_type = 'USER'; - if (cnt > 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, cnt; - EXEC SQL END DECLARE SECTION; - - id = *(int *)argv[0]; - EXEC SQL REPEATED SELECT COUNT(login) INTO :cnt FROM users - WHERE potype='POP' AND pop_id = :id; - if (cnt > 0) - return(MR_IN_USE); - EXEC SQL REPEATED SELECT COUNT(mach_id) INTO :cnt FROM serverhosts - WHERE mach_id = :id; - if (cnt > 0) - return(MR_IN_USE); - EXEC SQL REPEATED SELECT COUNT(mach_id) INTO :cnt FROM nfsphys - WHERE mach_id = :id; - if (cnt > 0) - return(MR_IN_USE); - EXEC SQL REPEATED SELECT COUNT(mach_id) INTO :cnt FROM hostaccess - WHERE mach_id = :id; - if (cnt > 0) - return(MR_IN_USE); - EXEC SQL REPEATED SELECT COUNT(mach_id) INTO :cnt FROM printcap - WHERE mach_id = :id; - if (cnt > 0) - return(MR_IN_USE); - EXEC SQL REPEATED SELECT COUNT(quotaserver) INTO :cnt FROM printcap - WHERE quotaserver = :id; - if (cnt > 0) - return(MR_IN_USE); - EXEC SQL REPEATED SELECT COUNT(mach_id) INTO :cnt FROM palladium - WHERE mach_id = :id; - if (cnt > 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, cnt; - EXEC SQL END DECLARE SECTION; - - id = *(int *)argv[0]; - EXEC SQL REPEATED SELECT COUNT(mach_id) INTO :cnt FROM mcmap - WHERE clu_id = :id; - if (cnt > 0) - return(MR_IN_USE); - EXEC SQL REPEATED SELECT COUNT(clu_id) INTO :cnt FROM svc - WHERE clu_id = :id; - if (cnt > 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. Also check that the list name does not contain uppercase - * characters, control characters, @, or :. - */ - -static int badlistchars[] = { - 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 - ^_ */ - 1, 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, 1, 0, 0, 0, 0, 1, /* 0 - ? */ - 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, 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, -}; - -int setup_alis(q, argv, cl) - struct query *q; - char *argv[]; - client *cl; -{ - EXEC SQL BEGIN DECLARE SECTION; - int ngid; - EXEC SQL END DECLARE SECTION; - char *malloc(); - unsigned char *p; - int idx; - - if (!strcmp(q->shortname, "alis")) - idx = 0; - else if (!strcmp(q->shortname, "ulis")) - idx = 1; - - for (p = (unsigned char *) argv[idx]; *p; p++) - if (badlistchars[*p]) - return(MR_BAD_CHAR); - - if (!strcmp(argv[6 + idx], UNIQUE_GID) || atoi(argv[6 + idx]) == -1) { - if (atoi(argv[5 + idx])) { - 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[6 + idx], "%d", ngid); - } else { - strcpy(argv[6 + idx], "-1"); - } - } - - if((mr_errcode=prefetch_value(q,argv,cl))!=MR_SUCCESS) - return(mr_errcode); - - return(MR_SUCCESS); -} - - -/* setup_dlis - verify that the list is no longer being referenced - * and may safely be deleted. - */ - -int setup_dlis(q, argv) - struct query *q; - char *argv[]; -{ - int flag, id, ec; - - id = *(int *)argv[0]; - sprintf(stmt_buf,"SELECT member_id FROM imembers WHERE member_id = %d AND member_type='LIST'",id); - if(ec=mr_select_any(stmt_buf)) { - if(ec==MR_EXISTS) return(MR_IN_USE); else return(ec); - } - - sprintf(stmt_buf,"SELECT member_id FROM imembers WHERE list_id = %d",id); - if(ec=mr_select_any(stmt_buf)) { - if(ec==MR_EXISTS) return(MR_IN_USE); else return(ec); - } - - sprintf(stmt_buf,"SELECT label FROM filesys WHERE owners = %d",id); - if(ec=mr_select_any(stmt_buf)) { - if(ec==MR_EXISTS) return(MR_IN_USE); else return(ec); - } - - sprintf(stmt_buf,"SELECT tag FROM capacls WHERE list_id = %d",id); - if(ec=mr_select_any(stmt_buf)) { - if(ec==MR_EXISTS) return(MR_IN_USE); else return(ec); - } - - sprintf(stmt_buf,"SELECT name FROM list WHERE acl_id = %d AND acl_type='LIST' AND list_id != %d",id,id); - if(ec=mr_select_any(stmt_buf)) { - if(ec==MR_EXISTS) return(MR_IN_USE); else return(ec); - } - - sprintf(stmt_buf,"SELECT name FROM servers WHERE acl_id = %d AND acl_type='LIST'",id); - if(ec=mr_select_any(stmt_buf)) { - if(ec==MR_EXISTS) return(MR_IN_USE); else return(ec); - } - - sprintf(stmt_buf,"SELECT entity_id FROM quota WHERE entity_id = %d AND type='GROUP'",id); - if(ec=mr_select_any(stmt_buf)) { - if(ec==MR_EXISTS) return(MR_IN_USE); else return(ec); - } - - sprintf(stmt_buf,"SELECT acl_id FROM hostaccess WHERE acl_id = %d AND acl_type='LIST'",id); - if(ec=mr_select_any(stmt_buf)) { - if(ec==MR_EXISTS) return(MR_IN_USE); else return(ec); - } - - sprintf(stmt_buf,"SELECT class FROM zephyr z \ -WHERE z.xmt_type = 'LIST' AND z.xmt_id = %d \ -OR z.sub_type = 'LIST' AND z.sub_id = %d \ -OR z.iws_type = 'LIST' AND z.iws_id = %d \ -OR z.iui_type = 'LIST' AND z.iui_id = %d",id,id,id,id); - if(ec=mr_select_any(stmt_buf)) { - if(ec==MR_EXISTS) return(MR_IN_USE); else return(ec); - } - - 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; - int ec; - char *svrname; - EXEC SQL END DECLARE SECTION; - - sprintf(stmt_buf,"SELECT service FROM serverhosts WHERE service = UPPERCASE('%s')",argv[0]); - if(ec=mr_select_any(stmt_buf)) { - if(ec==MR_EXISTS) - return(MR_IN_USE); - else - return(ec); - } - - svrname=argv[0]; - EXEC SQL SELECT inprogress INTO :ec FROM servers - WHERE name=UPPERCASE(:svrname); - if(ingres_errno) - return(mr_errcode); - if(ec) - return(MR_IN_USE); - - 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, ec; - char *svrname; - EXEC SQL END DECLARE SECTION; - - svrname=argv[0]; - id = *(int *)argv[1]; - - EXEC SQL SELECT inprogress INTO :ec FROM serverhosts - WHERE service=UPPERCASE(:svrname) AND mach_id = :id; - if(ingres_errno) - return(mr_errcode); - if(ec) - return(MR_IN_USE); - - - 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, cl) - struct query *q; - char *argv[]; - client *cl; -{ - 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 COUNT(trans) INTO :ok FROM alias - WHERE name = :ftype AND type = 'TYPE' and trans = :access; - if (ingres_errno) return(mr_errcode); - if (ok == 0) return(MR_FILESYS_ACCESS); - - if((mr_errcode=prefetch_value(q,argv,cl))!=MR_SUCCESS) - return(mr_errcode); - - if (!strcmp(type, "NFS")) - return (check_nfs(mach_id, name, access)); - - 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, ok; - char *entity, ftype[32], *access; - int var_phys_id = 0; - short int total_null; - 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 COUNT(trans) INTO :ok FROM alias - WHERE name = :ftype AND type='TYPE' AND trans = :access; - if (ingres_errno) return(mr_errcode); - if (ok == 0) return(MR_FILESYS_ACCESS); - - EXEC SQL SELECT type INTO :ftype FROM filesys - WHERE filsys_id = :fid; - strtrim(ftype); - if (ingres_errno) return(mr_errcode); - - 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") && strcmp(ftype, "AFS")) { - total = 0; - EXEC SQL REPEATED DELETE FROM quota - WHERE type = 'ANY' AND filsys_id = :fid; - EXEC SQL SELECT SUM (quota) INTO :total:total_null FROM quota - WHERE filsys_id = :fid AND phys_id != 0; - if (ingres_errno) return(mr_errcode); - if (!total_null && (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, phys_id; - short int none; - EXEC SQL END DECLARE SECTION; - - id = *(int *)argv[0]; - EXEC SQL REPEATED SELECT SUM (quota) INTO :total:none FROM quota - WHERE filsys_id = :id; - - if(none) total=0; - - /** What if there are multiple phys_id's per f/s? (bad data) **/ - EXEC SQL REPEATED SELECT phys_id INTO :phys_id FROM filesys - WHERE filsys_id = :id; - EXEC SQL REPEATED UPDATE nfsphys SET allocated = allocated - :total - WHERE nfsphys_id = :phys_id; - - if(!none) { - 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, cnt; - char *dir; - EXEC SQL END DECLARE SECTION; - - id = *(int *)argv[0]; - dir = argv[1]; - EXEC SQL REPEATED SELECT fs.tid INTO :cnt 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 (cnt > 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, physid; - 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 SELECT phys_id INTO :physid FROM filesys - WHERE filsys_id = :fs; - EXEC SQL REPEATED UPDATE nfsphys SET allocated = allocated - :quota - WHERE nfsphys_id = :physid; - - if (ingres_errno) return(mr_errcode); - return(MR_SUCCESS); -} - - -/* setup_sshi: don't exclusive lock the machine table during - * set_server_host_internal. - */ -/** Not allowed under (INGRES) SQL **/ -setup_sshi(q, argv, cl) - struct query *q; - char **argv; - client *cl; -{ -#if 0 -#ifsql INGRES - EXEC SQL set lockmode session where readlock = system; -#endsql -#endif - return(MR_SUCCESS); -} - - -/* 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 = LEFT('%s',SIZE(%s.name))",table,who,entity,table,name,table); - 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; - 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 = UPPERCASE(LEFT('%s',SIZE(%s.name)))",table,who,entity,table,name,table); - 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 = LEFT(:label,SIZE(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 = LEFT(:class,SIZE(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 - unsigned char sigbuf[256]; - char *kname; - SigInfo si; - EXEC SQL BEGIN DECLARE SECTION; - int timestamp, who; - char *login; - varchar struct { short data_size; char data_buf[257];} rsig; - EXEC SQL END DECLARE SECTION; -#endif /* GDSS */ - int id, status; - - i = q->vcnt - 2; - while (sq_get_data(sq, &argv)) { -#ifdef DEBUG - com_err(whoami, 0, "argv[SIGNATURE] = \"%s\"", argv[U_SIGNATURE]); -#endif /* DEBUG */ - 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 && strlen(argv[U_SIGNATURE])) { - login = argv[U_NAME]; - EXEC SQL REPEATED SELECT signature, sigdate, sigwho - INTO :rsig, :timestamp, :who FROM users - WHERE login = :login; - /** What about (INGRES) error handling? **/ - kname = malloc(1); - status = id_to_name(who, "STRING", &kname); - si.timestamp = timestamp; - si.SigInfoVersion = 0; /* XXXXX this isn't used */ - kname_parse(si.pname, si.pinst, si.prealm, kname); - free(kname); - rsig.data_buf[rsig.data_size] = 0; - si.rawsig = (unsigned char *)strsave(rsig.data_buf); - if (log_flags & LOG_GDSS) - com_err(whoami, 0, "rawsig length = %d, sig=\"%s\"", strlen(si.rawsig), si.rawsig); - GDSS_Recompose(&si, sigbuf); - free(si.rawsig); - free(argv[U_SIGNATURE]); - argv[U_SIGNATURE] = strsave(sigbuf); - if (log_flags & LOG_GDSS) - com_err(whoami, 0, "generated signature length %d", strlen(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, 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]; - int sigwho, timestamp; - 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 - if (q->vcnt == U_END && *argv[U_SIGNATURE]) { - /* unquote ' chars in signature */ - for (dst = src = argv[U_SIGNATURE]; *src; ) { - if (*src == '\'') - src++; - *dst++ = *src++; - } - *dst = 0; - sprintf(databuf, "%s:%s", argv[U_NAME], argv[U_MITID]); - /* skip bytes for timestamp & kname */ - si.rawsig = (unsigned char *) rawsig; - status = GDSS_Verify(databuf, strlen(databuf), argv[U_SIGNATURE], &si); - if (strlen(rawsig) > mr_sig_length) { - com_err(whoami, 0, "GDSS signature would be truncated."); /** untested **/ - return(MR_INTERNAL); - } - 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); - timestamp = si.timestamp; - } else { - if (log_flags & LOG_GDSS) - hex_dump(argv[U_SIGNATURE]); - return(gdss2et(status)); - } - } else { - rawsig[0] = 0; - sigwho = 0; - timestamp = 0; - } -#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, affiliation = type, - signature = :rawsig, sigdate = :timestamp, sigwho = :sigwho, - 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, affiliation = type, - fmodtime='now', fmodby = :who, fmodwith = :entity, - potype='NONE', pmodtime='now', pmodby = :who, pmodwith = :entity - WHERE login = :login; -#endif /* GDSS */ - - return(MR_SUCCESS); -} - - -/** - ** followup_uusr - do signature, set_user_modtime - ** - ** Inputs: - ** argv[0] - login (add_user) - ** argv[U_SIGNATURE] - sig - ** - **/ - -followup_uuac(q, argv, cl) - struct query *q; - char *argv[]; - client *cl; -{ - EXEC SQL BEGIN DECLARE SECTION; - int who, status, id; - char *entity, *name, *src, *dst; - EXEC SQL END DECLARE SECTION; -#ifdef GDSS - char databuf[32], *kname_unparse(); - EXEC SQL BEGIN DECLARE SECTION; - char rawsig[128]; - char *login; - int sigwho, timestamp; - EXEC SQL END DECLARE SECTION; - SigInfo si; -#endif /* GDSS */ - - id = *(int *)argv[0]; - who = cl->client_id; - entity = cl->entity; - -#ifdef GDSS - if (q->vcnt == U_MODTIME && *argv[U_SIGNATURE + 1]) { - /* unquote ' chars in signature */ - for (dst = src = argv[U_SIGNATURE+1]; *src; ) { - if (*src == '\'') - src++; - *dst++ = *src++; - } - *dst = 0; - login = malloc(1); - status = id_to_name(id, "USER", &login); - sprintf(databuf, "%s:%s", login, argv[U_MITID+1]); - free(login); - /* skip bytes for timestamp & kname */ - si.rawsig = (unsigned char *) rawsig; -#ifdef DEBUG - com_err(whoami, 0, "verifying sig"); -#endif /* DEBUG */ - status = GDSS_Verify(databuf, strlen(databuf), argv[U_SIGNATURE+1], &si); -#ifdef DEBUG - com_err(whoami, 0, "verified"); -#endif /* DEBUG */ - if (strlen(rawsig) > mr_sig_length) { - com_err(whoami, 0, "GDSS signature would be truncated."); /** untested **/ - return(MR_INTERNAL); - } - 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); - timestamp = si.timestamp; - } else { - if (log_flags & LOG_GDSS) - hex_dump(argv[U_SIGNATURE+1]); - return(gdss2et(status)); - } - } else { - rawsig[0] = 0; - sigwho = 0; - timestamp = 0; - } -#endif /* GDSS */ - - /* create finger entry, pobox & set modtime on user */ - -#ifdef GDSS - EXEC SQL REPEATED UPDATE users SET modtime='now', modby = :who, modwith = :entity, - signature = :rawsig, sigdate = :timestamp, sigwho = :sigwho - WHERE users_id = :id; -#else /* GDSS */ - EXEC SQL REPEATED UPDATE users SET modtime='now', modby = :who, modwith = :entity - WHERE users_id = :id; -#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, i; - - /* 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 */ - for (i = 0; i < q->vcnt; i++) - free(argv[i]); - 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, physid; - char *entity, *qtype, *table_name; - EXEC SQL END DECLARE SECTION; - char incr_qual[60]; - char *incr_argv[2]; - int status; - - table_name=q->rtable; - fs = *(int *)argv[0]; - EXEC SQL REPEATED SELECT phys_id INTO :physid FROM filesys - WHERE filsys_id = :fs; - if(ingres_errno) - return(mr_errcode); - - if (!strcmp(q->shortname, "aqot") || !strcmp(q->shortname, "uqot")) { - qtype = argv[1]; - id = *(int *)argv[2]; - quota = atoi(argv[3]); - sprintf(incr_qual,"q.filsys_id = %d",fs); - } else { - qtype = "USER"; - id = *(int *)argv[1]; - quota = atoi(argv[2]); - sprintf(incr_qual,"q.filsys_id=%d AND q.type='%s' AND q.entity_id=%d", - fs,qtype,id); - } - - /* quota case of incremental_{before|after} only looks at slot 1 */ - incr_argv[1]=qtype; - - /* Follows one of many possible gross hacks to fix these particular - * conflicts between what is possible in the query table and what - * is possible in SQL. - */ - if(q->type==APPEND) { - incremental_clear_before(); - EXEC SQL INSERT INTO quota - (filsys_id, type, entity_id, quota, phys_id) - VALUES (:fs, :qtype, :id, :quota, :physid); - incremental_after(table_name, incr_qual, incr_argv); - } else { - incremental_before(table_name, incr_qual, incr_argv); - EXEC SQL UPDATE quota SET quota = :quota - WHERE filsys_id = :fs AND type = :qtype AND entity_id = :id; - status = mr_errcode; - incremental_after(table_name, incr_qual, incr_argv); - } - - if (ingres_errno) - return(mr_errcode); - flush_name(argv[0], q->rtable); - if(q->type==APPEND) { - EXEC SQL UPDATE tblstats SET appends = appends + 1, modtime = 'now' - WHERE table_name = :table_name; - } else { - EXEC SQL UPDATE tblstats SET updates = updates + 1, modtime = 'now' - WHERE table_name = :table_name; - } - - /* Proceed with original followup */ - 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 = :physid; - if (ingres_errno) return(mr_errcode); - return(MR_SUCCESS); -} - - -/* Necessitated by the requirement of a correlation name by the incremental - * routines, since query table deletes don't provide one. - */ -followup_dqot(q,argv,cl) - struct query *q; - char **argv; - struct client *cl; -{ - char *qtype; - int id, fs; - char *incr_argv[2]; - EXEC SQL BEGIN DECLARE SECTION; - char incr_qual[80]; - char *tblname; - EXEC SQL END DECLARE SECTION; - - fs = *(int *)argv[0]; - if (!strcmp(q->shortname, "dqot")) { - qtype = argv[1]; - id = *(int *)argv[2]; - } else { - qtype = "USER"; - id = *(int *)argv[1]; - } - sprintf(incr_qual,"q.filsys_id=%d AND q.type='%s' AND q.entity_id=%d", - fs,qtype,id); - - /* quota case of incremental_{before|after} only looks at slot 1 */ - incr_argv[1]=qtype; - - incremental_before(q->rtable, incr_qual, incr_argv); - EXEC SQL DELETE FROM quota q WHERE :incr_qual; - incremental_clear_after(); - - if (ingres_errno) - return(mr_errcode); - flush_name(argv[0], q->rtable); - - tblname = q->rtable; - EXEC SQL UPDATE tblstats SET deletes = deletes + 1, modtime = 'now' - WHERE table_name = :tblname; - 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. @@ -2225,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 @@ -2261,7 +107,7 @@ get_list_info(q, aargv, cl, action, actarg) register int (*action)(); int actarg; { - char *argv[13], *malloc(), *realloc(); + 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]; @@ -2281,7 +127,11 @@ get_list_info(q, aargv, cl, action, actarg) 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; @@ -2401,7 +251,11 @@ 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; @@ -2424,7 +278,11 @@ int add_member_to_list(q, argv, cl) 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; @@ -2544,7 +402,11 @@ int delete_member_from_list(q, argv, cl) 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; @@ -2566,7 +428,11 @@ int delete_member_from_list(q, argv, cl) 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; @@ -2676,7 +542,11 @@ int get_ace_use(q, argv, cl, action, actarg) 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; @@ -2694,7 +564,11 @@ int get_ace_use(q, argv, cl, action, actarg) 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; @@ -2714,7 +588,11 @@ int get_ace_use(q, argv, cl, action, actarg) 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; @@ -2762,7 +640,11 @@ get_ace_internal(atype, aid, action, actarg) 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; @@ -2775,7 +657,11 @@ get_ace_internal(atype, aid, action, actarg) 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 ; if(sqlca.sqlcode != 0) break; @@ -2788,7 +674,11 @@ get_ace_internal(atype, aid, action, actarg) 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; @@ -2802,7 +692,11 @@ get_ace_internal(atype, aid, action, actarg) 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; if(sqlca.sqlcode != 0) break; @@ -2815,7 +709,11 @@ get_ace_internal(atype, aid, action, actarg) 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; @@ -2829,7 +727,11 @@ get_ace_internal(atype, aid, action, actarg) 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; @@ -2845,7 +747,11 @@ get_ace_internal(atype, aid, action, actarg) 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; if(sqlca.sqlcode != 0) break; @@ -2914,7 +820,11 @@ int get_lists_of_member(q, argv, cl, action, actarg) 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 INTO :name, :active, :public, :hidden, :maillist, :grouplist; @@ -2930,7 +840,11 @@ int get_lists_of_member(q, argv, cl, action, actarg) 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 INTO :name, :active, :public, :hidden, :maillist, :grouplist; @@ -3030,7 +944,11 @@ gmol_internal(q, argv, cl, action, actarg, flag) EXEC SQL DECLARE csr118 CURSOR FOR SELECT member_type, member_id FROM imembers 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; if (sqlca.sqlcode != 0) break; @@ -3082,7 +1000,11 @@ gmol_internal(q, argv, cl, action, actarg, flag) 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; @@ -3097,7 +1019,11 @@ gmol_internal(q, argv, cl, action, actarg, flag) 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; if(sqlca.sqlcode != 0) break; @@ -3112,7 +1038,11 @@ gmol_internal(q, argv, cl, action, actarg, flag) 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; if(sqlca.sqlcode != 0) break; @@ -3128,7 +1058,11 @@ gmol_internal(q, argv, cl, action, actarg, flag) 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; if(sqlca.sqlcode != 0) break; @@ -3282,7 +1216,11 @@ int qualified_get_serverhost(q, argv, cl, action, actarg) 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; @@ -3357,7 +1295,11 @@ register_user(q, argv, cl) 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; @@ -3506,7 +1448,7 @@ register_user(q, argv, cl) ** **/ -static int set_pop_usage(id, cnt) +int set_pop_usage(id, cnt) EXEC SQL BEGIN DECLARE SECTION; int id; int cnt; @@ -3519,756 +1461,42 @@ static int set_pop_usage(id, cnt) return(MR_SUCCESS); } -int _sdl_followup(q, argv, cl) - struct query *q; - char **argv; - client *cl; -{ - int i; - i = atoi(argv[0]); - log_flags = i; - if (i & LOG_SQL) { - EXEC SQL set printqry; - } else { - EXEC SQL set noprintqry; - } - 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); - - if (log_flags & LOG_VALID) - /* tell the logfile what we're doing */ - com_err(whoami, 0, "validating row: %s", qual); - - /* look for the record */ - sprintf(stmt_buf,"SELECT COUNT (*) FROM %s WHERE %s",q->rtable,qual); - EXEC SQL PREPARE stmt INTO :SQLDA USING NAMES FROM :stmt_buf; - if(sqlca.sqlcode) - return(MR_INTERNAL); - 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->sqlvar[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; - - case V_WILD: - status = convert_wildcards(argv[vo->index]); - break; - - case V_UPWILD: - status = convert_wildcards_uppercase(argv[vo->index]); - 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 = 'strings_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")) { - sprintf(stmt_buf,"SELECT %s FROM %s WHERE %s = %s",idfield,tbl,namefield,name); - } else { - sprintf(stmt_buf,"SELECT %s FROM %s WHERE %s = '%s'",idfield,tbl,namefield,name); - } - EXEC SQL PREPARE stmt INTO :SQLDA USING NAMES FROM :stmt_buf; - if(sqlca.sqlcode) - return(MR_INTERNAL); - 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 (ingres_errno) - return(mr_errcode); - - if (rowcount != 1) return(vo->error); - bcopy(SQLDA->sqlvar[0].sqldata,argv[vo->index],sizeof(int)); - 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); - } - sprintf(stmt_buf,"SELECT DISTINCT COUNT(*) FROM %s WHERE %s.%s = '%s'", - tbl,tbl,namefield,name); - EXEC SQL PREPARE stmt INTO :SQLDA USING NAMES FROM :stmt_buf; - if(sqlca.sqlcode) - return(MR_INTERNAL); - 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]; - 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); - sprintf(stmt_buf,"SELECT %s FROM %s WHERE %s = LEFT('%s',SIZE(%s))", - namefield,tbl,namefield,name,namefield); - EXEC SQL PREPARE stmt INTO :SQLDA USING NAMES FROM :stmt_buf; - if(sqlca.sqlcode) - return(MR_INTERNAL); - 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 *val; - int cnt; - EXEC SQL END DECLARE SECTION; - register char *c; - - typename = vo->table; - c = val = argv[vo->index]; - while (*c) { - if (illegalchars[*c++]) - return(MR_BAD_CHAR); - } - - /* uppercase type fields */ - for (c = val; *c; c++) if (islower(*c)) *c = toupper(*c); - - EXEC SQL SELECT COUNT(trans) INTO :cnt FROM alias - WHERE name = :typename AND type='TYPE' AND trans = :val; - if (ingres_errno) return(mr_errcode); - return (cnt ? 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; -{ - EXEC SQL BEGIN DECLARE SECTION; - char *name; - char *field_type; - char data_type[129]; - 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 */ - if (index(name, '@')) - return(MR_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; -} - - -/* Use this after FETCH USING DESCRIPTOR one or more - * result columns may contain NULLs. This routine is - * not currently needed, since db/schema creates all - * columns with a NOT NULL WITH DEFAULT clause. - * - * This is currently dead flesh, since no Moira columns - * allow null values; all use default values. - */ -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; - } - } -} - -/* prefetch_value(): - * This routine fetches an appropriate value from the numvalues table. - * It is a little hack to get around the fact that SQL doesn't let you - * do something like INSERT INTO table (foo) VALUES (other_table.bar). - * - * It is called from the query table as (*v->pre_rtn)(q,Argv,cl) or - * from within a setup_...() routine with the appropriate arguments. - * - * Correct functioning of this routine may depend on the assumption - * that this query is an APPEND. - */ - -prefetch_value(q,argv,cl) - struct query *q; - char **argv; - client *cl; -{ - EXEC SQL BEGIN DECLARE SECTION; - char *name = q->validate->object_id; - int value; - EXEC SQL END DECLARE SECTION; - int status, limit, argc; - - /* set next object id, limiting it if necessary */ - if(!strcmp(name, "uid") || !strcmp(name, "gid")) - limit = 1; /* So far as I know, this isn't needed. Just CMA. */ - else - limit = 0; - if((status = set_next_object_id(name, q->rtable, limit)) != MR_SUCCESS) - return(status); - - /* fetch object id */ - EXEC SQL SELECT value INTO :value FROM numvalues WHERE name=:name; - if(ingres_errno) return(mr_errcode); - if(sqlca.sqlerrd[2] != 1) return(MR_INTERNAL); - - argc = q->argc + q->vcnt; /* end of Argv for APPENDs */ - sprintf(argv[argc],"%d",value); /** Could save this step by changing tlist from %s to %d **/ - - return(MR_SUCCESS); -} - -/* prefetch_filesys(): - * Fetches the phys_id from filesys based on the filsys_id in argv[0]. - * Appends the filsys_id and the phys_id to the argv so they can be - * referenced in an INSERT into a table other than filesys. Also - * see comments at prefetch_value(). - * - * Assumes the existence of a row where filsys_id = argv[0], since a - * filesys label has already been resolved to a filsys_id. - */ -prefetch_filesys(q,argv,cl) - struct query *q; - char **argv; client *cl; + int (*action)(); + int actarg; { EXEC SQL BEGIN DECLARE SECTION; - int fid,phid; + char *alias=argv[0], *machine=argv[1], qual[BUFSIZ], *p; + int id; EXEC SQL END DECLARE SECTION; - int argc; - - fid = *(int *)argv[0]; - EXEC SQL SELECT phys_id INTO :phid FROM filesys WHERE filsys_id = :fid; - if(ingres_errno) return(mr_errcode); - - argc=q->argc+q->vcnt; - sprintf(argv[argc++],"%d",phid); - sprintf(argv[argc],"%d",fid); - - return(MR_SUCCESS); -} - -/* Convert normal Unix-style wildcards to SQL voodoo */ -convert_wildcards(arg) - char *arg; -{ - static char buffer[QMAXARGSIZE]; - register char *s, *d; - for(d=buffer,s=arg;*s;s++) { - switch(*s) { - case '*': *d++='%'; *d++='%'; break; - case '?': *d++='_'; break; - case '_': - case '[': - case ']': *d++='*'; *d++ = *s; break; - case '%': *d++='*'; *d++='%'; *d++='%'; break; - default: *d++ = *s; break; - } + for(p=machine; *p; p++) { + if(*p=='%' || *p=='_') break; + if(*p=='*') { + p++; + if(*p=='%') p++; + } } - *d='\0'; - - /* Copy back into argv */ - strcpy(arg,buffer); - - return(MR_EXISTS); -} - -/* This version includes uppercase conversion, for things like gmac. - * This is necessary because "LIKE" doesn't work with "uppercase()". - * Including it in a wildcard routine saves making two passes over - * the argument string. - */ -convert_wildcards_uppercase(arg) - char *arg; -{ - static char buffer[QMAXARGSIZE]; - register char *s, *d; - - for(d=buffer,s=arg;*s;s++) { - switch(*s) { - case '*': *d++='%'; *d++='%'; break; - case '?': *d++='_'; break; - case '_': - case '[': - case ']': *d++='*'; *d++ = *s; break; - case '%': *d++='*'; *d++='%'; *d++='%'; break; - default: *d++=toupper(*s); break; /* This is the only diff. */ - } + 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); } - *d='\0'; - - /* Copy back into argv */ - strcpy(arg,buffer); - - return(MR_EXISTS); -} - - -/* Looks like it's time to build an abstraction barrier, Yogi */ -mr_select_any(stmt) - EXEC SQL BEGIN DECLARE SECTION; - char *stmt; - EXEC SQL END DECLARE SECTION; -{ - int result=0; - EXEC SQL PREPARE stmt FROM :stmt; - EXEC SQL DESCRIBE stmt INTO :SQLDA; - if(SQLDA->sqld==0) /* Not a SELECT */ - return(MR_INTERNAL); - EXEC SQL DECLARE csr CURSOR FOR stmt; - EXEC SQL OPEN csr; - EXEC SQL FETCH csr USING DESCRIPTOR :SQLDA; - if(sqlca.sqlcode==0) - result=MR_EXISTS; - else if((sqlca.sqlcode<0) && mr_errcode) - result=mr_errcode; - else - result=0; - EXEC SQL CLOSE csr; - return(result); -} - - - -static hex_dump(p) -unsigned char *p; -{ - char buf[BUFSIZ]; - int i; - - fprintf(stderr, "Size: %d\n", strlen(p)); - while (strlen(p) >= 8) { - fprintf(stderr, "%02x %02x %02x %02x %02x %02x %02x %02x\n", - p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7]); - p += 8; - } - switch (strlen(p)) { - case 7: - fprintf(stderr, "%02x %02x %02x %02x %02x %02x %02x\n", - p[0], p[1], p[2], p[3], p[4], p[5], p[6]); - break; - case 6: - fprintf(stderr, "%02x %02x %02x %02x %02x %02x\n", - p[0], p[1], p[2], p[3], p[4], p[5]); - break; - case 5: - fprintf(stderr, "%02x %02x %02x %02x %02x\n", - p[0], p[1], p[2], p[3], p[4]); - break; - case 4: - fprintf(stderr, "%02x %02x %02x %02x\n", - p[0], p[1], p[2], p[3]); - break; - case 3: - fprintf(stderr, "%02x %02x %02x\n", - p[0], p[1], p[2]); - break; - case 2: - fprintf(stderr, "%02x %02x\n", - p[0], p[1]); - break; - case 1: - fprintf(stderr, "%02x\n", - p[0]); - break; - default: - return; - } + /* not the special case... do the normal query */ + build_qual(q->qual, q->argc, argv, qual); + return do_retrieve(q, qual, 0, action, actarg); } -/* eof:qsupport.dc */ +/* END KLUDGE */