/[smecontribs]/rpms/mailman/contribs7/mailman-2.1-multimail.patch
ViewVC logotype

Contents of /rpms/mailman/contribs7/mailman-2.1-multimail.patch

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.3 - (show annotations) (download)
Tue Nov 25 16:20:13 2008 UTC (15 years, 11 months ago) by slords
Branch: MAIN
CVS Tags: HEAD
Changes since 1.2: +0 -0 lines
Error occurred while calculating annotation data.
Restore

1 Mailman security is in part enforced by requiring it execute
2 SGID. When the mail process or the web server attempts to execute a
3 mailman script a C program is invoked to verify the group
4 permission. Mailman as it is shipped only allows one group to be
5 specified at build time. For users who build and install on their own
6 machine this is not a limitation. However, when making a binary
7 package to be installed on an arbitrary machine it is hard to predict
8 the correct group to use for that installation. Therefore this patch
9 allows us to specify at build time a list of groups that will be
10 iterated over, if the mailman process is executing as any of one of
11 the group in the set of groups then the permission check passes. Since
12 the groups we build with are limited to a small number of safe groups
13 this does not lower the security much while at the same time provides
14 a much more friendly way to package a binary installation that will
15 run in a wider range of installations.
16
17 It was necessary to add the macro MM_FIND_GROUP_LIST to the
18 configure.in file replacing the original use of MM_FIND_GROUP_NAME,
19 the former operates on a list of group names while the later on a
20 single name. MM_FIND_GROUP_LIST includes a filter parameter that was
21 added with the notion of supporting the with-permcheck option. If
22 filter is true then only group names that exist on the build machine
23 are permitted in the list, otherwise all names are permitted. However,
24 note that whenever MM_FIND_GROUP_LIST is invoked it is currently
25 hardcoded to disable filtering and is not tied to with-permcheck, this
26 was done because of the observation that if one is passing a list of
27 groups it is likely one is doing so to support installations that have
28 a group not present on the build machine, but one might still want to
29 take advantage of the other with-permcheck functionality.
30
31 diff -u mailman-2.1.2/configure.in.orig mailman-2.1.2/configure.in
32 --- mailman-2.1.2/configure.in.orig 2003-04-21 23:34:51.000000000 -0400
33 +++ mailman-2.1.2/configure.in 2003-05-02 16:32:45.000000000 -0400
34 @@ -208,26 +208,101 @@
35 fi
36
37 # new macro for finding group names
38 -AC_DEFUN(MM_FIND_GROUP_NAME, [
39 +# returns a comma separated list of quoted group names
40 +# the list is returned in the same order as specified with any duplicates removed
41 +# the filter flag must be "yes" or "no", e.g. this is permcheck
42 +# "no" ==> none existing groups are not filtered out
43 +# "yes" ==> only those groups that are in the group database are included
44 +# in the list
45 +AC_DEFUN(MM_FIND_GROUP_LIST, [
46 # $1 == variable name
47 -# $2 == user id to check for
48 +# $2 == white space separated list of groups to check,
49 +# list may contain mix of id's and names
50 +# $3 == filter, if == 'yes' then remove any non-existing groups
51 AC_SUBST($1)
52 changequote(,)
53 if test -z "$$1"
54 then
55 cat > conftest.py <<EOF
56 import grp
57 -gid = ''
58 +group_names = []
59 +seen = {}
60 +filter = "$3"
61 +
62 for group in "$2".split():
63 try:
64 + gid = int(group)
65 + try:
66 + gname = grp.getgrgid(gid)[0]
67 + except KeyError:
68 + gname = ''
69 + except ValueError:
70 try:
71 - gname = grp.getgrgid(int(group))[0]
72 - break
73 - except ValueError:
74 gname = grp.getgrnam(group)[0]
75 + except KeyError:
76 + if filter == "yes":
77 + gname = ''
78 + else:
79 + gname = group
80 + if gname:
81 + if gname not in seen:
82 + seen[gname] = 1
83 + group_names.append(gname)
84 +
85 +if group_names:
86 + val = '"' + '", "'.join(group_names) + '"'
87 + #val = "'"+val+"'"
88 +else:
89 + val = ''
90 +
91 +fp = open("conftest.out", "w")
92 +fp.write("%s\n" % val)
93 +fp.close()
94 +EOF
95 + $PYTHON conftest.py
96 + $1=`cat conftest.out`
97 +fi
98 +changequote([, ])
99 +rm -f conftest.out conftest.py])
100 +
101 +
102 +# new macro for finding group names
103 +AC_DEFUN(MM_FIND_GROUP_NAME, [
104 +# Given a list of tokens, either a name or a number (gid)
105 +# return the first one in the list that is found in the
106 +# group database. The return value is always a name, possibly
107 +# translated from a gid. If permcheck is "no" then the group
108 +# database is not checked, instead the first token in the list
109 +# which is a name is returned (e.g. the default value). If permcheck
110 +# is no and only gid's are in the list then the null string is returned.
111 +# $1 == variable name
112 +# $2 == group id to check for
113 +# $3 == permcheck, either "yes" or "no"
114 +AC_SUBST($1)
115 +changequote(,)
116 +if test -z "$$1"
117 +then
118 + cat > conftest.py <<EOF
119 +import grp
120 +gname=''
121 +if "$3" == "yes":
122 + for group in "$2".split():
123 + try:
124 + try:
125 + gname = grp.getgrgid(int(group))[0]
126 + break
127 + except ValueError:
128 + gname = grp.getgrnam(group)[0]
129 + break
130 + except KeyError:
131 + gname = ''
132 +else:
133 + for group in "$2".split():
134 + try:
135 + int(group)
136 + except ValueError:
137 + gname = group
138 break
139 - except KeyError:
140 - gname = ''
141 fp = open("conftest.out", "w")
142 fp.write("%s\n" % gname)
143 fp.close()
144 @@ -241,25 +316,41 @@
145
146 # new macro for finding UIDs
147 AC_DEFUN(MM_FIND_USER_NAME, [
148 +# Given a list of tokens, either a name or a number (uid)
149 +# return the first one in the list that is found in the
150 +# password database. The return value is always a name, possibly
151 +# translated from a uid. If permcheck is "no" then the password
152 +# database is not checked, instead the first token in the list
153 +# which is a name is returned (e.g. the default value). If permcheck
154 +# is no and only uid's are in the list then the null string is returned.
155 # $1 == variable name
156 # $2 == user id to check for
157 +# $3 == permcheck, either "yes" or "no"
158 AC_SUBST($1)
159 changequote(,)
160 if test -z "$$1"
161 then
162 cat > conftest.py <<EOF
163 import pwd
164 -uid = ''
165 -for user in "$2".split():
166 - try:
167 +uname=''
168 +if "$3" == "yes":
169 + for user in "$2".split():
170 try:
171 - uname = pwd.getpwuid(int(user))[0]
172 - break
173 + try:
174 + uname = pwd.getpwuid(int(user))[0]
175 + break
176 + except ValueError:
177 + uname = pwd.getpwnam(user)[0]
178 + break
179 + except KeyError:
180 + uname = ''
181 +else:
182 + for user in "$2".split():
183 + try:
184 + int(user)
185 except ValueError:
186 - uname = pwd.getpwnam(user)[0]
187 + uname = user
188 break
189 - except KeyError:
190 - uname = ''
191 fp = open("conftest.out", "w")
192 fp.write("%s\n" % uname)
193 fp.close()
194 @@ -285,7 +376,7 @@
195 # User `mailman' must exist
196 AC_SUBST(MAILMAN_USER)
197 AC_MSG_CHECKING(for user name \"$USERNAME\")
198 -MM_FIND_USER_NAME(MAILMAN_USER, $USERNAME)
199 +MM_FIND_USER_NAME(MAILMAN_USER, $USERNAME, $with_permcheck)
200 if test -z "$MAILMAN_USER"
201 then
202 if test "$with_permcheck" = "yes"
203 @@ -316,7 +407,7 @@
204 # Target group must exist
205 AC_SUBST(MAILMAN_GROUP)
206 AC_MSG_CHECKING(for group name \"$GROUPNAME\")
207 -MM_FIND_GROUP_NAME(MAILMAN_GROUP, $GROUPNAME)
208 +MM_FIND_GROUP_NAME(MAILMAN_GROUP, $GROUPNAME, $with_permcheck)
209 if test -z "$MAILMAN_GROUP"
210 then
211 if test "$with_permcheck" = "yes"
212 @@ -339,11 +430,11 @@
213 prefix = "$prefixcheck"
214 groupname = "$GROUPNAME"
215 mailmangroup = "$MAILMAN_GROUP"
216 -try:
217 - mailmangid = grp.getgrnam(mailmangroup)[2]
218 -except KeyError:
219 - mailmangid = -1
220 problems = []
221 +try: mailmangid = grp.getgrnam(mailmangroup)[2]
222 +except KeyError:
223 + problems.append("group doesn't exist: " + mailmangroup)
224 + mailmangid = 41
225 try: statdata = os.stat(prefix)
226 except OSError:
227 problems.append("Directory doesn't exist: " + prefix)
228 @@ -393,7 +484,7 @@
229 then
230 with_mail_gid="mailman other mail daemon"
231 fi
232 -MM_FIND_GROUP_NAME(MAIL_GROUP, $with_mail_gid)
233 +MM_FIND_GROUP_LIST(MAIL_GROUP, $with_mail_gid, $with_permcheck)
234 if test -z "$MAIL_GROUP"
235 then
236 if test "$with_permcheck" = "yes"
237 @@ -420,7 +511,7 @@
238 with_cgi_gid="www www-data nobody"
239 fi
240
241 -MM_FIND_GROUP_NAME(CGI_GROUP, $with_cgi_gid)
242 +MM_FIND_GROUP_LIST(CGI_GROUP, $with_cgi_gid, $with_permcheck)
243 if test -z "$CGI_GROUP"
244 then
245 if test "$with_permcheck" = "yes"
246 diff -u mailman-2.1.2/src/cgi-wrapper.c.orig mailman-2.1.2/src/cgi-wrapper.c
247 --- mailman-2.1.2/src/cgi-wrapper.c.orig 2002-08-23 16:39:47.000000000 -0400
248 +++ mailman-2.1.2/src/cgi-wrapper.c 2003-05-02 16:28:11.000000000 -0400
249 @@ -28,11 +28,11 @@
250 /* Group name that CGI scripts run as. See your web server's documentation
251 * for details.
252 */
253 -#define LEGAL_PARENT_GROUP CGI_GROUP
254 +#define LEGAL_PARENT_GROUPS CGI_GROUP
255
256 const char* logident = LOG_IDENT;
257 char* script = SCRIPTNAME;
258 -const char* parentgroup = LEGAL_PARENT_GROUP;
259 +const char* parentgroups[] = {LEGAL_PARENT_GROUPS};
260
261
262 int
263 @@ -42,7 +42,7 @@
264 char* fake_argv[3];
265
266 running_as_cgi = 1;
267 - check_caller(logident, parentgroup);
268 + check_caller(logident, parentgroups, sizeof(parentgroups) / sizeof(parentgroups[0]));
269
270 /* For these CGI programs, we can ignore argc and argv since they
271 * don't contain anything useful. `script' will always be the driver
272 diff -u mailman-2.1.2/src/common.c.orig mailman-2.1.2/src/common.c
273 --- mailman-2.1.2/src/common.c.orig 2002-09-04 21:29:57.000000000 -0400
274 +++ mailman-2.1.2/src/common.c 2003-05-02 16:28:11.000000000 -0400
275 @@ -116,13 +116,14 @@
276 /* Is the parent process allowed to call us?
277 */
278 void
279 -check_caller(const char* ident, const char* parentgroup)
280 +check_caller(const char* ident, const char** parentgroups, size_t numgroups)
281 {
282 GID_T mygid = getgid();
283 struct group *mygroup = getgrgid(mygid);
284 char* option;
285 char* server;
286 char* wrapper;
287 + int i;
288
289 if (running_as_cgi) {
290 option = "--with-cgi-gid";
291 @@ -136,22 +137,45 @@
292 }
293
294 if (!mygroup)
295 - fatal(ident, GROUP_NAME_NOT_FOUND,
296 - "Failure to find group name %s. Try adding this group\n"
297 - "to your system, or re-run configure, providing an\n"
298 - "existing group name with the command line option %s.",
299 - parentgroup, option);
300 + fatal(ident, GROUP_ID_NOT_FOUND,
301 + "Failure to lookup via getgrgid() the group info for group id %d that this Mailman %s wrapper is executing under.\n"
302 + "This is probably due to an incorrectly configured system and is not a Mailman problem",
303 + mygid, wrapper);
304 +
305 + for (i = 0; i < numgroups; i++) {
306 + if (strcmp(parentgroups[i], mygroup->gr_name) == 0) break;
307 + }
308 +
309 + if (i >= numgroups) {
310 + char *groupset = NULL;
311 + size_t size = 0;
312 +
313 + for (i = 0; i < numgroups; i++) {
314 + size += strlen(parentgroups[i]) + 2;
315 + }
316 +
317 + groupset = malloc(size);
318 +
319 + if (groupset) {
320 + groupset[0] = 0;
321 + for (i = 0; i < numgroups; i++) {
322 + strcat(groupset, parentgroups[i]);
323 + if (i < numgroups-1) strcat(groupset, ", ");
324 + }
325 + }
326
327 - if (strcmp(parentgroup, mygroup->gr_name))
328 fatal(ident, GROUP_MISMATCH,
329 - "Group mismatch error. Mailman expected the %s\n"
330 - "wrapper script to be executed as group \"%s\", but\n"
331 - "the system's %s server executed the %s script as\n"
332 - "group \"%s\". Try tweaking the %s server to run the\n"
333 - "script as group \"%s\", or re-run configure, \n"
334 - "providing the command line option `%s=%s'.",
335 - wrapper, parentgroup, server, wrapper, mygroup->gr_name,
336 - server, parentgroup, option, mygroup->gr_name);
337 + "Group mismatch error. Mailman expected the %s wrapper script to be\n"
338 + "executed as one of the following groups:\n"
339 + "[%s],\n"
340 + "but the system's %s server executed the %s script as group: \"%s\".\n"
341 + "Try tweaking the %s server to run the script as one of these groups:\n"
342 + "[%s],\n"
343 + "or re-run configure providing the command line option:\n"
344 + "'%s=%s'.",
345 + wrapper, groupset, server, wrapper, mygroup->gr_name,
346 + server, groupset, option, mygroup->gr_name);
347 + }
348 }
349
350
351 diff -u mailman-2.1.2/src/common.h.orig mailman-2.1.2/src/common.h
352 --- mailman-2.1.2/src/common.h.orig 2002-10-21 14:48:03.000000000 -0400
353 +++ mailman-2.1.2/src/common.h 2003-05-02 16:28:11.000000000 -0400
354 @@ -33,7 +33,7 @@
355 #define GID_T GETGROUPS_T
356
357 extern void fatal(const char*, int, char*, ...);
358 -extern void check_caller(const char*, const char*);
359 +extern void check_caller(const char* ident, const char**, size_t);
360 extern int run_script(const char*, int, char**, char**);
361
362 /* Global variable used as a flag. */
363 @@ -51,7 +51,7 @@
364 #define MAIL_USAGE_ERROR 5
365 #define MAIL_ILLEGAL_COMMAND 6
366 #define ADDALIAS_USAGE_ERROR 7
367 -#define GROUP_NAME_NOT_FOUND 8
368 +#define GROUP_ID_NOT_FOUND 8
369
370
371 /*
372 diff -u mailman-2.1.2/src/mail-wrapper.c.orig mailman-2.1.2/src/mail-wrapper.c
373 --- mailman-2.1.2/src/mail-wrapper.c.orig 2002-08-23 16:40:27.000000000 -0400
374 +++ mailman-2.1.2/src/mail-wrapper.c 2003-05-02 16:28:11.000000000 -0400
375 @@ -23,9 +23,9 @@
376 /* Group name that your mail programs run as. See your mail server's
377 * documentation for details.
378 */
379 -#define LEGAL_PARENT_GROUP MAIL_GROUP
380 +#define LEGAL_PARENT_GROUPS MAIL_GROUP
381
382 -const char* parentgroup = LEGAL_PARENT_GROUP;
383 +const char* parentgroups[] = {LEGAL_PARENT_GROUPS};
384 const char* logident = "Mailman mail-wrapper";
385
386
387 @@ -74,7 +74,7 @@
388 fatal(logident, MAIL_ILLEGAL_COMMAND,
389 "Illegal command: %s", argv[1]);
390
391 - check_caller(logident, parentgroup);
392 + check_caller(logident, parentgroups, sizeof(parentgroups) / sizeof(parentgroups[0]));
393
394 /* If we got here, everything must be OK */
395 status = run_script(argv[1], argc, argv, env);
396 diff -u mailman-2.1.2/src/Makefile.in.orig mailman-2.1.2/src/Makefile.in
397 --- mailman-2.1.2/src/Makefile.in.orig 2003-03-31 14:27:14.000000000 -0500
398 +++ mailman-2.1.2/src/Makefile.in 2003-05-02 16:28:11.000000000 -0400
399 @@ -49,9 +49,9 @@
400
401 SHELL= /bin/sh
402
403 -MAIL_FLAGS= -DMAIL_GROUP="\"$(MAIL_GROUP)\""
404 +MAIL_FLAGS= -DMAIL_GROUP='$(MAIL_GROUP)'
405
406 -CGI_FLAGS= -DCGI_GROUP="\"$(CGI_GROUP)\""
407 +CGI_FLAGS= -DCGI_GROUP='$(CGI_GROUP)'
408
409 HELPFUL= -DHELPFUL
410

admin@koozali.org
ViewVC Help
Powered by ViewVC 1.2.1 RSS 2.0 feed