+++ /dev/null
-/*
- * $Source$
- * $Author$
- * $Header$
- *
- * Copyright (C) 1987 by the Massachusetts Institute of Technology
- * For copying and distribution information, please see the file
- * <mit-copyright.h>.
- *
- */
-
-#ifndef lint
-static char *rcsid_qsupport_dc = "$Header$";
-#endif lint
-
-#include <mit-copyright.h>
-#include "mr_server.h"
-#include "query.h"
-#include <ctype.h>
-#include <arpa/inet.h>
-EXEC SQL INCLUDE sqlca;
-#include "qrtn.h"
-
-extern char *whoami, *strsave();
-extern int dbms_errno, mr_errcode;
-
-EXEC SQL BEGIN DECLARE SECTION;
-extern char stmt_buf[];
-EXEC SQL END DECLARE SECTION;
-
-EXEC SQL WHENEVER SQLERROR DO dbmserr();
-
-
-int prefetch_value(struct query *q, char **argv, client *cl);
-int check_nfs(int mach_idx, char *name, char *access);
-
-/* 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] = "#<uid>"
- */
-
-int setup_ausr(q, argv, cl)
- struct query *q;
- char *argv[];
- client *cl;
-{
- int row, err;
- 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 ((err=set_next_object_id("unix_uid", USERS_TABLE, 1)))
- return(err);
- EXEC SQL SELECT value INTO :nuid FROM numvalues WHERE name = 'unix_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 SELECT status INTO :flag FROM users
- WHERE users_id = :id;
- if (flag != 0 && flag != 4)
- return(MR_IN_USE);
-
- EXEC SQL DELETE FROM quota WHERE entity_id = :id AND type='USER';
- EXEC SQL DELETE FROM krbmap WHERE users_id = :id;
- EXEC SQL 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 SELECT COUNT(label) INTO :cnt FROM filesys
- WHERE owner = :id;
- if (cnt > 0)
- return(MR_IN_USE);
- EXEC SQL SELECT COUNT(name) INTO :cnt FROM list
- WHERE acl_id = :id AND acl_type = 'USER';
- if (cnt > 0)
- return(MR_IN_USE);
- EXEC SQL SELECT COUNT(name) INTO :cnt FROM servers
- WHERE acl_id = :id AND acl_type = 'USER';
- if (cnt > 0)
- return(MR_IN_USE);
- EXEC SQL SELECT COUNT(acl_id) INTO :cnt FROM hostaccess
- WHERE acl_id = :id AND acl_type = 'USER';
- if (cnt > 0)
- return(MR_IN_USE);
- if (dbms_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;
- char type[9];
- EXEC SQL END DECLARE SECTION;
-
- id = *(int *)argv[0];
- EXEC SQL SELECT potype, pop_id INTO :type, :mid FROM users
- WHERE users_id = :id;
- if(sqlca.sqlerrd[2] = 0)
- return(MR_MACHINE);
- EXEC SQL 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 SELECT potype, pop_id INTO :type, :id FROM users
- WHERE users_id = :user;
- if (dbms_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 SELECT status INTO :flag FROM machine
- WHERE mach_id = :id;
- if (flag != 3)
- return(MR_IN_USE);
- EXEC SQL SELECT COUNT(login) INTO :cnt FROM users
- WHERE potype='POP' AND pop_id = :id;
- if (cnt > 0)
- return(MR_IN_USE);
- EXEC SQL SELECT COUNT(mach_id) INTO :cnt FROM serverhosts
- WHERE mach_id = :id;
- if (cnt > 0)
- return(MR_IN_USE);
- EXEC SQL SELECT COUNT(mach_id) INTO :cnt FROM nfsphys
- WHERE mach_id = :id;
- if (cnt > 0)
- return(MR_IN_USE);
- EXEC SQL SELECT COUNT(mach_id) INTO :cnt FROM hostaccess
- WHERE mach_id = :id;
- if (cnt > 0)
- return(MR_IN_USE);
- EXEC SQL SELECT COUNT(mach_id) INTO :cnt FROM printcap
- WHERE mach_id = :id;
- if (cnt > 0)
- return(MR_IN_USE);
- EXEC SQL SELECT COUNT(quotaserver) INTO :cnt FROM printcap
- WHERE quotaserver = :id;
- if (cnt > 0)
- return(MR_IN_USE);
- EXEC SQL SELECT COUNT(mach_id) INTO :cnt FROM palladium
- WHERE mach_id = :id;
- if (cnt > 0)
- return(MR_IN_USE);
-
- EXEC SQL DELETE FROM mcmap WHERE mach_id = :id;
- if (dbms_errno) return(mr_errcode);
- return(MR_SUCCESS);
-}
-
-
-/* setup_dsnt - verify that the subnet is no longer being referenced
- * and may safely be deleted.
- */
-
-int setup_dsnt(q, argv)
- struct query *q;
- char **argv;
-{
- EXEC SQL BEGIN DECLARE SECTION;
- int id, cnt = 0;
- EXEC SQL END DECLARE SECTION;
-
- id = *(int *)argv[0];
- EXEC SQL SELECT COUNT(mach_id) INTO :cnt FROM machine
- WHERE snet_id = :id;
- if (cnt > 0)
- return(MR_IN_USE);
- 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 SELECT COUNT(mach_id) INTO :cnt FROM mcmap
- WHERE clu_id = :id;
- if (cnt > 0)
- return(MR_IN_USE);
- EXEC SQL SELECT COUNT(clu_id) INTO :cnt FROM svc
- WHERE clu_id = :id;
- if (cnt > 0)
- return(MR_IN_USE);
- if (dbms_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;
- unsigned char *p;
- int idx, err;
-
- 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 ((err=set_next_object_id("gid", LIST_TABLE, 1)))
- return(err);
- EXEC SQL SELECT value INTO :ngid FROM numvalues
- WHERE name = 'gid';
- if (dbms_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 id;
- EXEC SQL BEGIN DECLARE SECTION;
- int cnt;
- EXEC SQL END DECLARE SECTION;
-
- id = *(int *)argv[0];
-
- EXEC SQL SELECT COUNT(member_id) INTO :cnt FROM imembers
- WHERE member_id = :id AND member_type='LIST';
- if(cnt>0) return MR_IN_USE;
-
- EXEC SQL SELECT COUNT(member_id) INTO :cnt FROM imembers
- WHERE member_id = :id AND member_type='LIST';
- if(cnt>0) return MR_IN_USE;
-
- EXEC SQL SELECT COUNT(member_id) INTO :cnt FROM imembers
- WHERE list_id = :id;
- if(cnt>0) return MR_IN_USE;
-
- EXEC SQL SELECT COUNT(label) INTO :cnt FROM filesys WHERE owners = :id;
- if(cnt>0) return MR_IN_USE;
-
- EXEC SQL SELECT COUNT(tag) INTO :cnt FROM capacls WHERE list_id = :id;
- if(cnt>0) return MR_IN_USE;
-
- EXEC SQL SELECT COUNT(name) INTO :cnt FROM list
- WHERE acl_id = :id AND acl_type='LIST' AND list_id != :id;
- if(cnt>0) return MR_IN_USE;
-
- EXEC SQL SELECT COUNT(name) INTO :cnt FROM servers
- WHERE acl_id = :id AND acl_type='LIST';
- if(cnt>0) return MR_IN_USE;
-
- EXEC SQL SELECT COUNT(entity_id) INTO :cnt FROM quota
- WHERE entity_id = :id AND type='GROUP';
- if(cnt>0) return MR_IN_USE;
-
- EXEC SQL SELECT COUNT(acl_id) INTO :cnt FROM hostaccess
- WHERE acl_id = :id AND acl_type='LIST';
- if(cnt>0) return MR_IN_USE;
-
- EXEC SQL SELECT COUNT(class) INTO :cnt FROM zephyr z
- WHERE z.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(cnt>0) return MR_IN_USE;
-
- 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, cnt;
- char *svrname;
- EXEC SQL END DECLARE SECTION;
-
- svrname=argv[0];
- EXEC SQL SELECT COUNT(service) INTO :cnt FROM serverhosts
- WHERE service = UPPER(:svrname);
- if(cnt>0) return MR_IN_USE;
-
- EXEC SQL SELECT inprogress INTO :ec FROM servers
- WHERE name=UPPER(:svrname);
- if(dbms_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=UPPER(:svrname) AND mach_id = :id;
- if(dbms_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] - rwaccess
- **
- ** Description:
- ** - for type = RVD:
- ** * allow anything
- ** - for type = NFS:
- ** * extract directory prefix from name
- ** * verify mach_id/dir in nfsphys
- ** * verify rwaccess 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;
-int _var_phys_id;
-EXEC SQL END DECLARE SECTION;
-
-int 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], *rwaccess;
- EXEC SQL END DECLARE SECTION;
-
- type = argv[1];
- mach_id = *(int *)argv[2];
- name = argv[3];
- rwaccess = 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 = :rwaccess;
- if (dbms_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, rwaccess));
-
- 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.
- */
-
-int 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;
- short int total_null;
- EXEC SQL END DECLARE SECTION;
-
- _var_phys_id = 0;
- 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 (dbms_errno) return(mr_errcode);
- if (ok == 0) return(MR_FILESYS_ACCESS);
-
- EXEC SQL SELECT type INTO :ftype FROM filesys
- WHERE filsys_id = :fid;
- if (dbms_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 (dbms_errno) return(mr_errcode);
- return(status);
- } else if (!strcmp(type, "AFS") && strcmp(strtrim(ftype), "AFS")) {
- total = 0;
- EXEC SQL 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 (dbms_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', SYSDATE, :who, :entity) ;
- if (dbms_errno) return(mr_errcode);
- }
- } else {
- EXEC SQL UPDATE quota SET phys_id = 0 WHERE filsys_id = :fid;
- if (dbms_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.
- */
-
-int check_nfs(mach_id, name, access)
-EXEC SQL BEGIN DECLARE SECTION;
- int mach_id;
-EXEC SQL END DECLARE SECTION;
- char *name, *access;
-{
- EXEC SQL BEGIN DECLARE SECTION;
- char dir[81];
- EXEC SQL END DECLARE SECTION;
- register int status;
- register char *cp1;
- register char *cp2;
-
- status = MR_NFS;
- EXEC SQL DECLARE csr101 CURSOR FOR
- SELECT nfsphys_id, dir FROM nfsphys
- WHERE mach_id = :mach_id
- ORDER BY 2 DESC;
- if (dbms_errno)
- return(mr_errcode);
- EXEC SQL OPEN csr101;
- if (dbms_errno)
- return(mr_errcode);
- while(1) {
- EXEC SQL FETCH csr101 INTO :_var_phys_id, :dir;
- if(sqlca.sqlcode != 0) break;
- cp1 = name;
- cp2 = strtrim(dir);
- while (*cp2) {
- if (*cp1++ != *cp2) break;
- cp2++;
- }
- if (*cp2 == 0) {
- status = MR_SUCCESS;
- break;
- }
- }
- EXEC SQL CLOSE csr101;
- if (dbms_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.
- */
-
-int 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 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 SELECT phys_id INTO :phys_id FROM filesys
- WHERE filsys_id = :id;
- EXEC SQL UPDATE nfsphys SET allocated = allocated - :total
- WHERE nfsphys_id = :phys_id;
-
- if(!none) {
- EXEC SQL DELETE FROM quota WHERE filsys_id = :id;
- }
- EXEC SQL DELETE FROM fsgroup WHERE filsys_id = :id;
- EXEC SQL DELETE FROM fsgroup WHERE group_id = :id;
- if (dbms_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.
- */
-
-int 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 SELECT count(fs.rowid) 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 (dbms_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
- */
-
-int 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 SELECT quota INTO :quota FROM quota
- WHERE type = :qtype AND entity_id = :id AND filsys_id = :fs;
- EXEC SQL SELECT phys_id INTO :physid FROM filesys
- WHERE filsys_id = :fs;
- EXEC SQL UPDATE nfsphys SET allocated = allocated - :quota
- WHERE nfsphys_id = :physid;
-
- if (dbms_errno) return(mr_errcode);
- return(MR_SUCCESS);
-}
-
-
-/* setup add_kerberos_user_mapping: add the string to the string
- * table if necessary.
- */
-
-int setup_akum(q, argv, cl)
- struct query *q;
- char **argv;
- client *cl;
-{
- EXEC SQL BEGIN DECLARE SECTION;
- int id;
- char *name;
- EXEC SQL END DECLARE SECTION;
-
- name = argv[1];
- if (name_to_id(name, STRINGS_TABLE, &id) != MR_SUCCESS) {
- if (q->type != APPEND) return(MR_STRING);
- id=add_string(name);
- cache_entry(name, STRINGS_TABLE, id);
- }
- if (dbms_errno) return(mr_errcode);
- *(int *)argv[1] = id;
- return(MR_SUCCESS);
-}
-
-
-/* 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.
- */
-
-int 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, "unix_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(dbms_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.
- */
-int prefetch_filesys(q, argv, cl)
- struct query *q;
- char **argv;
- client *cl;
-{
- EXEC SQL BEGIN DECLARE SECTION;
- int fid,phid;
- 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(dbms_errno) return(mr_errcode);
-
- argc=q->argc+q->vcnt;
- sprintf(argv[argc++],"%d",phid);
- sprintf(argv[argc],"%d",fid);
-
- return(MR_SUCCESS);
-}
-
-
-/* setup_ahst():
- */
-
-int setup_ahst(q, argv, cl)
- struct query *q;
- char **argv;
- client *cl;
-{
- EXEC SQL BEGIN DECLARE SECTION;
- char *name;
- int value, id, saddr, mask, high, low, cnt;
- EXEC SQL END DECLARE SECTION;
- int row;
- struct in_addr addr;
- extern int host_access_level, privileged;
-
- if (!strcmp(q->shortname, "uhst"))
- row = 1;
- else
- row = 0;
-
- /* sanity check name: must start with a letter, contain only
- * letters, numerals, and hyphen, and not end with a hyphen.
- */
- if (row == 0 || strcmp(argv[1], cl->args->mr_argv[1])) {
- char *p = argv[row];
-
- if (!isalpha(*p)) return(MR_BAD_CHAR);
- for (; *p; p++) {
- if ((!isalnum(*p) && *p != '-' && *p != '.') ||
- (*p == '-' && p[1] == '.'))
- return(MR_BAD_CHAR);
- }
- if (*(p-1) == '-') return(MR_BAD_CHAR);
- }
-
- /* sanity check host vendor: must start with a letter, contain only
- * letters, numerals, and hyphen, and end with an alphanumeric.
- */
- if (*argv[row+1] && (row == 0 || strcmp(argv[2], cl->args->mr_argv[2]))) {
- char *p = argv[row+1];
-
- if (!isalpha(*p)) return(MR_BAD_CHAR);
- for (; *p; p++) {
- if ((!isalnum(*p) && *p != '-' && *p != '.') ||
- (*p == '-' && p[1] == '.'))
- return(MR_BAD_CHAR);
- }
- if (!isalnum(*(p-1))) return(MR_BAD_CHAR);
- }
-
- /* sanity check host type: must start with a letter, contain only
- * letters, numerals, and hyphen, and end with an alphanumeric.
- */
- if (*argv[row+2] && (row == 0 || strcmp(argv[3], cl->args->mr_argv[3]))) {
- char *p = argv[row+2];
-
- if (!isalnum(*p)) return(MR_BAD_CHAR);
- for (; *p; p++) {
- if ((!isalnum(*p) && *p != '-' && *p != '.') ||
- (*p == '-' && p[1] == '.'))
- return(MR_BAD_CHAR);
- }
- if (!isalnum(*(p-1))) return(MR_BAD_CHAR);
- }
-
- /* sanity check host vendor: must start with a letter, contain only
- * letters, numerals, and hyphen, and end with an hyphen alphanumeric.
- */
- if (*argv[row+3] && (row == 0 || strcmp(argv[4], cl->args->mr_argv[4]))) {
- char *p = argv[row+3];
-
- if (!isalpha(*p)) return(MR_BAD_CHAR);
- for (; *p; p++) {
- if ((!isalnum(*p) && *p != '-' && *p != '.') ||
- (*p == '-' && p[1] == '.'))
- return(MR_BAD_CHAR);
- }
- if (!isalnum(*(p-1))) return(MR_BAD_CHAR);
- }
-
- /* check for duplicate name */
- name = argv[row];
- EXEC SQL SELECT count(mach_id) INTO :cnt FROM hostalias
- WHERE name = :name;
- if (dbms_errno) return(mr_errcode);
- if (cnt != 0) return(MR_EXISTS);
-
- /* check address */
- if (!strcmp(argv[9+row], "unassigned"))
- value = -1;
- else if (!strcmp(argv[9+row], "unique")) {
- if (*(int *)argv[8+row] == 0)
- value = -1;
- else
- value = -2;
- } else {
- value = ntohl(inet_addr(argv[9+row]));
- if (value == -1) return(MR_ADDRESS);
- }
- if (value == 0) return(MR_ADDRESS);
- if (value != -1) {
- /*
- * an address or unique was specified.
- */
- id = *(int *)argv[8+row];
- EXEC SQL SELECT saddr, mask, high, low INTO :saddr, :mask, :high, :low
- FROM subnet WHERE snet_id = :id;
- if (dbms_errno) return(mr_errcode);
- if (value != -2) {
- /*
- * someone specified an IP address for the host record
- */
- if ((value & mask) != saddr) return(MR_ADDRESS);
- /*
- * run the address argument through inet_addr(). This
- * has the effect that any out of bounds host addrs will
- * be converted to a valid host addr. We do this now
- * so that the uniqueness check works. We should also
- * link in an inet_addr() that returns an error for
- * this case.
- */
- addr.s_addr=inet_addr(argv[9+row]);
- name = inet_ntoa(addr);
- EXEC SQL SELECT count(mach_id) INTO :cnt FROM machine
- WHERE address = :name;
- if (dbms_errno) return(mr_errcode);
- if (cnt > 0) {
- /*
- * make IP address is unique. If this a modify request
- * (row == 1), then we expect one record to exist.
- */
- if (row == 0 || row == 1 && cnt > 1) return(MR_ADDRESS);
- if (row == 1 && cnt == 1) {
- EXEC SQL SELECT mach_id INTO :id FROM machine
- WHERE address = :name;
- if (id != *(int *)argv[0]) return(MR_ADDRESS);
- }
- }
- } else {
- /*
- * a "unique" address was specified. Walk through the
- * range specified in the network record, return
- * error if no room left.
- */
- for (id = low; id <= high; id++) {
- if (((id & 0xff) == 0) ||
- ((id & 0xff) == 255))
- continue;
- addr.s_addr = htonl(id);
- name = (char *)inet_ntoa(addr);
- EXEC SQL SELECT count(mach_id) INTO :cnt FROM machine
- WHERE address = :name;
- if (dbms_errno) return(mr_errcode);
- if (cnt == 0) break;
- }
- if (cnt != 0)
- return(MR_ADDRESS);
- else
- value = htonl(id);
- }
- /*
- * we have an address in value. Convert it to a string and store it.
- */
- addr.s_addr = htonl(value);
- strcpy(argv[9+row], inet_ntoa(addr));
- } else {
- strcpy(argv[9+row], "unassigned");
- }
-
- /* status checking */
- value = atoi(argv[7+row]);
- if (row == 0 && !(value == 1 || value == 0))
- return(MR_TYPE);
- if (row == 1) {
- id = *(int *)argv[0];
- EXEC SQL SELECT status INTO :cnt FROM machine WHERE mach_id = :id;
- if (dbms_errno) return(mr_errcode);
- if (value != cnt) {
- EXEC SQL UPDATE machine SET statuschange = SYSDATE
- WHERE mach_id = :id;
- }
- }
-
- if (row == 0 && !privileged) {
- /* subnet owner is adding a host */
- /* Non-query owner must set use to zero */
- if (atoi(argv[6]) != 0) return(MR_PERM);
- } else if (row == 1 && !privileged) {
- EXEC SQL BEGIN DECLARE SECTION;
- int i8, i12, i13, i7, i9, i14;
- char s6[33], s10[33], s11[9];
- EXEC SQL END DECLARE SECTION;
- /* Non-query owner is restricted in changes that can be made */
- id = *(int *)argv[0];
- EXEC SQL SELECT contact, status, address, owner_type, owner_id,
- acomment, use, snet_id, ocomment INTO :s6, :i8, :s10, :s11,
- :i12, :i13, :i7, :i9, :i14 FROM machine WHERE mach_id = :id;
- if (dbms_errno) return(mr_errcode);
- /* subnet owner cannot change use, comment, or network */
- if ((i7 != atoi(argv[7])) || (i14 != *(int *)argv[14]) ||
- (i9 != *(int *)argv[9]))
- return(MR_PERM);
- /* host owner cannot change contact, status, address, owner_type,
- * owner_id, acomment, or subnet */
- if (host_access_level == 2 &&
- (strcmp(argv[6], strtrim(s6)) || (i8 != atoi(argv[8])) ||
- strcmp(argv[10], strtrim(s10)) ||strcmp(argv[11], strtrim(s11)) ||
- (i12 != *(int *)argv[12]) || (i13 != *(int *)argv[13]) ||
- (i9 != *(int *)argv[9])))
- return(MR_PERM);
- }
-
- /*
- * If this is an update_host query, we're done.
- */
- if (row == 1)
- return(MR_SUCCESS);
-
- /*
- * For an add_host query, allocate and fill in a new machine id,
- * and then insert the creator id.
- */
- if ((mr_errcode = prefetch_value(q,argv,cl)) != MR_SUCCESS)
- return(mr_errcode);
-
- sprintf(argv[q->argc + q->vcnt + 1], "%d",cl->client_id);
- return(MR_SUCCESS);
-}
-
-
-/* setup_ahal():
- */
-
-int setup_ahal(q, argv, cl)
- struct query *q;
- char **argv;
- client *cl;
-{
- EXEC SQL BEGIN DECLARE SECTION;
- char *name;
- int cnt;
- EXEC SQL END DECLARE SECTION;
- char *p;
-
- p = name = argv[0];
- if (!isalpha(*p)) return(MR_BAD_CHAR);
- for (; *p; p++) {
- if ((!isalnum(*p) && *p != '-' && *p != '.') ||
- (*p == '-' && p[1] == '.'))
- return(MR_BAD_CHAR);
- }
- if (*(p-1) == '-') return(MR_BAD_CHAR);
-
- EXEC SQL SELECT count(mach_id) INTO :cnt FROM machine WHERE
- name = :name;
- if (dbms_errno) return(mr_errcode);
- if (cnt > 0) return(MR_EXISTS);
-
- return(MR_SUCCESS);
-}