1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
|
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).
http://bugzilla.redhat.com/452248
--- spamass-milter.1.in
+++ 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 m
.Op Fl M
@@ -115,6 +116,12 @@ flag.
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.
--- spamass-milter.cpp
+++ spamass-milter.cpp
@@ -89,6 +89,7 @@
#endif
#include <errno.h>
#include <netdb.h>
+#include <grp.h>
// C++ includes
#include <cstdio>
@@ -184,8 +185,9 @@ int
main(int argc, char* argv[])
{
int c, err = 0;
- const char *args = "afd:mMp:P:r:u:D:i:b:B:e:xS:R:C:";
+ const char *args = "afd:mMp:P:r:u:D:i:b:B:e:xS:R:C:g:";
char *sock = NULL;
+ char *group = NULL;
bool dofork = false;
char *pidfilename = NULL;
FILE *pidfile = NULL;
@@ -206,6 +208,9 @@ main(int argc, char* argv[])
case 'f':
dofork = true;
break;
+ case 'g':
+ group = strdup(optarg);
+ break;
case 'd':
parse_debuglevel(optarg);
break;
@@ -298,7 +303,7 @@ main(int argc, char* argv[])
cout << "Usage: spamass-milter -p socket [-b|-B bucket] [-d xx[,yy...]] [-D host]" << endl;
cout << " [-e defaultdomain] [-f] [-i networks] [-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;
@@ -310,6 +315,7 @@ main(int argc, char* argv[])
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 << " -m: don't modify body, Content-type: or Subject:" << endl;
@@ -378,6 +384,30 @@ main(int argc, char* argv[])
} 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);
|