Blame SOURCES/mailman-2.1.12-multimail.patch

5c2a97
diff -ruN mailman-2.1.12-a/configure.in mailman-2.1.12-b/configure.in
5c2a97
--- mailman-2.1.12-a/configure.in	2009-02-23 22:23:35.000000000 +0100
5c2a97
+++ mailman-2.1.12-b/configure.in	2009-07-28 12:19:47.000000000 +0200
5c2a97
@@ -249,26 +249,101 @@
5c2a97
 fi
5c2a97
 
5c2a97
 # new macro for finding group names
5c2a97
-AC_DEFUN([MM_FIND_GROUP_NAME], [
5c2a97
+# returns a comma separated list of quoted group names
5c2a97
+# the list is returned in the same order as specified with any duplicates removed
5c2a97
+# the filter flag must be "yes" or "no", e.g. this is permcheck
5c2a97
+#         "no"  ==> none existing groups are not filtered out
5c2a97
+#         "yes" ==> only those groups that are in the group database are included
5c2a97
+#                   in the list
5c2a97
+AC_DEFUN(MM_FIND_GROUP_LIST, [
5c2a97
 # $1 == variable name
5c2a97
-# $2 == user id to check for
5c2a97
+# $2 == white space separated list of groups to check,
5c2a97
+#       list may contain mix of id's and names
5c2a97
+# $3 == filter, if == 'yes' then remove any non-existing groups
5c2a97
 AC_SUBST($1)
5c2a97
 changequote(,)
5c2a97
 if test -z "$$1"
5c2a97
 then
5c2a97
     cat > conftest.py <
5c2a97
 import grp
5c2a97
-gid = ''
5c2a97
+group_names = []
5c2a97
+seen = {}
5c2a97
+filter = "$3"
5c2a97
+
5c2a97
 for group in "$2".split():
5c2a97
     try:
5c2a97
+        gid = int(group)
5c2a97
+        try:
5c2a97
+            gname = grp.getgrgid(gid)[0]
5c2a97
+        except KeyError:
5c2a97
+            gname = ''
5c2a97
+    except ValueError:
5c2a97
         try:
5c2a97
-            gname = grp.getgrgid(int(group))[0]
5c2a97
-            break
5c2a97
-        except ValueError:
5c2a97
             gname = grp.getgrnam(group)[0]
5c2a97
+        except KeyError:
5c2a97
+            if filter == "yes":
5c2a97
+                gname = ''
5c2a97
+            else:
5c2a97
+                gname = group
5c2a97
+    if gname:
5c2a97
+        if gname not in seen:
5c2a97
+            seen[gname] = 1
5c2a97
+            group_names.append(gname)
5c2a97
+
5c2a97
+if group_names:
5c2a97
+    val = '"' + '", "'.join(group_names) + '"'
5c2a97
+    #val = "'"+val+"'"
5c2a97
+else:
5c2a97
+    val = ''
5c2a97
+
5c2a97
+fp = open("conftest.out", "w")
5c2a97
+fp.write("%s\n" % val)
5c2a97
+fp.close()
5c2a97
+EOF
5c2a97
+    $PYTHON conftest.py
5c2a97
+    $1=`cat conftest.out`
5c2a97
+fi
5c2a97
+changequote([, ])
5c2a97
+rm -f conftest.out conftest.py])
5c2a97
+
5c2a97
+
5c2a97
+# new macro for finding group names
5c2a97
+AC_DEFUN(MM_FIND_GROUP_NAME, [
5c2a97
+# Given a list of tokens, either a name or a number (gid)
5c2a97
+# return the first one in the list that is found in the 
5c2a97
+# group database. The return value is always a name, possibly
5c2a97
+# translated from a gid. If permcheck is "no" then the group
5c2a97
+# database is not checked, instead the first token in the list
5c2a97
+# which is a name is returned (e.g. the default value). If permcheck
5c2a97
+# is no and only gid's are in the list then the null string is returned.
5c2a97
+# $1 == variable name
5c2a97
+# $2 == group id to check for
5c2a97
+# $3 == permcheck, either "yes" or "no"
5c2a97
+AC_SUBST($1)
5c2a97
+changequote(,)
5c2a97
+if test -z "$$1"
5c2a97
+then
5c2a97
+    cat > conftest.py <
5c2a97
+import grp
5c2a97
+gname=''
5c2a97
+if "$3" == "yes":
5c2a97
+    for group in "$2".split():
5c2a97
+        try:
5c2a97
+            try:
5c2a97
+                gname = grp.getgrgid(int(group))[0]
5c2a97
+                break
5c2a97
+            except ValueError:
5c2a97
+                gname = grp.getgrnam(group)[0]
5c2a97
+                break
5c2a97
+        except KeyError:
5c2a97
+            gname = ''
5c2a97
+else:
5c2a97
+    for group in "$2".split():
5c2a97
+        try:
5c2a97
+            int(group)
5c2a97
+        except ValueError:
5c2a97
+            gname = group
5c2a97
             break
5c2a97
-    except KeyError:
5c2a97
-        gname = ''
5c2a97
 fp = open("conftest.out", "w")
5c2a97
 fp.write("%s\n" % gname)
5c2a97
 fp.close()
5c2a97
@@ -282,25 +357,41 @@
5c2a97
 
5c2a97
 # new macro for finding UIDs
5c2a97
 AC_DEFUN([MM_FIND_USER_NAME], [
5c2a97
+# Given a list of tokens, either a name or a number (uid)
5c2a97
+# return the first one in the list that is found in the 
5c2a97
+# password database. The return value is always a name, possibly
5c2a97
+# translated from a uid. If permcheck is "no" then the password
5c2a97
+# database is not checked, instead the first token in the list
5c2a97
+# which is a name is returned (e.g. the default value). If permcheck
5c2a97
+# is no and only uid's are in the list then the null string is returned.
5c2a97
 # $1 == variable name
5c2a97
 # $2 == user id to check for
5c2a97
+# $3 == permcheck, either "yes" or "no"
5c2a97
 AC_SUBST($1)
5c2a97
 changequote(,)
5c2a97
 if test -z "$$1"
5c2a97
 then
5c2a97
     cat > conftest.py <
5c2a97
 import pwd
5c2a97
-uid = ''
5c2a97
-for user in "$2".split():
5c2a97
-    try:
5c2a97
+uname=''
5c2a97
+if "$3" == "yes":
5c2a97
+    for user in "$2".split():
5c2a97
         try:
5c2a97
-            uname = pwd.getpwuid(int(user))[0]
5c2a97
-            break
5c2a97
+            try:
5c2a97
+                uname = pwd.getpwuid(int(user))[0]
5c2a97
+                break
5c2a97
+            except ValueError:
5c2a97
+                uname = pwd.getpwnam(user)[0]
5c2a97
+                break
5c2a97
+        except KeyError:
5c2a97
+            uname = ''
5c2a97
+else:
5c2a97
+    for user in "$2".split():
5c2a97
+        try:
5c2a97
+            int(user)
5c2a97
         except ValueError:
5c2a97
-            uname = pwd.getpwnam(user)[0]
5c2a97
+            uname = user
5c2a97
             break
5c2a97
-    except KeyError:
5c2a97
-        uname = ''
5c2a97
 fp = open("conftest.out", "w")
5c2a97
 fp.write("%s\n" % uname)
5c2a97
 fp.close()
5c2a97
@@ -326,7 +417,7 @@
5c2a97
 # User `mailman' must exist
5c2a97
 AC_SUBST(MAILMAN_USER)
5c2a97
 AC_MSG_CHECKING(for user name \"$USERNAME\")
5c2a97
-MM_FIND_USER_NAME(MAILMAN_USER, $USERNAME)
5c2a97
+MM_FIND_USER_NAME(MAILMAN_USER, $USERNAME, $with_permcheck)
5c2a97
 if test -z "$MAILMAN_USER"
5c2a97
 then
5c2a97
   if test "$with_permcheck" = "yes"
5c2a97
@@ -357,7 +448,7 @@
5c2a97
 # Target group must exist
5c2a97
 AC_SUBST(MAILMAN_GROUP)
5c2a97
 AC_MSG_CHECKING(for group name \"$GROUPNAME\")
5c2a97
-MM_FIND_GROUP_NAME(MAILMAN_GROUP, $GROUPNAME)
5c2a97
+MM_FIND_GROUP_NAME(MAILMAN_GROUP, $GROUPNAME, $with_permcheck)
5c2a97
 if test -z "$MAILMAN_GROUP"
5c2a97
 then
5c2a97
   if test "$with_permcheck" = "yes"
5c2a97
@@ -380,11 +471,11 @@
5c2a97
 prefix = "$prefixcheck"
5c2a97
 groupname = "$GROUPNAME"
5c2a97
 mailmangroup = "$MAILMAN_GROUP"
5c2a97
-try:
5c2a97
-    mailmangid = grp.getgrnam(mailmangroup)[2]
5c2a97
-except KeyError:
5c2a97
-    mailmangid = -1
5c2a97
 problems = []
5c2a97
+try: mailmangid = grp.getgrnam(mailmangroup)[2]
5c2a97
+except KeyError:
5c2a97
+    problems.append("group doesn't exist: " + mailmangroup)
5c2a97
+    mailmangid = 41
5c2a97
 try: statdata = os.stat(prefix)
5c2a97
 except OSError:
5c2a97
     problems.append("Directory doesn't exist: " + prefix)
5c2a97
@@ -434,7 +525,7 @@
5c2a97
 then
5c2a97
     with_mail_gid="mailman other mail daemon"
5c2a97
 fi
5c2a97
-MM_FIND_GROUP_NAME(MAIL_GROUP, $with_mail_gid)
5c2a97
+MM_FIND_GROUP_LIST(MAIL_GROUP, $with_mail_gid, $with_permcheck)
5c2a97
 if test -z "$MAIL_GROUP"
5c2a97
 then
5c2a97
   if test "$with_permcheck" = "yes"
5c2a97
@@ -461,7 +552,7 @@
5c2a97
     with_cgi_gid="www www-data nobody"
5c2a97
 fi
5c2a97
 
5c2a97
-MM_FIND_GROUP_NAME(CGI_GROUP, $with_cgi_gid)
5c2a97
+MM_FIND_GROUP_LIST(CGI_GROUP, $with_cgi_gid, $with_permcheck)
5c2a97
 if test -z "$CGI_GROUP"
5c2a97
 then
5c2a97
   if test "$with_permcheck" = "yes"
5c2a97
diff -ruN mailman-2.1.12-a/src/cgi-wrapper.c mailman-2.1.12-b/src/cgi-wrapper.c
5c2a97
--- mailman-2.1.12-a/src/cgi-wrapper.c	2009-02-23 22:23:35.000000000 +0100
5c2a97
+++ mailman-2.1.12-b/src/cgi-wrapper.c	2009-07-28 12:19:47.000000000 +0200
5c2a97
@@ -28,11 +28,11 @@
5c2a97
 /* Group name that CGI scripts run as.  See your web server's documentation
5c2a97
  * for details.
5c2a97
  */
5c2a97
-#define LEGAL_PARENT_GROUP CGI_GROUP
5c2a97
+#define LEGAL_PARENT_GROUPS CGI_GROUP
5c2a97
 
5c2a97
 const char* logident = LOG_IDENT;
5c2a97
 char* script = SCRIPTNAME;
5c2a97
-const char* parentgroup = LEGAL_PARENT_GROUP;
5c2a97
+const char* parentgroups[] = {LEGAL_PARENT_GROUPS};
5c2a97
 
5c2a97
 
5c2a97
 int
5c2a97
@@ -42,7 +42,7 @@
5c2a97
         char* fake_argv[3];
5c2a97
 
5c2a97
         running_as_cgi = 1;
5c2a97
-        check_caller(logident, parentgroup);
5c2a97
+	check_caller(logident, parentgroups, sizeof(parentgroups) / sizeof(parentgroups[0]));
5c2a97
 
5c2a97
         /* For these CGI programs, we can ignore argc and argv since they
5c2a97
          * don't contain anything useful.  `script' will always be the driver
5c2a97
diff -ruN mailman-2.1.12-a/src/common.c mailman-2.1.12-b/src/common.c
5c2a97
--- mailman-2.1.12-a/src/common.c	2009-02-23 22:23:35.000000000 +0100
5c2a97
+++ mailman-2.1.12-b/src/common.c	2009-07-28 12:19:47.000000000 +0200
5c2a97
@@ -117,13 +117,14 @@
5c2a97
 /* Is the parent process allowed to call us?
5c2a97
  */
5c2a97
 void
5c2a97
-check_caller(const char* ident, const char* parentgroup)
5c2a97
+check_caller(const char* ident, const char** parentgroups, size_t numgroups)
5c2a97
 {
5c2a97
         GID_T mygid = getgid();
5c2a97
         struct group *mygroup = getgrgid(mygid);
5c2a97
         char* option;
5c2a97
         char* server;
5c2a97
         char* wrapper;
5c2a97
+	int i;
5c2a97
 
5c2a97
         if (running_as_cgi) {
5c2a97
                 option = "--with-cgi-gid";
5c2a97
@@ -136,28 +137,46 @@
5c2a97
                 wrapper = "mail";
5c2a97
         }
5c2a97
 
5c2a97
-        if (!mygroup)
5c2a97
-                fatal(ident, GROUP_NAME_NOT_FOUND,
5c2a97
-                      "Failure to find group name for GID %d.  Mailman\n"
5c2a97
-                      "expected the %s wrapper to be executed as group\n"
5c2a97
-                      "\"%s\", but the system's %s server executed the\n"
5c2a97
-                      "wrapper as GID %d for which the name could not be\n"
5c2a97
-                      "found.  Try adding GID %d to your system as \"%s\",\n"
5c2a97
-                      "or tweak your %s server to run the wrapper as group\n"
5c2a97
-                      "\"%s\".",
5c2a97
-                      mygid, wrapper, parentgroup, server, mygid, mygid,
5c2a97
-                      parentgroup, server, parentgroup);
5c2a97
+  	if (!mygroup)
5c2a97
+		fatal(ident, GROUP_ID_NOT_FOUND,
5c2a97
+		      "Failure to lookup via getgrgid() the group info for group id %d that this Mailman %s wrapper is executing under.\n"
5c2a97
+		      "This is probably due to an incorrectly configured system and is not a Mailman problem",
5c2a97
+		      mygid, wrapper);
5c2a97
+
5c2a97
+	for (i = 0; i < numgroups; i++) {
5c2a97
+		if (strcmp(parentgroups[i], mygroup->gr_name) == 0) break;
5c2a97
+	}
5c2a97
+
5c2a97
+        if (i >= numgroups) {
5c2a97
+		char *groupset = NULL;
5c2a97
+		size_t size = 0;
5c2a97
+
5c2a97
+		for (i = 0; i < numgroups; i++) {
5c2a97
+			size += strlen(parentgroups[i]) + 2;
5c2a97
+		}
5c2a97
+
5c2a97
+		groupset = malloc(size);
5c2a97
+
5c2a97
+		if (groupset) {
5c2a97
+			groupset[0] = 0;
5c2a97
+			for (i = 0; i < numgroups; i++) {
5c2a97
+				strcat(groupset, parentgroups[i]);
5c2a97
+				if (i < numgroups-1) strcat(groupset, ", ");
5c2a97
+			}
5c2a97
+		}
5c2a97
 
5c2a97
-        if (strcmp(parentgroup, mygroup->gr_name))
5c2a97
                 fatal(ident, GROUP_MISMATCH,
5c2a97
-                      "Group mismatch error.  Mailman expected the %s\n"
5c2a97
-                      "wrapper script to be executed as group \"%s\", but\n"
5c2a97
-                      "the system's %s server executed the %s script as\n"
5c2a97
-                      "group \"%s\".  Try tweaking the %s server to run the\n"
5c2a97
-                      "script as group \"%s\", or re-run configure, \n"
5c2a97
-                      "providing the command line option `%s=%s'.",
5c2a97
-                      wrapper, parentgroup, server, wrapper, mygroup->gr_name,
5c2a97
-                      server, parentgroup, option, mygroup->gr_name);
5c2a97
+		      "Group mismatch error. Mailman expected the %s wrapper script to be\n"
5c2a97
+		      "executed as one of the following groups:\n"
5c2a97
+		      "[%s],\n"
5c2a97
+		      "but the system's %s server executed the %s script as group: \"%s\".\n"
5c2a97
+		      "Try tweaking the %s server to run the script as one of these groups:\n"
5c2a97
+		      "[%s],\n"
5c2a97
+		      "or re-run configure providing the command line option:\n"
5c2a97
+		      "'%s=%s'.",
5c2a97
+		      wrapper, groupset, server, wrapper, mygroup->gr_name,
5c2a97
+		      server, groupset, option, mygroup->gr_name);
5c2a97
+	}
5c2a97
 }
5c2a97
 
5c2a97
 
5c2a97
diff -ruN mailman-2.1.12-a/src/common.h mailman-2.1.12-b/src/common.h
5c2a97
--- mailman-2.1.12-a/src/common.h	2009-02-23 22:23:35.000000000 +0100
5c2a97
+++ mailman-2.1.12-b/src/common.h	2009-07-28 12:19:47.000000000 +0200
5c2a97
@@ -33,7 +33,7 @@
5c2a97
 #define GID_T GETGROUPS_T
5c2a97
 
5c2a97
 extern void fatal(const char*, int, char*, ...);
5c2a97
-extern void check_caller(const char*, const char*);
5c2a97
+extern void check_caller(const char* ident, const char**, size_t);
5c2a97
 extern int run_script(const char*, int, char**, char**);
5c2a97
 
5c2a97
 /* Global variable used as a flag. */
5c2a97
@@ -51,7 +51,7 @@
5c2a97
 #define MAIL_USAGE_ERROR 5
5c2a97
 #define MAIL_ILLEGAL_COMMAND 6
5c2a97
 #define ADDALIAS_USAGE_ERROR 7
5c2a97
-#define GROUP_NAME_NOT_FOUND 8
5c2a97
+#define GROUP_ID_NOT_FOUND 8
5c2a97
 
5c2a97
 
5c2a97
 /*
5c2a97
diff -ruN mailman-2.1.12-a/src/mail-wrapper.c mailman-2.1.12-b/src/mail-wrapper.c
5c2a97
--- mailman-2.1.12-a/src/mail-wrapper.c	2009-02-23 22:23:35.000000000 +0100
5c2a97
+++ mailman-2.1.12-b/src/mail-wrapper.c	2009-07-28 12:19:47.000000000 +0200
5c2a97
@@ -23,9 +23,9 @@
5c2a97
 /* Group name that your mail programs run as.  See your mail server's
5c2a97
  * documentation for details.
5c2a97
  */
5c2a97
-#define LEGAL_PARENT_GROUP MAIL_GROUP
5c2a97
+#define LEGAL_PARENT_GROUPS MAIL_GROUP
5c2a97
 
5c2a97
-const char* parentgroup = LEGAL_PARENT_GROUP;
5c2a97
+const char* parentgroups[] = {LEGAL_PARENT_GROUPS};
5c2a97
 const char* logident = "Mailman mail-wrapper";
5c2a97
 
5c2a97
 
5c2a97
@@ -74,7 +74,7 @@
5c2a97
                 fatal(logident, MAIL_ILLEGAL_COMMAND,
5c2a97
                       "Illegal command: %s", argv[1]);
5c2a97
 
5c2a97
-        check_caller(logident, parentgroup);
5c2a97
+        check_caller(logident, parentgroups, sizeof(parentgroups) / sizeof(parentgroups[0]));
5c2a97
 
5c2a97
         /* If we got here, everything must be OK */
5c2a97
         status = run_script(argv[1], argc, argv, env);
5c2a97
diff -ruN mailman-2.1.12-a/src/Makefile.in mailman-2.1.12-b/src/Makefile.in
5c2a97
--- mailman-2.1.12-a/src/Makefile.in	2009-02-23 22:23:35.000000000 +0100
5c2a97
+++ mailman-2.1.12-b/src/Makefile.in	2009-07-28 12:19:47.000000000 +0200
5c2a97
@@ -49,9 +49,9 @@
5c2a97
 
5c2a97
 SHELL=		/bin/sh
5c2a97
 
5c2a97
-MAIL_FLAGS=	-DMAIL_GROUP="\"$(MAIL_GROUP)\""
5c2a97
+MAIL_FLAGS=	-DMAIL_GROUP='$(MAIL_GROUP)'
5c2a97
 
5c2a97
-CGI_FLAGS=	-DCGI_GROUP="\"$(CGI_GROUP)\""
5c2a97
+CGI_FLAGS=	-DCGI_GROUP='$(CGI_GROUP)'
5c2a97
 
5c2a97
 HELPFUL=	-DHELPFUL
5c2a97