{
EXEC SQL BEGIN DECLARE SECTION;
int list_id, acl_id, flags, gid, users_id, member_id, member_acl_id;
- int memacl_id;
+ int memacl_id, mailman, mailman_id;
char acl_type[LIST_ACL_TYPE_SIZE], name[LIST_NAME_SIZE], *newname;
char member_acl_type[LIST_ACL_TYPE_SIZE], memacl_type[LIST_ACL_TYPE_SIZE];
EXEC SQL END DECLARE SECTION;
- int status;
+ int status, cnt;
list_id = *(int *)argv[0];
member_id = *(int *)argv[2];
EXEC SQL SELECT acl_id, acl_type, memacl_id, memacl_type,
- gid, publicflg, name
+ gid, publicflg, name, mailman, mailman_id
INTO :acl_id, :acl_type, :memacl_id, :memacl_type,
- :gid, :flags, :name
+ :gid, :flags, :name, :mailman, :mailman_id
FROM list
WHERE list_id = :list_id;
newname = argv[1];
- if (!strcmp("ulis", q->shortname))
- {
- /* Check that it doesn't conflict with the Grouper namespace. */
- if (strlen(newname) > 4 && isdigit(newname[2]) &&
- isdigit(newname[3]) && newname[4] == '-')
- {
- if (!strncasecmp(newname, "fa", 2) ||
- !strncasecmp(newname, "sp", 2) ||
- !strncasecmp(newname, "su", 2) ||
- !strncasecmp(newname, "ja", 2))
- return MR_RESERVED;
- }
-
- /* Don't let anyone take owner-foo list names. They interact
- * weirdly with the aliases automatically generated by
- * mailhub.gen.
- */
- if (!strncasecmp(newname, "owner-", 6))
- return MR_RESERVED;
- }
-
+ /* Check that it doesn't conflict with the Grouper namespace. */
+ if (strlen(newname) > 4 && isdigit(newname[2]) &&
+ isdigit(newname[3]) && newname[4] == '-')
+ {
+ if (!strncasecmp(newname, "fa", 2) ||
+ !strncasecmp(newname, "sp", 2) ||
+ !strncasecmp(newname, "su", 2) ||
+ !strncasecmp(newname, "ja", 2))
+ return MR_RESERVED;
+ }
+
+ /* Don't let anyone take owner-foo list names. They interact
+ * weirdly with the aliases automatically generated by
+ * mailhub.gen.
+ */
+ if (!strncasecmp(newname, "owner-", 6))
+ return MR_RESERVED;
+
EXEC SQL SELECT users_id INTO :users_id FROM users
WHERE login = :newname;
if ((sqlca.sqlcode != SQL_NO_MATCH) && strcmp(strtrim(name), newname) &&
(users_id != cl->users_id))
return MR_PERM;
+
+ /* For modern enough clients, don't allow ordinary users to toggle
+ * the mailman bit or change the server.
+ */
+ if (q->version >= 10)
+ {
+ if (mailman != atoi(argv[9]))
+ return MR_PERM;
+
+ if (mailman_id != *(int *)argv[10])
+ return MR_PERM;
+ }
}
/* check for client in access control list and return success right
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 */
int setup_alis(struct query *q, char *argv[], client *cl)
{
EXEC SQL BEGIN DECLARE SECTION;
- int ngid, cnt;
+ int ngid, cnt, mailman, mailman_id;
char *name, *desc;
EXEC SQL END DECLARE SECTION;
unsigned char *p;
- int idx, err;
+ int idx, err, best = -1, usage;
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)
{
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.
+ */
+ if ((err = check_mailman_listname(name, "-admin")) != MR_SUCCESS)
+ return err;
+ if ((err = check_mailman_listname(name, "-owner")) != MR_SUCCESS)
+ return err;
+ if ((err = check_mailman_listname(name, "-request")) != 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;
+ }
+ }
+
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;
+}
"modwith",
};
-static char *glin_fields[] = {
+static char *glin4_fields[] = {
"name",
"name", "active", "publicflg", "hidden", "maillist", "grouplist", "gid",
"nfsgroup", "ace_type", "ace_name", "memace_type", "memace_name",
"description", "modtime", "modby", "modwith",
};
+static char *glin_fields[] = {
+ "name",
+ "name", "active", "publicflg", "hidden", "maillist", "grouplist", "gid",
+ "nfsgroup", "mailman", "mailman_server", "ace_type", "ace_name",
+ "memace_type", "memace_name", "description", "modtime", "modby", "modwith",
+};
+
static struct validate glin_validate = {
0,
0,
set_modtime,
};
-static char *alis_fields[] = {
+static char *alis4_fields[] = {
"name", "active", "publicflg", "hidden", "maillist", "grouplist", "gid",
"nfsgroup", "ace_type", "ace_name", "memace_type", "memace_name",
"description",
};
-static struct valobj alis_valobj[] = {
+static struct valobj alis4_valobj[] = {
{V_CHAR, 0, LIST_TABLE, "name"},
{V_NUM, 1},
{V_NUM, 2},
{V_LEN, 12, LIST_TABLE, "description"},
};
+static struct validate alis4_validate = {
+ alis4_valobj,
+ 13,
+ "name",
+ "name = '%s'",
+ 1,
+ "list_id",
+ 0,
+ setup_alis,
+ set_modtime,
+};
+
+static char *alis_fields[] = {
+ "name", "active", "publicflg", "hidden", "maillist", "grouplist", "gid",
+ "nfsgroup", "mailman", "mailman_server", "ace_type", "ace_name",
+ "memace_type", "memace_name", "description",
+};
+
+static struct valobj alis_valobj[] = {
+ {V_CHAR, 0, LIST_TABLE, "name"},
+ {V_NUM, 1},
+ {V_NUM, 2},
+ {V_NUM, 3},
+ {V_NUM, 4},
+ {V_NUM, 5},
+ {V_NUM, 6},
+ {V_NUM, 7},
+ {V_NUM, 8},
+ {V_ID, 9, MACHINE_TABLE, "name", "mach_id", MR_MACHINE},
+ {V_TYPE, 10, 0, "ace_type", 0, MR_ACE},
+ {V_TYPEDATA, 11, 0, 0, "list_id", MR_ACE},
+ {V_TYPE, 12, 0, "ace_type", 0, MR_ACE},
+ {V_TYPEDATA, 13, 0, 0, "list_id", MR_ACE},
+ {V_LEN, 14, LIST_TABLE, "description"},
+};
+
static struct validate alis_validate = {
alis_valobj,
- 13,
+ 15,
"name",
"name = '%s'",
1,
set_modtime_by_id,
};
-static char *ulis_fields[] = {
+static char *ulis4_fields[] = {
"name",
"newname", "active", "publicflg", "hidden", "maillist", "grouplist", "gid",
"nfsgroup", "ace_type", "ace_name", "memace_type", "memace_name",
"description",
};
-static struct valobj ulis_valobj[] = {
+static struct valobj ulis4_valobj[] = {
{V_ID, 0, LIST_TABLE, "name", "list_id", MR_LIST},
{V_RENAME, 1, LIST_TABLE, "name", "list_id", MR_NOT_UNIQUE},
{V_NUM, 2},
{V_LEN, 13, LIST_TABLE, "description"},
};
+static struct validate ulis4_validate = {
+ ulis4_valobj,
+ 14,
+ "name",
+ "list_id = %d",
+ 1,
+ "list_id",
+ access_list,
+ setup_alis,
+ set_modtime_by_id,
+};
+
+static char *ulis_fields[] = {
+ "name",
+ "newname", "active", "publicflg", "hidden", "maillist", "grouplist", "gid",
+ "nfsgroup", "mailman", "mailman_server", "ace_type", "ace_name",
+ "memace_type", "memace_name", "description",
+};
+
+static struct valobj ulis_valobj[] = {
+ {V_ID, 0, LIST_TABLE, "name", "list_id", MR_LIST},
+ {V_RENAME, 1, LIST_TABLE, "name", "list_id", MR_NOT_UNIQUE},
+ {V_NUM, 2},
+ {V_NUM, 3},
+ {V_NUM, 4},
+ {V_NUM, 5},
+ {V_NUM, 6},
+ {V_NUM, 7},
+ {V_NUM, 8},
+ {V_NUM, 9},
+ {V_ID, 10, MACHINE_TABLE, "name", "mach_id", MR_MACHINE},
+ {V_TYPE, 11, 0, "ace_type", 0, MR_ACE},
+ {V_TYPEDATA, 12, 0, 0, "list_id", MR_ACE},
+ {V_TYPE, 13, 0, "ace_type", 0, MR_ACE},
+ {V_TYPEDATA, 14, 0, 0, "list_id", MR_ACE},
+ {V_LEN, 15, LIST_TABLE, "description"},
+};
+
static struct validate ulis_validate = {
ulis_valobj,
- 14,
+ 16,
"name",
"list_id = %d",
1,
"l",
LIST_TABLE,
"name, active, publicflg, hidden, maillist, grouplist, gid, nfsgroup, acl_type, acl_id, memacl_type, memacl_id, description, TO_CHAR(modtime, 'DD-mon-YYYY HH24:MI:SS'), modby, modwith FROM list",
- glin_fields,
+ glin4_fields,
16,
"name LIKE '%s'",
1,
&glin_validate,
},
+ {
+ /* Q_GLIN - GET_LIST_INFO, v10 */
+ "get_list_info",
+ "glin",
+ 10,
+ RETRIEVE,
+ "l",
+ LIST_TABLE,
+ "l.name, l.active, l.publicflg, l.hidden, l.maillist, l.grouplist, l.gid, l.nfsgroup, l.mailman, m.name, l.acl_type, l.acl_id, l.memacl_type, l.memacl_id, l.description, TO_CHAR(l.modtime, 'DD-mon-YYYY HH24:MI:SS'), l.modby, l.modwith FROM list l, machine m",
+ glin_fields,
+ 18,
+ "l.name LIKE '%s' AND m.mach_id = l.mailman_id",
+ 1,
+ "l.name",
+ &glin_validate,
+ },
+
{
/* Q_EXLN - EXPAND_LIST_NAMES */
"expand_list_names",
"l",
LIST_TABLE,
"INTO list (name, active, publicflg, hidden, maillist, grouplist, gid, nfsgroup, acl_type, acl_id, memacl_type, memacl_id, description, list_id) VALUES ('%s', %s, %s, %s, %s, %s, %s, %s, '%s', %d, '%s', %d, NVL('%s', CHR(0)), %s)",
- alis_fields,
+ alis4_fields,
13,
0,
0,
NULL,
+ &alis4_validate,
+ },
+
+ {
+ /* Q_ALIS - ADD_LIST, v10 */ /* uses prefetch_value() for list_id */
+ "add_list",
+ "alis",
+ 10,
+ APPEND,
+ "l",
+ LIST_TABLE,
+ "INTO list (name, active, publicflg, hidden, maillist, grouplist, gid, nfsgroup, mailman, mailman_id, acl_type, acl_id, memacl_type, memacl_id, description, list_id) VALUES ('%s', %s, %s, %s, %s, %s, %s, %s, %s, %d, '%s', %d, '%s', %d, NVL('%s', CHR(0)), %s)",
+ alis_fields,
+ 15,
+ 0,
+ 0,
+ NULL,
&alis_validate,
},
"l",
LIST_TABLE,
"list SET name = '%s', active = %s, publicflg = %s, hidden = %s, maillist = %s, grouplist = %s, gid = %s, nfsgroup = %s, acl_type = '%s', acl_id = %d, memacl_type = '%s', memacl_id = %d, description = NVL('%s', CHR(0))",
- ulis_fields,
+ ulis4_fields,
13,
"list_id = %d",
1,
NULL,
+ &ulis4_validate,
+ },
+
+ {
+ /* Q_ULIS, UPDATE_LIST, v10 */
+ "update_list",
+ "ulis",
+ 10,
+ UPDATE,
+ "l",
+ LIST_TABLE,
+ "list SET name = '%s', active = %s, publicflg = %s, hidden = %s, maillist = %s, grouplist = %s, gid = %s, nfsgroup = %s, mailman = %s, mailman_id = %d, acl_type = '%s', acl_id = %d, memacl_type = '%s', memacl_id = %d, description = NVL('%s', CHR(0))",
+ ulis_fields,
+ 15,
+ "list_id = %d",
+ 1,
+ NULL,
&ulis_validate,
},