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 */
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 ((err = set_next_object_id("unix_uid", USERS_TABLE, 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;
}
id = *(int *)argv[0];
- /* For now, only allow users to be deleted if their status is 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) || *resv)
+ if ((flag != 0 && flag != 4 && flag != 8) || *resv)
return MR_IN_USE;
EXEC SQL SELECT COUNT(member_id) INTO :cnt FROM imembers
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 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)
char *account_number;
/* Check for asnt or usnt. */
- if (q->type == APPEND)
+ if (q->type == MR_Q_APPEND)
row = 0;
else
row = 1;
/* Don't allow Private subnets to be created without a valid billing
* number.
*/
- if (status == SNET_STATUS_PRIVATE)
+ 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;
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;
+ 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;
desc = argv[9 + idx];
else if (q->version == 3)
desc = argv[10 + idx];
- else if (q->version >= 4)
+ 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;
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 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;
}
* 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():
*/
EXEC SQL END DECLARE SECTION;
/* Check for aprn or uprn. */
- if (q->type == APPEND)
+ if (q->type == MR_Q_APPEND)
row = 0;
else
row = 1;
return MR_BAD_CHAR;
else
{
- if (q->type == APPEND)
+ if (q->type == MR_Q_APPEND)
{
EXEC SQL SELECT COUNT(name) INTO :count FROM printers
WHERE name = :name OR duplexname = :name;
if (*duplexname)
{
- if (q->type == APPEND)
+ if (q->type == MR_Q_APPEND)
{
EXEC SQL SELECT COUNT(name) INTO :count FROM printers
WHERE name = :duplexname OR duplexname = :duplexname;
strcpy(containername, strtrim(containername));
EXEC SQL SELECT COUNT(cnt_id) INTO :cnt FROM containers
- WHERE name LIKE :containername || '/' || '%';
+ WHERE LOWER(name) LIKE LOWER(:containername || '/' || '%');
if (cnt > 0)
return MR_IN_USE;
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
*/
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;
+}