-/*
- * $Source$
- * $Author$
- * $Header$
+/* $Id$
*
- * Copyright (C) 1987 by the Massachusetts Institute of Technology
- * For copying and distribution information, please see the file
- * <mit-copyright.h>.
+ * Query setup routines
*
+ * Copyright (C) 1987-1998 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 "qrtn.h"
+
#include <arpa/inet.h>
+#include <netinet/in.h>
+
+#include <ctype.h>
+#include <stdlib.h>
+#include <string.h>
+
EXEC SQL INCLUDE sqlca;
-#include "qrtn.h"
-extern char *whoami, *strsave();
+RCSID("$Header$");
+
+extern char *whoami;
extern int dbms_errno, mr_errcode;
EXEC SQL BEGIN DECLARE SECTION;
EXEC SQL WHENEVER SQLERROR DO dbmserr();
-
+int hostname_check(char *name);
+int hostinfo_check(char *name, int num);
int prefetch_value(struct query *q, char **argv, client *cl);
int check_nfs(int mach_idx, char *name, char *access);
+int check_mailman_listname(char *name, const char *suffix);
/* Setup Routines */
* - if argv[0] == UNIQUE_LOGIN then set argv[0] = "#<uid>"
*/
-int setup_ausr(q, argv, cl)
- struct query *q;
- char *argv[];
- client *cl;
+int setup_ausr(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);
+ 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 (q->version > 2)
+ {
+ if (strlen(argv[row + 3]) + strlen(argv[row + 4]) +
+ strlen(argv[row + 5]) + 2 > USERS_FULLNAME_SIZE)
+ return MR_ARG_TOO_LONG;
+ }
+ else
+ {
+ if (strlen(argv[row + 2]) + strlen(argv[row + 3]) +
+ strlen(argv[row + 4]) + 2 > USERS_FULLNAME_SIZE)
+ return MR_ARG_TOO_LONG;
}
- if (!strcmp(argv[0], UNIQUE_LOGIN) || atoi(argv[row]) == -1) {
- sprintf(argv[0], "#%s", argv[row]);
+ if (q->version > 10)
+ {
+ /* For both winhomedir and winprofiledir, we allow values of the
+ * following forms:
+ *
+ * [AFS] - Magic token for AFS home directory.
+ * [LOCAL] - Magic token for AD default local values, i.e. C:\<mumble>
+ * [DFS] - Magic token for DFS home directory
+ * UNC pathname - \\<something>
+ * local pathname - <drive letter>:<something>
+ */
+
+ if ((strcasecmp(argv[row + 12], "[AFS]")) &&
+ (strcasecmp(argv[row + 12], "[LOCAL]")) &&
+ (strcasecmp(argv[row + 12], "[DFS]")) &&
+ (!(argv[row + 12][0] == '\\' && argv[row + 12][1] == '\\')) &&
+ (!(isalpha(*argv[row + 12]) && (argv[row + 12][1] == ':'))))
+ return MR_BAD_CHAR;
+
+ if ((strcasecmp(argv[row + 13], "[AFS]")) &&
+ (strcasecmp(argv[row + 13], "[LOCAL]")) &&
+ (strcasecmp(argv[row + 13], "[DFS]")) &&
+ (!(argv[row + 13][0] == '\\' && argv[row + 13][1] == '\\')) &&
+ (!(isalpha(*argv[row + 13]) && (argv[row + 13][1] == ':'))))
+ return MR_BAD_CHAR;
}
- if((mr_errcode=prefetch_value(q,argv,cl))!=MR_SUCCESS)
- return(mr_errcode);
+ 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);
+ }
- return(MR_SUCCESS);
-}
+ 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;
-/* setup_dusr - verify that the user is no longer being referenced
- * and may safely be deleted.
- */
+ /* If this is an MR_Q_UPDATE query, we're done. */
+ if (row == 2)
+ return MR_SUCCESS;
-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);
+ /* For an add query, we need to fill in the creator id. */
+ sprintf(argv[q->argc + q->vcnt + 1], "%d", cl->client_id);
+ 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.
+/* setup_dusr - verify that the user is no longer being referenced
+ * and may safely be deleted.
*/
-int setup_spop(q, argv)
- struct query *q;
- char **argv;
+
+int setup_dusr(struct query *q, char *argv[], client *cl)
{
- 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);
+ EXEC SQL BEGIN DECLARE SECTION;
+ int flag, id, cnt;
+ char resv[USERS_RESERVATIONS_SIZE];
+ EXEC SQL END DECLARE SECTION;
+
+ id = *(int *)argv[0];
+
+ /* For now, only allow users to be deleted if their status is
+ * one of 0, 4, or 8 (the various registerable statuses)
+ * and we have no reservations about deleting them.
+ */
+ EXEC SQL SELECT status, reservations INTO :flag, :resv
+ FROM users WHERE users_id = :id;
+ if ((flag != 0 && flag != 4 && flag != 8) || *resv)
+ return MR_IN_USE;
+
+ 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;
+
+ EXEC SQL DELETE FROM quota WHERE entity_id = :id AND type = 'USER';
+ EXEC SQL DELETE FROM krbmap WHERE users_id = :id;
+ 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;
+int setup_dpob(struct query *q, char *argv[], client *cl)
{
- 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);
+ EXEC SQL BEGIN DECLARE SECTION;
+ int id, user;
+ char type[USERS_POTYPE_SIZE];
+ 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;
}
* and may safely be deleted.
*/
-int setup_dmac(q, argv)
- struct query *q;
- char **argv;
+int setup_dmac(struct query *q, char *argv[], client *cl)
{
- 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 SELECT COUNT(mach_id) INTO :cnt FROM hostalias
- 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);
+ 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(login) INTO :cnt FROM users
+ WHERE potype = 'EXCHANGE' and exchange_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 printers
+ WHERE mach_id = :id;
+ if (cnt > 0)
+ return MR_IN_USE;
+ EXEC SQL SELECT COUNT(rm) INTO :cnt FROM printers
+ WHERE rm = :id;
+ if (cnt > 0)
+ return MR_IN_USE;
+ EXEC SQL SELECT COUNT(rq) INTO :cnt FROM printers
+ WHERE rq = :id;
+ if (cnt > 0)
+ return MR_IN_USE;
+ EXEC SQL SELECT COUNT(mach_id) INTO :cnt FROM printservers
+ WHERE mach_id = :id;
+ if (cnt > 0)
+ return MR_IN_USE;
+ EXEC SQL SELECT COUNT(mach_id) INTO :cnt FROM hostalias
+ WHERE mach_id = :id;
+ if (cnt > 0)
+ return MR_IN_USE;
+ EXEC SQL SELECT COUNT(member_id) INTO :cnt FROM imembers
+ WHERE member_type = 'MACHINE' and member_id = :id;
+ if (cnt > 0)
+ return MR_IN_USE;
+
+ EXEC SQL DELETE FROM mcmap WHERE mach_id = :id;
+ if (dbms_errno)
+ return mr_errcode;
+
+ EXEC SQL DELETE FROM mcntmap WHERE mach_id = :id;
+ if (dbms_errno)
+ return mr_errcode;
+ return MR_SUCCESS;
}
+/* setup_asnt - verify that the data entered for the subnet is sane.
+ * In particular, make sure that the "low" and "high" addresses are
+ * correctly ordered, i.e., high > low.
+ */
+
+int setup_asnt(struct query *q, char *argv[], client *cl)
+{
+ int high, low, row, status;
+ char *account_number;
+
+ /* Check for asnt or usnt. */
+ if (q->type == MR_Q_APPEND)
+ row = 0;
+ else
+ row = 1;
+
+ low = atoi(argv[row + 7]);
+ high = atoi(argv[row + 8]);
+ status = atoi(argv[row + 2]);
+ account_number = argv[row + 4];
+
+ /* Don't allow Private subnets to be created without a valid billing
+ * number.
+ */
+ if (status == SNET_STATUS_PRIVATE_10MBPS ||
+ status == SNET_STATUS_PRIVATE_100MBPS ||
+ status == SNET_STATUS_PRIVATE_1000MBPS)
+ {
+ EXEC SQL SELECT account_number FROM accountnumbers
+ WHERE account_number = :account_number;
+ if (sqlca.sqlcode == SQL_NO_MATCH)
+ return MR_ACCOUNT_NUMBER;
+ }
+
+ /* Special case 0.0.0.0 and 255.255.255.255 */
+ if (!(low == 0 || low == -1 || high == 0 || high == -1))
+ if (low > high)
+ return MR_ADDRESS;
+
+ /* If this is update_subnet, we're done. */
+ if (row == 1)
+ return MR_SUCCESS;
+
+ /* For an add_subnet query, allocate and fill in a new snet_id */
+ if ((mr_errcode = prefetch_value(q, argv, cl)) != MR_SUCCESS)
+ 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;
+int setup_dsnt(struct query *q, char *argv[], client *cl)
{
- 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);
+ 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;
}
* and may safely be deleted.
*/
-int setup_dclu(q, argv)
- struct query *q;
- char **argv;
+int setup_dclu(struct query *q, char *argv[], client *cl)
{
- 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);
+ 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;
}
* 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 :.
+ *
+ * Newlines in list descriptions do bad things to the aliases file
+ * moira generates, so make sure the description doesn't contain any, too.
*/
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,
+ 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, 1, 1, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, /* SPACE - / */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 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, 1, 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, 1, 1, 1, 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;
+static const char *mailman_suffixes[] = { "-admin", "-owner", "-request",
+ "-bounces", "-confirm", "-join",
+ "-leave", "-subscribe",
+ "-unsubscribe", NULL };
+
+int setup_alis(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++)
+ EXEC SQL BEGIN DECLARE SECTION;
+ int ngid, cnt, mailman, mailman_id, lid;
+ char *name, *desc;
+ EXEC SQL END DECLARE SECTION;
+ unsigned char *p;
+ int idx, err, best = -1, usage, i;
+
+ if (!strcmp(q->shortname, "alis"))
+ idx = 0;
+ else if (!strcmp(q->shortname, "ulis"))
+ idx = 1;
+ name = argv[idx];
+
+ if (q->version == 2)
+ desc = argv[9 + idx];
+ else if (q->version == 3)
+ desc = argv[10 + idx];
+ else if (q->version == 4)
+ desc = argv[12 + idx];
+ else if (q->version >= 10)
+ desc = argv[14 + idx];
+
+ if (idx == 1)
+ {
+ lid = *(int *)argv[0];
+
+ if (acl_access_check(lid, cl))
+ return MR_PERM;
+ }
+
+ for (p = (unsigned char *) name; *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");
+ return MR_BAD_CHAR;
+ }
+
+ for (p = (unsigned char *) desc; *p; p++)
+ {
+ if (*p == '\n')
+ return MR_BAD_CHAR;
+ }
+
+ /* Check that it doesn't conflict with a pre-existing weirdly-cased
+ * name. */
+ EXEC SQL SELECT COUNT(name) INTO :cnt FROM list
+ WHERE LOWER(name) = :name AND name != :name;
+ if (cnt)
+ return MR_EXISTS;
+
+ 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);
+ /* Don't let someone rename a list to one of the magic mailman names
+ * (foo-admin, etc) if foo already exists as a mailman list.
+ */
+ for (i = 0; mailman_suffixes[i]; i++)
+ {
+ if ((err = check_mailman_listname(name, mailman_suffixes[i]))
+ != MR_SUCCESS)
+ return err;
+ }
+
+ if (q->version >= 10)
+ {
+ /* Don't let them take this name for a mailman list if we can't
+ * reserve the -admin, -owner, and -request names.
+ */
+ if (atoi(argv[8 + idx]))
+ {
+ EXEC SQL SELECT COUNT(name) INTO :cnt FROM list
+ WHERE (name = :name || '-admin' OR name = :name || '-owner' OR
+ name = :name || '-request');
+ if (cnt)
+ return MR_EXISTS;
+ }
+
+ /* Handle the [ANY] case for mailman server. */
+ mailman_id = *(int *)argv[9 + idx];
+ if (mailman_id == -1)
+ {
+ EXEC SQL DECLARE csr_mailman CURSOR FOR
+ SELECT mach_id FROM serverhosts WHERE service = 'MAILMAN'
+ AND enable = 1;
+ if (dbms_errno)
+ return mr_errcode;
+ EXEC SQL OPEN csr_mailman;
+ if (dbms_errno)
+ return mr_errcode;
+
+ while (1)
+ {
+ EXEC SQL FETCH csr_mailman INTO :mailman_id;
+ if (sqlca.sqlcode)
+ break;
+
+ EXEC SQL SELECT COUNT(name) INTO :usage FROM list
+ WHERE mailman_id = :mailman_id;
+
+ if (best < 0 || usage < best)
+ {
+ best = usage;
+ *(int *)argv[9 + idx] = mailman_id;
+ break;
+ }
+ }
+ EXEC SQL CLOSE csr_mailman;
+ if (dbms_errno)
+ return mr_errcode;
+
+ if (best == -1)
+ return MR_SERVICE;
+ }
+ }
+ else
+ {
+ /* Client too old to know about the mailman code.
+ * Use existing value of mailman boolean in the table.
+ * Don't do this for add_list from an old client, since the row
+ * they're creating won't exist yet, and there's no way for them to
+ * create a list with the mailman bit set, anyway.
+ */
+ if (idx == 1)
+ {
+ EXEC SQL SELECT mailman INTO :mailman FROM list WHERE list_id = :lid;
+ if (mailman)
+ {
+ EXEC SQL SELECT COUNT(name) INTO :cnt FROM list
+ WHERE (name = :name || '-admin' OR name = :name || '-owner' OR
+ name = :name || '-request');
+ if (cnt)
+ return MR_EXISTS;
+ }
+ }
+ }
- return(MR_SUCCESS);
+ if ((mr_errcode = prefetch_value(q, argv, cl)) != MR_SUCCESS)
+ return mr_errcode;
+
+ return MR_SUCCESS;
}
* and may safely be deleted.
*/
-int setup_dlis(q, argv)
- struct query *q;
- char *argv[];
+int setup_dlis(struct query *q, char *argv[], client *cl)
{
- 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);
+ 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 list
+ WHERE memacl_id = :id AND memacl_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
+ OR z.owner_type = 'LIST' and z.owner_id = :id;
+ if (cnt > 0)
+ return MR_IN_USE;
+
+ EXEC SQL SELECT COUNT(name) INTO :cnt FROM printers
+ WHERE lpc_acl = :id OR ac = :id;
+ if (cnt > 0)
+ return MR_IN_USE;
+
+ EXEC SQL SELECT COUNT(mach_id) INTO :cnt FROM printservers
+ WHERE owner_type = 'LIST' AND owner_id = :id
+ OR lpc_acl = :id;
+ if (cnt > 0)
+ return MR_IN_USE;
+
+ EXEC SQL SELECT count(name) INTO :cnt FROM containers
+ WHERE acl_id = :id AND acl_type = 'LIST';
+ if (cnt > 0)
+ return MR_IN_USE;
+
+ EXEC SQL SELECT count(name) INTO :cnt FROM containers
+ WHERE memacl_id = :id AND memacl_type = 'LIST';
+ if (cnt > 0)
+ return MR_IN_USE;
+
+ return MR_SUCCESS;
}
* and may safely be deleted.
*/
-int setup_dsin(q, argv)
- struct query *q;
- char **argv;
+int setup_dsin(struct query *q, char *argv[], client *cl)
{
- 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);
+ 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;
}
* and may safely be deleted.
*/
-int setup_dshi(q, argv)
- struct query *q;
- char **argv;
+int setup_dshi(struct query *q, char *argv[], client *cl)
{
- 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);
+ 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;
}
** Description:
** - for type = RVD:
** * allow anything
- ** - for type = NFS:
+ ** - for type = NFS/IMAP:
** * extract directory prefix from name
** * verify mach_id/dir in nfsphys
** * verify rwaccess in {r, w, R, W}
int _var_phys_id;
EXEC SQL END DECLARE SECTION;
-int setup_afil(q, argv, cl)
- struct query *q;
- char *argv[];
- client *cl;
+int setup_afil(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);
+ char *type, *name;
+ int mach_id;
+ EXEC SQL BEGIN DECLARE SECTION;
+ int ok;
+ char ftype[FILESYS_TYPE_SIZE + 10], *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") || !strcmp(type, "IMAP"))
+ return check_nfs(mach_id, name, rwaccess);
+
+ return MR_SUCCESS;
}
* the new phys_id.
*/
-int setup_ufil(q, argv, cl)
- struct query *q;
- char *argv[];
- client *cl;
+int setup_ufil(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);
+ int mach_id, status;
+ char *type, *name;
+ EXEC SQL BEGIN DECLARE SECTION;
+ int fid, total, who, ok;
+ char *entity, ftype[FILESYS_TYPE_SIZE + 10], *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") || !strcmp(type, "IMAP"))
+ {
+ 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")
+ && strcmp(strtrim(ftype), "ERR"))
+ {
+ 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))
+ {
+ 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);
+ else
+ {
+ EXEC SQL UPDATE quota SET phys_id = 0 WHERE filsys_id = :fid;
+ if (dbms_errno)
+ return mr_errcode;
+ }
+ return MR_SUCCESS;
}
* 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;
+int check_nfs(int mach_id, char *name, char *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;
+ EXEC SQL BEGIN DECLARE SECTION;
+ char dir[NFSPHYS_DIR_SIZE];
+ int mid = mach_id;
+ EXEC SQL END DECLARE SECTION;
+ int status;
+ char *cp1;
+ char *cp2;
+
+ status = MR_NFS;
+ EXEC SQL DECLARE csr101 CURSOR FOR
+ SELECT nfsphys_id, dir FROM nfsphys
+ WHERE mach_id = :mid
+ 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)
+ break;
+ cp1 = name;
+ cp2 = strtrim(dir);
+ while (*cp2)
+ {
+ if (*cp1++ != *cp2)
break;
+ cp2++;
+ }
+ if (!*cp2)
+ {
+ status = MR_SUCCESS;
+ break;
}
}
- EXEC SQL CLOSE csr101;
- if (dbms_errno)
- return(mr_errcode);
- return(status);
+ EXEC SQL CLOSE csr101;
+ if (dbms_errno)
+ return mr_errcode;
+ return status;
}
* a filesystem when it is deleted. Also adjust the allocation numbers.
*/
-int setup_dfil(q, argv, cl)
- struct query *q;
- char **argv;
- client *cl;
+int setup_dfil(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);
+ 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;
}
* any filesystems assigned to it before allowing it to be deleted.
*/
-int setup_dnfp(q, argv, cl)
- struct query *q;
- char **argv;
- client *cl;
+int setup_dnfp(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);
+ 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;
}
* argv[2 or 1] = users_id or list_id
*/
-int setup_dqot(q, argv, cl)
- struct query *q;
- char **argv;
- client *cl;
+int setup_dqot(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 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;
+ 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);
+ if (dbms_errno)
+ return mr_errcode;
+ return MR_SUCCESS;
}
* 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
+ * 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.
+ * that this query is an MR_Q_APPEND.
*/
-int prefetch_value(q, argv, cl)
- struct query *q;
- char **argv;
- client *cl;
+int prefetch_value(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);
+ 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 MR_Q_APPENDs */
+ sprintf(argv[argc], "%d", value);
+
+ return MR_SUCCESS;
}
/* prefetch_filesys():
* 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;
+int prefetch_filesys(struct query *q, char **argv, client *cl)
{
- EXEC SQL BEGIN DECLARE SECTION;
- int fid,phid;
- EXEC SQL END DECLARE SECTION;
- int argc;
+ 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);
+ 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);
+ argc = q->argc + q->vcnt;
+ sprintf(argv[argc++], "%d", phid);
+ sprintf(argv[argc], "%d", fid);
- return(MR_SUCCESS);
+ return MR_SUCCESS;
}
+/* setup_ghst():
+ */
+
+int setup_ghst(struct query *q, char **argv, client *cl)
+{
+ if (strcmp(argv[0], "*") || strcmp(argv[1], "*") ||
+ strcmp(argv[2], "*") || strcmp(argv[3], "*"))
+ return MR_SUCCESS;
+ else
+ return MR_PERM;
+}
+
/* setup_ahst():
*/
-int setup_ahst(q, argv, cl)
- struct query *q;
- char **argv;
- client *cl;
+int setup_ahst(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"))
+ EXEC SQL BEGIN DECLARE SECTION;
+ char *name, oldname[MACHINE_NAME_SIZE], vendor[MACHINE_VENDOR_SIZE];
+ char model[MACHINE_MODEL_SIZE], os[MACHINE_OS_SIZE];
+ int value, id, ssaddr, smask, shigh, slow, cnt;
+ unsigned int saddr, mask, high, low;
+ EXEC SQL END DECLARE SECTION;
+ int row, idx;
+ struct in_addr addr;
+
+ id = *(int *)argv[0];
+
+ 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);
+ EXEC SQL SELECT name, vendor, model, os
+ INTO :oldname, :vendor, :model, :os
+ FROM machine WHERE mach_id = :id;
+ }
+ else
+ row = 0;
+
+ if (q->version < 6)
+ idx = 0;
+ else if (q->version >= 6 && q->version < 8)
+ idx = 1;
+ else
+ idx = 2;
+
+ /* Sanity check name, vendor, model, and os. */
+ if ((row == 0 || strcasecmp(argv[1], oldname)) &&
+ !hostname_check(argv[row]))
+ return MR_BAD_CHAR;
+ if ((row == 0 || strcasecmp(argv[2], vendor)) &&
+ !hostinfo_check(argv[row + 1], 0))
+ return MR_BAD_CHAR;
+ if ((row == 0 || strcasecmp(argv[3], model)) &&
+ !hostinfo_check(argv[row + 2], 1))
+ return MR_BAD_CHAR;
+ if ((row == 0 || strcasecmp(argv[4], os)) &&
+ !hostinfo_check(argv[row + 3], 0))
+ return MR_BAD_CHAR;
+
+ /* check for duplicate name */
+ name = argv[row];
+ EXEC SQL SELECT count(mach_id) INTO :cnt FROM hostalias
+ WHERE name = UPPER(:name);
+ if (dbms_errno)
+ return mr_errcode;
+ if (cnt != 0)
+ return MR_EXISTS;
+
+ /* check address */
+ if (!strcmp(argv[9 + row + idx], "unassigned"))
+ value = -1;
+ else if (!strcmp(argv[9 + row + idx], "unique"))
+ {
+ if (*(int *)argv[8 + row + idx] == 0)
+ value = -1;
+ else
+ value = -2;
+ }
+ else
+ {
+ value = ntohl(inet_addr(argv[9 + row + idx]));
+ 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 + idx];
+ EXEC SQL SELECT saddr, mask, high, low INTO :ssaddr, :smask,
+ :shigh, :slow FROM subnet WHERE snet_id = :id;
+ if (dbms_errno)
+ return mr_errcode;
+ saddr = (unsigned) ssaddr;
+ mask = (unsigned) smask;
+ high = (unsigned) shigh;
+ low = (unsigned) slow;
+ if (value != -2)
+ {
+ /*
+ * someone specified an IP address for the host record
+ */
+ if ((value & mask) != saddr || value < low || value > high)
+ 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 + idx]);
+ 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;
+ }
+ }
}
- if (*(p-1) == '-') return(MR_BAD_CHAR);
+ 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 = 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_NO_ID;
+ 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 + idx], inet_ntoa(addr));
}
-
- /* 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);
+ else
+ strcpy(argv[9 + row + idx], "unassigned");
+
+ /* status checking */
+ value = atoi(argv[7 + row + idx]);
+ 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 (!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 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(struct query *q, char **argv, client *cl)
+{
+ EXEC SQL BEGIN DECLARE SECTION;
+ char *name;
+ int cnt;
+ EXEC SQL END DECLARE SECTION;
+ char *p;
+
+ name = argv[0];
+ if (!hostname_check(argv[0]))
+ return MR_BAD_CHAR;
+
+ EXEC SQL SELECT count(mach_id) INTO :cnt FROM machine WHERE
+ name = UPPER(:name);
+ if (dbms_errno)
+ return mr_errcode;
+ if (cnt > 0)
+ return MR_EXISTS;
+
+ return MR_SUCCESS;
+}
+
+/* setup_uhha(): Check characters in hwaddr, and make sure it's not
+ * a duplicate.
+ */
+int setup_uhha(struct query *q, char **argv, client *cl)
+{
+ EXEC SQL BEGIN DECLARE SECTION;
+ char *hwaddr = argv[1];
+ int count;
+ EXEC SQL END DECLARE SECTION;
+ char *p;
+
+ if (*hwaddr && strcasecmp(hwaddr, "unknown"))
+ {
+ for (p = hwaddr; *p; p++)
+ {
+ if (isupper(*p))
+ *p = tolower(*p);
+ if (!isxdigit(*p))
+ return MR_BAD_CHAR;
}
- if (!isalnum(*(p-1))) return(MR_BAD_CHAR);
+ if (p != hwaddr + 12)
+ return MR_ADDRESS;
+
+ EXEC SQL SELECT COUNT(hwaddr) INTO :count
+ FROM machine WHERE hwaddr = :hwaddr;
+ if (count)
+ return MR_NOT_UNIQUE;
}
- /* 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);
+ return MR_SUCCESS;
+}
+
+/* setup_aprn(): Make sure name/duplexname don't conflict with
+ * anything. If [ANY] was specified for the spooling host, pick the
+ * least loaded print server that serves this kind of printer.
+ */
+int setup_aprn(struct query *q, char **argv, client *cl)
+{
+ int best = -1, row;
+ char *p;
+ EXEC SQL BEGIN DECLARE SECTION;
+ int mid, usage, count;
+ char types[STRINGS_STRING_SIZE], *hwaddr, *name, *duplexname, *oldname;
+ EXEC SQL END DECLARE SECTION;
+
+ /* Check for aprn or uprn. */
+ if (q->type == MR_Q_APPEND)
+ row = 0;
+ else
+ row = 1;
+
+ name = argv[PRN_NAME + row];
+ duplexname = argv[PRN_DUPLEXNAME + row];
+ oldname = argv[0];
+
+ if (!*name)
+ return MR_BAD_CHAR;
+ else
+ {
+ if (q->type == MR_Q_APPEND)
+ {
+ EXEC SQL SELECT COUNT(name) INTO :count FROM printers
+ WHERE name = :name OR duplexname = :name;
}
- if (!isalnum(*(p-1))) return(MR_BAD_CHAR);
+ else
+ {
+ EXEC SQL SELECT COUNT(name) INTO :count FROM printers
+ WHERE ( name = :name OR duplexname = :name )
+ AND name != :oldname;
+ }
+ if (dbms_errno)
+ return mr_errcode;
+ if (count)
+ return MR_NOT_UNIQUE;
}
- /* 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 (*duplexname)
+ {
+ if (q->type == MR_Q_APPEND)
+ {
+ EXEC SQL SELECT COUNT(name) INTO :count FROM printers
+ WHERE name = :duplexname OR duplexname = :duplexname;
+ }
+ else
+ {
+ EXEC SQL SELECT COUNT(name) INTO :count FROM printers
+ WHERE ( name = :duplexname OR duplexname = :duplexname )
+ AND name != :oldname;
+ }
+
+ if (dbms_errno)
+ return mr_errcode;
+ if (count)
+ return MR_NOT_UNIQUE;
}
- 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);
+
+ if (!strcmp(name, duplexname))
+ return MR_NOT_UNIQUE;
+
+ mid = *(int *)argv[PRN_RM + row];
+ if (mid == -1)
+ {
+ EXEC SQL DECLARE csr_rm CURSOR FOR
+ SELECT ps.mach_id, s.string FROM printservers ps, strings s
+ WHERE ps.mach_id IN
+ ( SELECT mach_id FROM serverhosts WHERE service = 'PRINT'
+ AND enable = 1 )
+ AND ps.printer_types = s.string_id;
+ if (dbms_errno)
+ return mr_errcode;
+ EXEC SQL OPEN csr_rm;
+ if (dbms_errno)
+ return mr_errcode;
+
+ while (1)
+ {
+ EXEC SQL FETCH csr_rm INTO :mid, :types;
+ if (sqlca.sqlcode)
+ break;
+
+ for (p = strtok(types, ", "); p; p = strtok(NULL, ", "))
+ {
+ if (!strcasecmp(argv[PRN_TYPE + row], p))
+ {
+ EXEC SQL SELECT COUNT(name) INTO :usage
+ FROM printers WHERE rm = :mid;
+
+ if (best < 0 || usage < best)
+ {
+ best = usage;
+ *(int *)argv[PRN_RM + row] = mid;
+ break;
+ }
}
}
- } 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");
- }
+ EXEC SQL CLOSE csr_rm;
+ if (dbms_errno)
+ return mr_errcode;
- /* 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 (best == -1)
+ return MR_SERVICE;
}
-
- 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);
+ else
+ {
+ EXEC SQL SELECT mach_id INTO :mid FROM printservers
+ WHERE mach_id = :mid;
+ if (sqlca.sqlcode)
+ return MR_SERVICE;
}
- /*
- * 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);
+ return MR_SUCCESS;
}
+int setup_dpsv(struct query *q, char **argv, client *cl)
+{
+ int id;
+ EXEC SQL BEGIN DECLARE SECTION;
+ int cnt;
+ EXEC SQL END DECLARE SECTION;
-/* setup_ahal():
+ id = *(int *)argv[0];
+
+ EXEC SQL SELECT COUNT(rm) INTO :cnt FROM printers
+ WHERE rm = :id;
+ if (cnt > 0)
+ return MR_IN_USE;
+
+ return MR_SUCCESS;
+}
+
+int setup_dcon(struct query *q, char *argv[], client *cl)
+{
+ EXEC SQL BEGIN DECLARE SECTION;
+ int id, cnt;
+ char containername[CONTAINERS_NAME_SIZE];
+ EXEC SQL END DECLARE SECTION;
+
+ id = *(int *)argv[0];
+ /* check to see if there are machines in this container */
+ EXEC SQL SELECT COUNT(mach_id) INTO :cnt FROM mcntmap
+ WHERE cnt_id = :id;
+ if (cnt > 0)
+ return MR_IN_USE;
+
+ /* check to see if there are subcontainers in this container */
+
+ /* get the container name */
+
+ EXEC SQL SELECT name INTO :containername
+ FROM containers
+ WHERE cnt_id = :id;
+
+ /* trim off the trailing spaces */
+ strcpy(containername, strtrim(containername));
+
+ EXEC SQL SELECT COUNT(cnt_id) INTO :cnt FROM containers
+ WHERE LOWER(name) LIKE LOWER(:containername || '/' || '%');
+
+ if (cnt > 0)
+ return MR_IN_USE;
+
+ if (dbms_errno)
+ return mr_errcode;
+ return MR_SUCCESS;
+}
+
+int setup_scli(struct query *q, char *argv[], client *cl)
+{
+ EXEC SQL BEGIN DECLARE SECTION;
+ int cnt_id, list_id;
+ EXEC SQL END DECLARE SECTION;
+
+ cnt_id = *(int *)argv[0];
+ /* Check if someone has already set the list for this container */
+ EXEC SQL SELECT list_id INTO :list_id FROM containers
+ WHERE cnt_id = :cnt_id;
+ if (list_id != 0)
+ return MR_EXISTS;
+
+ if (dbms_errno)
+ return mr_errcode;
+
+ return MR_SUCCESS;
+}
+
+/* hostname_check()
+ * validate the rfc1035/rfc1123-ness of a hostname
*/
-int setup_ahal(q, argv, cl)
- struct query *q;
- char **argv;
- client *cl;
+int hostname_check(char *name)
+{
+ char *p;
+ int count;
+
+ /* Sanity check name: must contain only letters, numerals, and
+ * hyphen, and not start or end with a hyphen. Also make sure no
+ * label (the thing the .s seperate) is longer than 63 characters,
+ * or empty.
+ */
+
+ for (p = name, count = 0; *p; p++)
+ {
+ count++;
+ if ((!isalnum(*p) && *p != '-' && *p != '.') ||
+ (*p == '-' && p[1] == '.'))
+ return 0;
+ if (*p == '.')
+ {
+ if (count == 1)
+ return 0;
+ count = 0;
+ }
+ if (count == 64)
+ return 0;
+ }
+ if (*(p - 1) == '-')
+ return 0;
+ return 1;
+}
+
+int hostinfo_check(char *info, int num)
+{
+ char *p;
+
+ if (!*info)
+ return 1;
+
+ /* Sanity check host hostinfo: must start with a letter (or number
+ * if num is true), contain only letters, numerals, and hyphen, and
+ * not end with a hyphen.
+ */
+
+ if (!isalpha(*info) && (!num || !isdigit(*info)))
+ return 0;
+ for (p = info; *p; p++)
+ {
+ if ((!isalnum(*p) && *p != '-' && *p != '.') ||
+ (*p == '-' && p[1] == '.'))
+ return 0;
+ }
+ if (!isalnum(*(p - 1)))
+ return 1;
+}
+
+int setup_aali(struct query *q, char *argv[], client *cl)
+{
+ EXEC SQL BEGIN DECLARE SECTION;
+ int cnt;
+ char *name, *type, *trans;
+ EXEC SQL END DECLARE SECTION;
+ name = argv[0];
+ type = argv[1];
+ trans = argv[2];
+
+ if (strcmp(strtrim(type), "FILESYS"))
+ return MR_SUCCESS;
+
+ EXEC SQL SELECT count(label) INTO :cnt FROM filesys WHERE
+ label = :name;
+ if (cnt > 0)
+ return MR_EXISTS;
+
+ return MR_SUCCESS;
+}
+
+int setup_acon(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);
+ EXEC SQL BEGIN DECLARE SECTION;
+ char containername[CONTAINERS_NAME_SIZE];
+ EXEC SQL END DECLARE SECTION;
+
+ char* ptr;
+
+ memset(containername, 0, sizeof(containername));
+ strcpy(containername, argv[0]);
+ ptr = strrchr(containername, '/');
+ /* sub container, check for parents */
+ if (ptr)
+ {
+ *ptr = '\0';
+ EXEC SQL SELECT * FROM containers
+ WHERE lower(name) = lower(:containername);
+ if (sqlca.sqlerrd[2] != 1)
+ return MR_CONTAINER_NO_PARENT;
}
- if (*(p-1) == '-') return(MR_BAD_CHAR);
+
+ if ((mr_errcode = prefetch_value(q, argv, cl)) != MR_SUCCESS)
+ return mr_errcode;
+
+ return MR_SUCCESS;
+}
- 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);
+int check_mailman_listname(char *name, const char *suffix)
+{
+ char *p;
+ EXEC SQL BEGIN DECLARE SECTION;
+ int i, cnt;
+ EXEC SQL END DECLARE SECTION;
+
+ p = strstr(name, suffix);
+ if (p)
+ {
+ if (strlen(name) == (p - name + strlen(suffix)))
+ {
+ /* list is of the form "name-suffix" */
+ i = (p - name);
+ EXEC SQL SELECT COUNT(name) INTO :cnt FROM list
+ WHERE name = SUBSTR(:name, 1, :i) AND mailman = 1;
+ if (cnt > 0)
+ return MR_EXISTS;
+ }
+ }
- return(MR_SUCCESS);
+ return MR_SUCCESS;
}