/* If going from SMTP or NONE to SPLIT, make sure we have a valid
* POP or IMAP box.
*/
- if (!strcmp(potype, "SMTP") || !strcmp(potype, "NONE"))
+ if ((!strcmp(potype, "SMTP") || !strcmp(potype, "NONE")) &&
+ !strcmp(argv[1], "SPLIT"))
{
status = set_pobox_pop(q, argv, cl);
if (status)
* how many different ancestors a member is allowed to have.
*/
-#define MAXLISTDEPTH 1024
+#define MAXLISTDEPTH 2048
int add_member_to_list(struct query *q, char **argv, client *cl)
{
{
EXEC SQL INSERT INTO imembers
(list_id, member_type, member_id, tag, direct, ref_count)
- VALUES (:lid, :mtype, :mid, :tag, 1, 1);
+ VALUES (:lid, :mtype, :mid, :tag, 1, :ref);
}
else
{
EXEC SQL INSERT INTO imembers
(list_id, member_type, member_id, tag, direct, ref_count)
- VALUES (:lid, :mtype, :mid, :tag, 0, 1);
+ VALUES (:lid, :mtype, :mid, :tag, 0, :ref);
}
iargv[0] = (char *)lid;
iargv[1] = mtype;
return MR_SUCCESS;
}
+int tag_member_of_list(struct query *q, char **argv, client *cl)
+{
+ EXEC SQL BEGIN DECLARE SECTION;
+ int lid, mid, cnt, tag;
+ char *mtype;
+ EXEC SQL END DECLARE SECTION;
+ char *iargv[3];
+
+ lid = *(int *)argv[0];
+ mtype = argv[1];
+ mid = *(int *)argv[2];
+ tag = *(int *)argv[3];
+
+ EXEC SQL SELECT COUNT(member_id) INTO :cnt FROM imembers
+ WHERE member_id = :mid AND member_type = :mtype AND
+ list_id = :lid;
+ if (dbms_errno)
+ return mr_errcode;
+ if (cnt == 0)
+ return MR_NO_MATCH;
+
+ incremental_clear_before();
+ EXEC SQL UPDATE imembers SET tag = :tag WHERE list_id = :lid
+ AND member_type = :mtype AND member_id = :mid;
+ if (dbms_errno)
+ return mr_errcode;
+
+ iargv[0] = (char *)lid;
+ iargv[1] = mtype;
+ iargv[2] = (char *)mid;
+ incremental_after(IMEMBERS_TABLE, 0, iargv);
+
+ return MR_SUCCESS;
+}
/* Don't allow someone to add someone to a list which is the acl of a
* query unless they're on the list acl, even if they're on the amtl
int acl_access_check(int list_id, client *cl)
{
EXEC SQL BEGIN DECLARE SECTION;
- int c1, c2, lid = list_id, acl_id;
- char acl_type[LIST_ACL_TYPE_SIZE];
+ int c1, c2, lid = list_id, acl_id, memacl_id;
+ char acl_type[LIST_ACL_TYPE_SIZE], memacl_type[LIST_ACL_TYPE_SIZE];
EXEC SQL END DECLARE SECTION;
/* Check if the list is directly a capacl */
if (cl->proxy_id)
return 1;
- EXEC SQL SELECT acl_type, acl_id INTO :acl_type, :acl_id
+ EXEC SQL SELECT acl_type, acl_id, memacl_type, memacl_id
+ INTO :acl_type, :acl_id, :memacl_type, :memacl_id
FROM list WHERE list_id=:lid;
- return !find_member(acl_type, acl_id, cl);
+
+ if (!find_member(acl_type, acl_id, cl))
+ {
+ if (!find_member(memacl_type, memacl_id, cl))
+ return 1;
+ }
+
+ return 0;
}
rargv[0] = "LIST";
EXEC SQL DECLARE csr113 CURSOR FOR
SELECT name FROM list
- WHERE acl_type = :type AND acl_id = :id;
+ WHERE (acl_type = :type AND acl_id = :id)
+ OR (memacl_type = :type AND memacl_id = :id);
if (dbms_errno)
return mr_errcode;
EXEC SQL OPEN csr113;
WHERE z.xmt_type = :type AND z.xmt_id = :id
OR z.sub_type = :type AND z.sub_id = :id
OR z.iws_type = :type AND z.iws_id = :id
- OR z.iui_type = :type AND z.iui_id = :id;
+ OR z.iui_type = :type AND z.iui_id = :id
+ OR z.owner_type = :type AND z.owner_id = :id;
if (dbms_errno)
return mr_errcode;
EXEC SQL OPEN csr116;
return mr_errcode;
if ((ostatus == 0) || (tmp != users_id))
return MR_IN_USE;
- EXEC SQL SELECT count(potype) INTO :rowcount FROM users WHERE
- login = :login AND potype = 'IMAP';
- if (dbms_errno)
- return mr_errcode;
- if (rowcount > 0)
+ else
po_exists = 1;
}
EXEC SQL SELECT COUNT(name) INTO :rowcount FROM alias
com_err(whoami, 0, "set login name to %s", login);
incremental_after(USERS_TABLE, buffer, 0);
- /* We've just changed the login name in the DB; recache it in case
- the wrong thing got into the cache earlier. */
- cache_entry(login, USERS_TABLE, users_id);
-
/* create filesystem */
if (set_next_object_id("filsys_id", FILESYS_TABLE, 0))
return MR_NO_ID;
return MR_SUCCESS;
}
+
+int update_container(struct query *q, char *argv[], client *cl)
+{
+ EXEC SQL BEGIN DECLARE SECTION;
+ int cnt_id, acl_id, memacl_id, who;
+ char name[CONTAINERS_NAME_SIZE], newchildname[CONTAINERS_NAME_SIZE];
+ char* newname, *entity, *description, *location, *contact, *acl_type, *memacl_type;
+ EXEC SQL END DECLARE SECTION;
+ char* tmpchar;
+ int cnt, childid;
+ char childname[CONTAINERS_NAME_SIZE];
+
+ cnt_id = *(int *)argv[0];
+ newname = argv[1];
+ description = argv[2];
+ location = argv[3];
+ contact = argv[4];
+ acl_type = argv[5];
+ acl_id = *(int *)argv[6];
+ memacl_type = argv[7];
+ memacl_id = *(int *)argv[8];
+ entity = cl->entity;
+ who = cl->client_id;
+
+ EXEC SQL SELECT name INTO :name
+ FROM containers
+ WHERE cnt_id = :cnt_id;
+
+ /* trim off the trailing spaces */
+ strcpy(name, strtrim(name));
+
+ /* if we are renaming the container */
+ if (strcmp(name, newname))
+ {
+ /* make sure that only the name part of the name has been changed */
+ tmpchar = strrchr(name, '/');
+ /* not a top-level name */
+ if (tmpchar)
+ {
+ cnt = tmpchar - name + 1;
+ /* the parent part of the old and new name should be identical */
+ if (strncmp(name, newname, cnt))
+ return MR_NEW_CONTAINER_NAME;
+ }
+ /* top level name, new name should be a top level name too */
+ else
+ {
+ if (strrchr(newname, '/'))
+ return MR_NEW_CONTAINER_NAME;
+ }
+
+ /* update the name for this container */
+ EXEC SQL UPDATE containers
+ SET name = :newname
+ WHERE cnt_id = :cnt_id;
+
+ if (dbms_errno)
+ return mr_errcode;
+
+ /* get names for its child containers */
+ EXEC SQL DECLARE csr_ucon CURSOR FOR
+ SELECT name, cnt_id FROM containers WHERE name LIKE :name || '/' || '%';
+
+ EXEC SQL OPEN csr_ucon;
+ if (dbms_errno)
+ return mr_errcode;
+
+ while (1)
+ {
+ EXEC SQL FETCH csr_ucon INTO :childname, :childid;
+ if (sqlca.sqlcode)
+ break;
+
+ strcpy(childname, strtrim(childname));
+ /* concatenate the new parent name with the existing sub-container name
+ * we get the sub-containers new name */
+ tmpchar = childname + strlen(name);
+ strcpy(newchildname, newname);
+ strcat(newchildname, tmpchar);
+
+ /* update the name */
+ EXEC SQL UPDATE containers
+ SET name = :newchildname, modtime = SYSDATE, modby = :who, modwith = :entity
+ WHERE cnt_id = :childid;
+
+ if (sqlca.sqlcode)
+ break;
+ }
+
+ EXEC SQL CLOSE csr_ucon;
+ if (dbms_errno)
+ return mr_errcode;
+ }
+
+ /* update the remaining fields */
+ EXEC SQL UPDATE containers
+ SET description = NVL(:description, CHR(0)), location = NVL(:location, CHR(0)),
+ contact = NVL(:contact, CHR(0)), acl_type = :acl_type, acl_id = :acl_id,
+ memacl_type = :memacl_type, memacl_id = :memacl_id,
+ modtime = SYSDATE, modby = :who, modwith = :entity
+ WHERE cnt_id = :cnt_id;
+
+ if (dbms_errno)
+ return mr_errcode;
+
+ return MR_SUCCESS;
+}
+
+int get_machines_of_container(struct query *q, char *argv[], client *cl,
+ int (*action)(int, char *[], void *), void *actarg)
+{
+ EXEC SQL BEGIN DECLARE SECTION;
+ int cnt_id, isrecursive;
+ char machinename[MACHINE_NAME_SIZE], containername[CONTAINERS_NAME_SIZE];
+ char *qs;
+ EXEC SQL END DECLARE SECTION;
+
+ char querystring[512], tmp [256];
+ char *rargv[2];
+ int found = 0;
+
+ rargv[0] = machinename;
+ rargv[1] = containername;
+
+ cnt_id = *(int *)argv[0];
+ isrecursive = *(int *)argv[1];
+
+ /* get the container name */
+
+ EXEC SQL SELECT name INTO :containername
+ FROM containers
+ WHERE cnt_id = :cnt_id;
+
+ /* trim off the trailing spaces */
+ strcpy(containername, strtrim(containername));
+
+ strcpy(querystring, "SELECT a.name, b.name FROM machine a, containers b, mcntmap c ");
+ strcat(querystring, "WHERE a.mach_id = c.mach_id AND b.cnt_id = c.cnt_id ");
+
+ if (!isrecursive)
+ sprintf(tmp, "AND b.cnt_id = %d ", cnt_id);
+ else
+ sprintf(tmp, "AND (b.cnt_id = %d OR b.name LIKE '%s/%%') ", cnt_id, containername);
+
+ strcat(querystring, tmp);
+ strcat(querystring, "ORDER BY b.name, a.name");
+
+ qs = querystring;
+
+ EXEC SQL PREPARE stmt FROM :qs;
+ if (sqlca.sqlcode)
+ return MR_INTERNAL;
+ EXEC SQL DECLARE curs_gmnm CURSOR FOR stmt;
+ EXEC SQL OPEN curs_gmnm;
+
+ while (1)
+ {
+ EXEC SQL FETCH curs_gmnm INTO :machinename, :containername;
+ if (sqlca.sqlcode)
+ break;
+ (*action)(2, rargv, actarg);
+ found++;
+ }
+
+ EXEC SQL CLOSE curs_gmnm;
+ if (!found)
+ return MR_NO_MATCH;
+ return MR_SUCCESS;
+}
+
+int get_subcontainers_of_container(struct query *q, char *argv[], client *cl,
+ int (*action)(int, char *[], void *), void *actarg)
+{
+ EXEC SQL BEGIN DECLARE SECTION;
+ int cnt_id, isrecursive;
+ char containername[CONTAINERS_NAME_SIZE], subcontainername[CONTAINERS_NAME_SIZE];
+ char *qs;
+ EXEC SQL END DECLARE SECTION;
+
+ char querystring[512], tmp [256];
+ char *rargv[1];
+ int found = 0;
+
+ rargv[0] = subcontainername;
+
+ cnt_id = *(int *)argv[0];
+ isrecursive = *(int *)argv[1];
+
+ /* get the container name */
+
+ EXEC SQL SELECT name INTO :containername
+ FROM containers
+ WHERE cnt_id = :cnt_id;
+
+ /* trim off the trailing spaces */
+ strcpy(containername, strtrim(containername));
+
+ strcpy(querystring, "SELECT name FROM containers ");
+
+ if (!isrecursive)
+ sprintf(tmp, "WHERE name LIKE '%s/%%' and name NOT LIKE '%s/%%/%%' ", containername,
+ containername);
+ else
+ sprintf(tmp, "WHERE name LIKE '%s/%%' ", containername);
+
+ strcat(querystring, tmp);
+ strcat(querystring, "ORDER BY name");
+
+ qs = querystring;
+
+ EXEC SQL PREPARE stmt FROM :qs;
+ if (sqlca.sqlcode)
+ return MR_INTERNAL;
+ EXEC SQL DECLARE curs_gsoc CURSOR FOR stmt;
+ EXEC SQL OPEN curs_gsoc;
+
+ while (1)
+ {
+ EXEC SQL FETCH curs_gsoc INTO :subcontainername;
+ if (sqlca.sqlcode)
+ break;
+ (*action)(1, rargv, actarg);
+ found++;
+ }
+
+ EXEC SQL CLOSE curs_gsoc;
+ if (!found)
+ return MR_NO_MATCH;
+ return MR_SUCCESS;
+}