]> andersk Git - moira.git/commitdiff
First cut of mailman support.
authorzacheiss <zacheiss>
Tue, 3 Dec 2002 21:22:26 +0000 (21:22 +0000)
committerzacheiss <zacheiss>
Tue, 3 Dec 2002 21:22:26 +0000 (21:22 +0000)
- New list queries that add mailman and mailman_server arguments.

- Don't let non-dbadmin set mailman bit on a list (this will go away
  when the second tier of features is added).

- Add two arguments to end of incremental argv for benefit of
  mailman.incr.

- Make sure the magic mailman administrative lists (foo-admin,
  foo-request, foo-admin) are treated as reserved if the mailman list
  foo exists.

server/increment.pc
server/qaccess.pc
server/qfollow.pc
server/qsetup.pc
server/queries2.c

index cf30ddda24ee210337c4e2dbea2fc21ba20d42af..7f803aee84b1b0be147d424913e9bcc01af8ff1c 100644 (file)
@@ -197,9 +197,15 @@ void incremental_before(enum tables table, char *qual, char **argv)
     case LIST_TABLE:
       sprintf(stmt_buf, "SELECT l.name, l.active, l.publicflg, l.hidden, "
              "l.maillist, l.grouplist, l.gid, l.acl_type, l.acl_id, "
-             "l.description, l.list_id FROM list l WHERE %s", qual);
+             "l.description, l.list_id, l.mailman, l.mailman_id "
+             "FROM list l WHERE %s", qual);
       dosql(before);
-      beforec = 11;
+      name = xmalloc(0);
+      id = atoi(before[12]);
+      id_to_name(id, MACHINE_TABLE, &name);
+      strcpy(before[12], name);
+      free(name);
+      beforec = 13;
       break;
     case IMEMBERS_TABLE:
       id = (int) argv[0];
@@ -380,9 +386,15 @@ void incremental_after(enum tables table, char *qual, char **argv)
     case LIST_TABLE:
       sprintf(stmt_buf, "SELECT l.name, l.active, l.publicflg, l.hidden, "
              "l.maillist, l.grouplist, l.gid, l.acl_type, l.acl_id, "
-             "l.description, l.list_id FROM list l WHERE %s", qual);
+             "l.description, l.list_id, l.mailman, l.mailman_id "
+             "FROM list l WHERE %s", qual);
       dosql(after);
-      afterc = 11;
+      name = xmalloc(0);
+      id = atoi(after[12]);
+      id_to_name(id, MACHINE_TABLE, &name);
+      strcpy(after[12], name);
+      free(name);
+      afterc = 13;
       break;
     case IMEMBERS_TABLE:
       id = (int) argv[0];
index dd473bc189aed1e1b6925036672fe45ba6b20d96..c80e842609cb19a267e5e359fc1b42b0e5ac3226 100644 (file)
@@ -128,18 +128,18 @@ int access_list(struct query *q, char *argv[], client *cl)
 {
   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;
 
@@ -163,32 +163,41 @@ int access_list(struct query *q, char *argv[], client *cl)
 
       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 
index 24864e60abfdf4b3ea2fc383e77fb272a72ab8d8..3b6becbd75f929d1d34ee282d079af7767823ced 100644 (file)
@@ -606,16 +606,21 @@ int followup_glin(struct query *q, struct save_queue *sq, struct validate *v,
 
       if (q->version == 2)
        status = fix_ace(argv[7], &argv[8]);
-      else 
+      else if (q->version > 2 && q->version < 10)
        status = fix_ace(argv[8], &argv[9]);
+      else
+       status = fix_ace(argv[10], &argv[11]);
+
+      if (status && status != MR_NO_MATCH)
+       return status;
+
+      if (q->version > 3 && q->version < 10)
+       status = fix_ace(argv[10], &argv[11]);
+      else 
+       status = fix_ace(argv[12], &argv[13]); 
+      
       if (status && status != MR_NO_MATCH)
        return status;
-      if (q->version > 3)
-       {
-         status = fix_ace(argv[10], &argv[11]);
-         if (status && status != MR_NO_MATCH)
-           return status;
-       }
 
       if (atoi(argv[6]) == -1)
        {
index 99cd2bbfc4a714eaf3be401ccc70cdb05278cb4f..24431f9fc7545e36cce648d3c3998d5a71a9aa9e 100644 (file)
@@ -36,6 +36,7 @@ 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 */
 
@@ -367,11 +368,11 @@ static int badlistchars[] = {
 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;
@@ -383,8 +384,10 @@ int setup_alis(struct query *q, char *argv[], client *cl)
     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)
     {
@@ -431,6 +434,68 @@ int setup_alis(struct query *q, char *argv[], client *cl)
        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;
 
@@ -1473,3 +1538,27 @@ int setup_acon(struct query *q, char *argv[], client *cl)
   
   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;
+}
index 8277ac01487ab437781a825fd252871406fe07ac..634a401ee4059f7bb13d174f455c685a7dbb82b1 100644 (file)
@@ -1526,13 +1526,20 @@ static char *glin3_fields[] = {
   "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,
@@ -1606,13 +1613,13 @@ static struct validate alis3_validate = {
   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},
@@ -1628,9 +1635,45 @@ static struct valobj alis_valobj[] = {
   {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,
@@ -1705,14 +1748,14 @@ static struct validate ulis3_validate = {
   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},
@@ -1729,9 +1772,47 @@ static struct valobj ulis_valobj[] = {
   {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,
@@ -5226,7 +5307,7 @@ struct query Queries[] = {
     "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,
@@ -5234,6 +5315,23 @@ struct query Queries[] = {
     &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",
@@ -5294,11 +5392,28 @@ struct query Queries[] = {
     "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,
   },
 
@@ -5345,11 +5460,28 @@ struct query Queries[] = {
     "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,
   },
 
This page took 0.78468 seconds and 5 git commands to generate.