Description: Add option -g group to have the milter create a group-writeable socket for communication with the MTA and set the GID of the socket to the specified group. This makes it possible to use the milter via a unix-domain socket with Postfix as the MTA (Postfix doesn't run as root and would otherwise be unable to use the socket).
Origin: http://bugzilla.redhat.com/452248
Forarded: no
--- a/spamass-milter.1.in
+++ b/spamass-milter.1.in
@@ -14,6 +14,7 @@
 .Op Fl D Ar host
 .Op Fl e Ar defaultdomain
 .Op Fl f
+.Op Fl g Ar group
 .Op Fl i Ar networks
 .Op Fl I
 .Op Fl m
@@ -116,6 +117,12 @@
 Causes
 .Nm
 to fork into the background.
+.It Fl g Ar group
+Makes the socket for communication with the MTA group-writable (mode 0750)
+and sets the socket's group to
+.Ar group .
+This option is intended for use with MTA's like Postfix that do not run as
+root, and is incompatible with Sendmail usage.
 .It Fl i Ar networks
 Ignores messages if the originating IP is in the network(s) listed.
 The message will be passed through without calling SpamAssassin at all.
--- a/spamass-milter.cpp
+++ b/spamass-milter.cpp
@@ -89,6 +89,7 @@
 #endif
 #include <errno.h>
 #include <netdb.h>
+#include <grp.h>
 
 // C++ includes
 #include <cstdio>
@@ -185,8 +186,9 @@
 main(int argc, char* argv[])
 {
    int c, err = 0;
-   const char *args = "afd:mMp:P:r:u:D:i:Ib:B:e:xS:R:C:";
+   const char *args = "afd:mMp:P:r:u:D:i:Ib:B:e:xS:R:C:g:";
    char *sock = NULL;
+   char *group = NULL;
    bool dofork = false;
    char *pidfilename = NULL;
    FILE *pidfile = NULL;
@@ -207,6 +209,9 @@
             case 'f':
                 dofork = true;
                 break;
+            case 'g':
+                group = strdup(optarg);
+                break;
             case 'd':
                 parse_debuglevel(optarg);
                 break;
@@ -303,7 +308,7 @@
       cout << "Usage: spamass-milter -p socket [-b|-B bucket] [-d xx[,yy...]] [-D host]" << endl;
       cout << "                      [-e defaultdomain] [-f] [-i networks] [-I] [-m] [-M]" << endl;
       cout << "                      [-P pidfile] [-r nn] [-u defaultuser] [-x] [-a]" << endl;
-      cout << "                      [-C rejectcode] [ -R rejectmsg ]" << endl;
+      cout << "                      [-C rejectcode] [-R rejectmsg] [-g group]" << endl;
       cout << "                      [-- spamc args ]" << endl;
       cout << "   -p socket: path to create socket" << endl;
       cout << "   -b bucket: redirect spam to this mail address.  The orignal" << endl;
@@ -315,6 +320,7 @@
       cout << "   -e defaultdomain: pass full email address to spamc instead of just\n"
               "          username.  Uses 'defaultdomain' if there was none" << endl;
       cout << "   -f: fork into background" << endl;
+      cout << "   -g group: socket group (perms to 660 as well)" << endl;
       cout << "   -i: skip (ignore) checks from these IPs or netblocks" << endl;
       cout << "          example: -i 192.168.12.5,10.0.0.0/8,172.16.0.0/255.255.0.0" << endl;
       cout << "   -I: skip (ignore) checks if sender is authenticated" << endl;
@@ -384,6 +390,30 @@
 	} else {
       debug(D_MISC, "smfi_register succeeded");
    }
+
+	if (group)
+	{
+		struct group *gr;
+
+		(void) smfi_opensocket(0);
+		gr = getgrnam(group);
+		if (gr)
+		{
+			int rc;
+			rc = chown(sock, (uid_t)-1, gr->gr_gid);
+			if (!rc)
+			{
+				(void) chmod(sock, 0660);
+			} else {
+				perror("group option, chown");
+				exit(EX_NOPERM);
+			}
+		} else { 
+			perror("group option, getgrnam");
+			exit(EX_NOUSER);
+		}
+	}
+
 	debug(D_ALWAYS, "spamass-milter %s starting", PACKAGE_VERSION);
 	err = smfi_main();
 	debug(D_ALWAYS, "spamass-milter %s exiting", PACKAGE_VERSION);
