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 */
else
row = 1;
- if (strlen(argv[row + 2]) + strlen(argv[row + 3]) +
- strlen(argv[row + 4]) + 2 > USERS_FULLNAME_SIZE)
- return MR_ARG_TOO_LONG;
+ 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 (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 (!strcmp(argv[row], UNIQUE_UID) || atoi(argv[row]) == -1)
{
if ((mr_errcode = prefetch_value(q, argv, cl)) != MR_SUCCESS)
return mr_errcode;
+ /* If this is an MR_Q_UPDATE query, we're done. */
+ if (row == 2)
+ 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;
}
{
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 0 */
- EXEC SQL SELECT status INTO :flag FROM users WHERE users_id = :id;
- if (flag != 0 && flag != 4)
+ /* 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 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;
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(struct query *q, char *argv[], client *cl)
-{
- EXEC SQL BEGIN DECLARE SECTION;
- int id, mid;
- char type[USERS_POTYPE_SIZE];
- 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);
+ EXEC SQL DELETE FROM quota WHERE entity_id = :id AND type = 'USER';
+ EXEC SQL DELETE FROM krbmap WHERE users_id = :id;
return MR_SUCCESS;
}
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)
WHERE rq = :id;
if (cnt > 0)
return MR_IN_USE;
- EXEC SQL SELECT COUNT(mach_id) INTO :cnt FROM palladium
+ EXEC SQL SELECT COUNT(mach_id) INTO :cnt FROM printservers
WHERE mach_id = :id;
if (cnt > 0)
return MR_IN_USE;
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.
* 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, 1, 1, 0, 0, 1, 0, 0, 1, 1, 1, 0, 1, 0, 0, 1, /* SPACE - / */
+ 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 - _ */
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
};
+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, cnt;
- char *name;
+ int ngid, cnt, mailman, mailman_id, lid;
+ char *name, *desc;
EXEC SQL END DECLARE SECTION;
unsigned char *p;
- int idx, err;
+ int idx, err, best = -1, usage, i;
if (!strcmp(q->shortname, "alis"))
idx = 0;
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)
{
- EXEC SQL BEGIN DECLARE SECTION;
- int lid = *(int *)argv[0];
- EXEC SQL END DECLARE SECTION;
+ lid = *(int *)argv[0];
if (acl_access_check(lid, cl))
return MR_PERM;
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
strcpy(argv[6 + idx], "-1");
}
+ /* 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;
+ }
+ }
+ }
+
if ((mr_errcode = prefetch_value(q, argv, cl)) != MR_SUCCESS)
return mr_errcode;
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)
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.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;
** 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}
if ((mr_errcode = prefetch_value(q, argv, cl)) != MR_SUCCESS)
return mr_errcode;
- if (!strcmp(type, "NFS"))
+ if (!strcmp(type, "NFS") || !strcmp(type, "IMAP"))
return check_nfs(mach_id, name, rwaccess);
return MR_SUCCESS;
if (dbms_errno)
return mr_errcode;
- if (!strcmp(type, "NFS"))
+ if (!strcmp(type, "NFS") || !strcmp(type, "IMAP"))
{
status = check_nfs(mach_id, name, access);
EXEC SQL UPDATE quota SET phys_id = :_var_phys_id
* 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(struct query *q, char **argv, client *cl)
if (sqlca.sqlerrd[2] != 1)
return MR_INTERNAL;
- argc = q->argc + q->vcnt; /* end of Argv for APPENDs */
+ argc = q->argc + q->vcnt; /* end of Argv for MR_Q_APPENDs */
sprintf(argv[argc], "%d", value);
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 value, id, ssaddr, smask, shigh, slow, cnt;
unsigned int saddr, mask, high, low;
EXEC SQL END DECLARE SECTION;
- int row;
+ int row, idx;
struct in_addr addr;
id = *(int *)argv[0];
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_EXISTS;
/* check address */
- if (!strcmp(argv[9 + row], "unassigned"))
+ if (!strcmp(argv[9 + row + idx], "unassigned"))
value = -1;
- else if (!strcmp(argv[9 + row], "unique"))
+ else if (!strcmp(argv[9 + row + idx], "unique"))
{
- if (*(int *)argv[8 + row] == 0)
+ if (*(int *)argv[8 + row + idx] == 0)
value = -1;
else
value = -2;
}
else
{
- value = ntohl(inet_addr(argv[9 + row]));
+ value = ntohl(inet_addr(argv[9 + row + idx]));
if (value == -1)
return MR_ADDRESS;
}
/*
* an address or unique was specified.
*/
- id = *(int *)argv[8 + row];
+ 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)
* link in an inet_addr() that returns an error for
* this case.
*/
- addr.s_addr = inet_addr(argv[9 + row]);
+ 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;
* 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));
+ strcpy(argv[9 + row + idx], inet_ntoa(addr));
}
else
- strcpy(argv[9 + row], "unassigned");
+ strcpy(argv[9 + row + idx], "unassigned");
/* status checking */
- value = atoi(argv[7 + row]);
+ value = atoi(argv[7 + row + idx]);
if (row == 0 && !(value == 1 || value == 0))
return MR_TYPE;
if (row == 1)
*/
int setup_aprn(struct query *q, char **argv, client *cl)
{
- int best = -1;
+ int best = -1, row;
char *p;
EXEC SQL BEGIN DECLARE SECTION;
int mid, usage, count;
- char types[SERVERHOSTS_VALUE3_SIZE], *hwaddr, *name;
+ char types[STRINGS_STRING_SIZE], *hwaddr, *name, *duplexname, *oldname;
EXEC SQL END DECLARE SECTION;
- name = argv[PRN_NAME];
+ /* 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
{
- EXEC SQL SELECT COUNT(name) INTO :count FROM printers
- WHERE name = :name OR duplexname = :name;
+ if (q->type == MR_Q_APPEND)
+ {
+ EXEC SQL SELECT COUNT(name) INTO :count FROM printers
+ WHERE name = :name OR duplexname = :name;
+ }
+ 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;
}
- name = argv[PRN_DUPLEXNAME];
- if (*name)
+ if (*duplexname)
{
- EXEC SQL SELECT COUNT(name) INTO :count FROM printers
- WHERE name = :name OR duplexname = :name;
+ 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 (*(int *)argv[PRN_RM] == -1)
+ 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 mach_id, value1, value3 FROM serverhosts
- WHERE service = 'PRINT';
+ 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;
while (1)
{
- EXEC SQL FETCH csr_rm INTO :mid, :usage, :types;
+ EXEC SQL FETCH csr_rm INTO :mid, :types;
if (sqlca.sqlcode)
break;
- if (best > 0 && usage > best)
- continue;
-
for (p = strtok(types, ", "); p; p = strtok(NULL, ", "))
{
- if (!strcasecmp(argv[PRN_TYPE], p))
+ if (!strcasecmp(argv[PRN_TYPE + row], p))
{
- best = usage;
- *(int *)argv[PRN_RM] = mid;
- break;
+ 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;
+ }
}
}
}
if (best == -1)
return MR_SERVICE;
}
+ else
+ {
+ EXEC SQL SELECT mach_id INTO :mid FROM printservers
+ WHERE mach_id = :mid;
+ if (sqlca.sqlcode)
+ return MR_SERVICE;
+ }
+
+ 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;
+
+ 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;
}
/* 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.
+ * label (the thing the .s seperate) is longer than 63 characters,
+ * or empty.
*/
for (p = name, count = 0; *p; p++)
(*p == '-' && p[1] == '.'))
return 0;
if (*p == '.')
- count = 0;
+ {
+ if (count == 1)
+ return 0;
+ count = 0;
+ }
if (count == 64)
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 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 ((mr_errcode = prefetch_value(q, argv, cl)) != MR_SUCCESS)
+ return mr_errcode;
+
+ return MR_SUCCESS;
+}
+
+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;
+}