Import rpm: be748fff6a6b044ba3f9e9264defbe13572d3747

This commit is contained in:
James Antill 2022-08-08 12:40:40 -04:00
commit 17891ed6af
28 changed files with 4193 additions and 0 deletions

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
SOURCES/mailman-2.1.29.tgz

24
httpd-mailman.conf Normal file
View File

@ -0,0 +1,24 @@
#
# httpd configuration settings for use with mailman.
#
ScriptAlias /mailman/ @MMDIR@/cgi-bin/
<Directory @MMDIR@/cgi-bin/>
AllowOverride None
Options ExecCGI
Require all granted
</Directory>
Alias /pipermail/ @VARMMDIR@/archives/public/
<Directory @VARMMDIR@/archives/public>
Options MultiViews FollowSymLinks
AllowOverride None
Require all granted
AddDefaultCharset Off
</Directory>
# Uncomment the following line, replacing www.example.com with your server's
# name, to redirect queries to /mailman to the listinfo page (recommended).
# RedirectMatch ^/mailman[/]*$ http://www.example.com/mailman/listinfo

715
mailman-2.1-build.patch Normal file
View File

@ -0,0 +1,715 @@
diff --git a/Mailman/Archiver/Makefile.in b/Mailman/Archiver/Makefile.in
index 65e46cb..dc3a1c6 100644
--- a/Mailman/Archiver/Makefile.in
+++ b/Mailman/Archiver/Makefile.in
@@ -28,7 +28,6 @@ exec_prefix= @exec_prefix@
DESTDIR=
CC= @CC@
-CHMOD= @CHMOD@
INSTALL= @INSTALL@
DEFS= @DEFS@
@@ -47,7 +46,7 @@ pipermail.py
# Modes for directories and executables created by the install
# process. Default to group-writable directories but
# user-only-writable for executables.
-DIRMODE= 775
+DIRMODE= 2775
EXEMODE= 755
FILEMODE= 644
INSTALL_PROGRAM=$(INSTALL) -m $(EXEMODE)
@@ -63,8 +62,6 @@ install:
$(INSTALL) -m $(FILEMODE) $(srcdir)/$$f $(DESTDIR)$(PACKAGEDIR); \
done
-finish:
-
clean:
distclean:
diff --git a/Mailman/Bouncers/Makefile.in b/Mailman/Bouncers/Makefile.in
index 8865a9f..8878cd9 100644
--- a/Mailman/Bouncers/Makefile.in
+++ b/Mailman/Bouncers/Makefile.in
@@ -28,7 +28,6 @@ exec_prefix= @exec_prefix@
DESTDIR=
CC= @CC@
-CHMOD= @CHMOD@
INSTALL= @INSTALL@
DEFS= @DEFS@
@@ -45,7 +44,7 @@ MODULES= *.py
# Modes for directories and executables created by the install
# process. Default to group-writable directories but
# user-only-writable for executables.
-DIRMODE= 775
+DIRMODE= 2775
EXEMODE= 755
FILEMODE= 644
INSTALL_PROGRAM=$(INSTALL) -m $(EXEMODE)
@@ -61,8 +60,6 @@ install:
$(INSTALL) -m $(FILEMODE) $(srcdir)/$$f $(DESTDIR)$(PACKAGEDIR); \
done
-finish:
-
clean:
distclean:
diff --git a/Mailman/Cgi/Makefile.in b/Mailman/Cgi/Makefile.in
index 47929e9..e20c07e 100644
--- a/Mailman/Cgi/Makefile.in
+++ b/Mailman/Cgi/Makefile.in
@@ -28,7 +28,6 @@ exec_prefix= @exec_prefix@
DESTDIR=
CC= @CC@
-CHMOD= @CHMOD@
INSTALL= @INSTALL@
DEFS= @DEFS@
@@ -47,7 +46,7 @@ CGI_MODULES= *.py
# Modes for directories and executables created by the install
# process. Default to group-writable directories but
# user-only-writable for executables.
-DIRMODE= 775
+DIRMODE= 2775
EXEMODE= 755
FILEMODE= 644
INSTALL_PROGRAM=$(INSTALL) -m $(EXEMODE)
@@ -63,8 +62,6 @@ install:
$(INSTALL) -m $(FILEMODE) $(srcdir)/$$f $(DESTDIR)$(CGIDIR); \
done
-finish:
-
clean:
distclean:
diff --git a/Mailman/Commands/Makefile.in b/Mailman/Commands/Makefile.in
index 645d78b..12bbc1b 100644
--- a/Mailman/Commands/Makefile.in
+++ b/Mailman/Commands/Makefile.in
@@ -28,7 +28,6 @@ exec_prefix= @exec_prefix@
DESTDIR=
CC= @CC@
-CHMOD= @CHMOD@
INSTALL= @INSTALL@
DEFS= @DEFS@
@@ -45,7 +44,7 @@ MODULES= *.py
# Modes for directories and executables created by the install
# process. Default to group-writable directories but
# user-only-writable for executables.
-DIRMODE= 775
+DIRMODE= 2775
EXEMODE= 755
FILEMODE= 644
INSTALL_PROGRAM=$(INSTALL) -m $(EXEMODE)
@@ -61,8 +60,6 @@ install:
$(INSTALL) -m $(FILEMODE) $(srcdir)/$$f $(DESTDIR)$(PACKAGEDIR); \
done
-finish:
-
clean:
distclean:
diff --git a/Mailman/Gui/Makefile.in b/Mailman/Gui/Makefile.in
index 000441e..9273b8a 100644
--- a/Mailman/Gui/Makefile.in
+++ b/Mailman/Gui/Makefile.in
@@ -28,7 +28,6 @@ exec_prefix= @exec_prefix@
DESTDIR=
CC= @CC@
-CHMOD= @CHMOD@
INSTALL= @INSTALL@
DEFS= @DEFS@
@@ -45,7 +44,7 @@ MODULES= *.py
# Modes for directories and executables created by the install
# process. Default to group-writable directories but
# user-only-writable for executables.
-DIRMODE= 775
+DIRMODE= 2775
EXEMODE= 755
FILEMODE= 644
INSTALL_PROGRAM=$(INSTALL) -m $(EXEMODE)
@@ -61,8 +60,6 @@ install:
$(INSTALL) -m $(FILEMODE) $(srcdir)/$$f $(DESTDIR)$(PACKAGEDIR); \
done
-finish:
-
clean:
distclean:
diff --git a/Mailman/Handlers/Makefile.in b/Mailman/Handlers/Makefile.in
index 71e5576..56ee2eb 100644
--- a/Mailman/Handlers/Makefile.in
+++ b/Mailman/Handlers/Makefile.in
@@ -28,7 +28,6 @@ exec_prefix= @exec_prefix@
DESTDIR=
CC= @CC@
-CHMOD= @CHMOD@
INSTALL= @INSTALL@
DEFS= @DEFS@
@@ -45,7 +44,7 @@ MODULES= *.py
# Modes for directories and executables created by the install
# process. Default to group-writable directories but
# user-only-writable for executables.
-DIRMODE= 775
+DIRMODE= 2775
EXEMODE= 755
FILEMODE= 644
INSTALL_PROGRAM=$(INSTALL) -m $(EXEMODE)
@@ -61,8 +60,6 @@ install:
$(INSTALL) -m $(FILEMODE) $(srcdir)/$$f $(DESTDIR)$(PACKAGEDIR); \
done
-finish:
-
clean:
distclean:
diff --git a/Mailman/Logging/Makefile.in b/Mailman/Logging/Makefile.in
index e185775..ad5c128 100644
--- a/Mailman/Logging/Makefile.in
+++ b/Mailman/Logging/Makefile.in
@@ -28,7 +28,6 @@ exec_prefix= @exec_prefix@
DESTDIR=
CC= @CC@
-CHMOD= @CHMOD@
INSTALL= @INSTALL@
DEFS= @DEFS@
@@ -45,7 +44,7 @@ MODULES= *.py
# Modes for directories and executables created by the install
# process. Default to group-writable directories but
# user-only-writable for executables.
-DIRMODE= 775
+DIRMODE= 2775
EXEMODE= 755
FILEMODE= 644
INSTALL_PROGRAM=$(INSTALL) -m $(EXEMODE)
@@ -61,8 +60,6 @@ install:
$(INSTALL) -m $(FILEMODE) $(srcdir)/$$f $(DESTDIR)$(PACKAGEDIR); \
done
-finish:
-
clean:
distclean:
diff --git a/Mailman/MTA/Makefile.in b/Mailman/MTA/Makefile.in
index 0338806..e1de296 100644
--- a/Mailman/MTA/Makefile.in
+++ b/Mailman/MTA/Makefile.in
@@ -28,7 +28,6 @@ exec_prefix= @exec_prefix@
DESTDIR=
CC= @CC@
-CHMOD= @CHMOD@
INSTALL= @INSTALL@
DEFS= @DEFS@
@@ -45,7 +44,7 @@ MODULES= *.py
# Modes for directories and executables created by the install
# process. Default to group-writable directories but
# user-only-writable for executables.
-DIRMODE= 775
+DIRMODE= 2775
EXEMODE= 755
FILEMODE= 644
INSTALL_PROGRAM=$(INSTALL) -m $(EXEMODE)
@@ -61,8 +60,6 @@ install:
$(INSTALL) -m $(FILEMODE) $(srcdir)/$$f $(DESTDIR)$(PACKAGEDIR); \
done
-finish:
-
clean:
distclean:
diff --git a/Mailman/Makefile.in b/Mailman/Makefile.in
index 93c7efd..45439f0 100644
--- a/Mailman/Makefile.in
+++ b/Mailman/Makefile.in
@@ -20,8 +20,6 @@
# Variables set by configure
-VERSION= @VERSION@
-
VPATH= @srcdir@
srcdir= @srcdir@
bindir= @bindir@
@@ -30,7 +28,6 @@ exec_prefix= @exec_prefix@
DESTDIR=
CC= @CC@
-CHMOD= @CHMOD@
INSTALL= @INSTALL@
DEFS= @DEFS@
@@ -48,7 +45,7 @@ SUBDIRS= Cgi Logging Archiver Handlers Bouncers Queue MTA Gui Commands
# Modes for directories and executables created by the install
# process. Default to group-writable directories but
# user-only-writable for executables.
-DIRMODE= 775
+DIRMODE= 2775
EXEMODE= 755
FILEMODE= 644
INSTALL_PROGRAM=$(INSTALL) -m $(EXEMODE)
@@ -79,12 +76,6 @@ install: install-here
(cd $$d; $(MAKE) DESTDIR=$(DESTDIR) install); \
done
-finish:
- @for d in $(SUBDIRS); \
- do \
- (cd $$d; $(MAKE) DESTDIR=$(DESTDIR) finish); \
- done
-
clean:
for d in $(SUBDIRS); \
do \
diff --git a/Mailman/Queue/Makefile.in b/Mailman/Queue/Makefile.in
index 179f3d9..e0e97ad 100644
--- a/Mailman/Queue/Makefile.in
+++ b/Mailman/Queue/Makefile.in
@@ -28,7 +28,6 @@ exec_prefix= @exec_prefix@
DESTDIR=
CC= @CC@
-CHMOD= @CHMOD@
INSTALL= @INSTALL@
DEFS= @DEFS@
@@ -45,7 +44,7 @@ MODULES= *.py
# Modes for directories and executables created by the install
# process. Default to group-writable directories but
# user-only-writable for executables.
-DIRMODE= 775
+DIRMODE= 2775
EXEMODE= 755
FILEMODE= 644
INSTALL_PROGRAM=$(INSTALL) -m $(EXEMODE)
@@ -61,8 +60,6 @@ install:
$(INSTALL) -m $(FILEMODE) $(srcdir)/$$f $(DESTDIR)$(PACKAGEDIR); \
done
-finish:
-
clean:
distclean:
diff --git a/Makefile.in b/Makefile.in
index 40e04f5..eb40844 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -61,11 +61,10 @@ SUBDIRS= bin cron misc Mailman scripts src templates messages tests
# Modes for directories and executables created by the install
# process. Default to group-writable directories but
# user-only-writable for executables.
-DIRMODE= 775
+DIRMODE= 2775
EXEMODE= 755
FILEMODE= 644
INSTALL_PROGRAM=$(INSTALL) -m $(EXEMODE)
-DIRSETGID= chmod g+s
DATE = $(shell python -c 'import time; print time.strftime("%d-%b-%Y"),')
LANGPACK = README-I18N.en templates messages
@@ -85,14 +84,24 @@ install: doinstall update
doinstall: $(SUBDIRS)
@echo "Creating architecture independent directories..."
+ dir=$(DESTDIR)$(prefix); \
+ if test ! -d $$dir; then \
+ echo "Creating directory hierarchy $$dir"; \
+ $(INSTALL) -d -m $(DIRMODE) $$dir; \
+ else true; \
+ fi;
+ dir=$(DESTDIR)$(var_prefix); \
+ if test ! -d $$dir; then \
+ echo "Creating directory hierarchy $$dir"; \
+ $(INSTALL) -d -m $(DIRMODE) $$dir; \
+ else true; \
+ fi;
@for d in $(VAR_DIRS); \
do \
dir=$(DESTDIR)$(var_prefix)/$$d; \
if test ! -d $$dir; then \
echo "Creating directory hierarchy $$dir"; \
- $(srcdir)/mkinstalldirs $$dir; \
- chmod $(DIRMODE) $$dir; \
- $(DIRSETGID) $$dir; \
+ $(INSTALL) -d -m $(DIRMODE) $$dir; \
else true; \
fi; \
done
@@ -102,9 +111,7 @@ doinstall: $(SUBDIRS)
dir=$(DESTDIR)$(prefix)/$$d; \
if test ! -d $$dir; then \
echo "Creating directory hierarchy $$dir"; \
- $(srcdir)/mkinstalldirs $$dir; \
- chmod $(DIRMODE) $$dir; \
- $(DIRSETGID) $$dir; \
+ $(INSTALL) -d -m $(DIRMODE) $$dir; \
else true; \
fi; \
done
@@ -114,9 +121,7 @@ doinstall: $(SUBDIRS)
dir=$(DESTDIR)$(exec_prefix)/$$d; \
if test ! -d $$dir; then \
echo "Creating directory hierarchy $$dir"; \
- $(srcdir)/mkinstalldirs $$dir; \
- chmod $(DIRMODE) $$dir; \
- $(DIRSETGID) $$dir; \
+ $(INSTALL) -d -m $(DIRMODE) $$dir; \
else true; \
fi; \
done
diff --git a/bin/Makefile.in b/bin/Makefile.in
index 22c24b0..d795333 100644
--- a/bin/Makefile.in
+++ b/bin/Makefile.in
@@ -28,7 +28,6 @@ exec_prefix= @exec_prefix@
DESTDIR=
CC= @CC@
-CHMOD= @CHMOD@
INSTALL= @INSTALL@
DEFS= @DEFS@
@@ -56,7 +55,7 @@ BUILDDIR= ../build/bin
# Modes for directories and executables created by the install
# process. Default to group-writable directories but
# user-only-writable for executables.
-DIRMODE= 775
+DIRMODE= 2775
EXEMODE= 755
FILEMODE= 644
INSTALL_PROGRAM=$(INSTALL) -m $(EXEMODE)
@@ -72,8 +71,6 @@ install:
$(INSTALL) -m $(EXEMODE) $(BUILDDIR)/$$f $(DESTDIR)$(SCRIPTSDIR); \
done
-finish:
-
clean:
distclean:
diff --git a/cron/Makefile.in b/cron/Makefile.in
index 2a7c8fd..c14d119 100644
--- a/cron/Makefile.in
+++ b/cron/Makefile.in
@@ -28,7 +28,6 @@ exec_prefix= @exec_prefix@
DESTDIR=
CC= @CC@
-CHMOD= @CHMOD@
INSTALL= @INSTALL@
DEFS= @DEFS@
@@ -68,8 +67,6 @@ install:
$(INSTALL) -m $(EXEMODE) $(BUILDDIR)/$$f $(DESTDIR)$(CRONDIR); \
done
-finish:
-
clean:
distclean:
diff --git a/messages/Makefile.in b/messages/Makefile.in
index 2bbec3f..0b8b7d6 100644
--- a/messages/Makefile.in
+++ b/messages/Makefile.in
@@ -32,7 +32,6 @@ exec_prefix= @exec_prefix@
DESTDIR=
CC= @CC@
-CHMOD= @CHMOD@
INSTALL= @INSTALL@
DEFS= @DEFS@
@@ -43,7 +42,6 @@ OPT= @OPT@
CFLAGS= $(OPT) $(DEFS)
PACKAGEDIR= $(prefix)/messages
SHELL= /bin/sh
-DIRSETGID= chmod g+s
MSGFMT= @PYTHON@ ../build/bin/msgfmt.py
MSGMERGE= msgmerge
@@ -60,7 +58,7 @@ TARGETS= $(MOFILES)
# Modes for directories and executables created by the install
# process. Default to group-writable directories but
# user-only-writable for executables.
-DIRMODE= 775
+DIRMODE= 2775
EXEMODE= 755
FILEMODE= 644
INSTALL_PROGRAM=$(INSTALL) -m $(EXEMODE)
@@ -90,9 +88,8 @@ doinstall: mofiles
do \
dir=$(DESTDIR)$(prefix)/$$d; \
echo "Creating language directory $$dir"; \
- $(srcdir)/../mkinstalldirs $$dir; \
- chmod $(DIRMODE) $$dir; \
- $(DIRSETGID) $$dir; \
+ $(INSTALL) -d -m $(DIRMODE) `dirname $$dir`; \
+ $(INSTALL) -d -m $(DIRMODE) $$dir; \
done
@for d in $(LANGUAGES); \
do \
@@ -113,8 +110,6 @@ doinstall: mofiles
mofiles: $(MOFILES)
-finish:
-
clean:
-rm -f */LC_MESSAGES/mailman.mo
diff --git a/misc/Makefile.in b/misc/Makefile.in
index 5125cd8..af99c04 100644
--- a/misc/Makefile.in
+++ b/misc/Makefile.in
@@ -30,7 +30,6 @@ var_prefix= @VAR_PREFIX@
DESTDIR=
CC= @CC@
-CHMOD= @CHMOD@
INSTALL= @INSTALL@
PYTHON= @PYTHON@
@@ -62,7 +61,7 @@ PACKAGES= $(EMAILPKG) $(JACODECSPKG) $(KOCODECSPKG)
# Modes for directories and executables created by the install
# process. Default to group-writable directories but
# user-only-writable for executables.
-DIRMODE= 775
+DIRMODE= 2775
EXEMODE= 755
FILEMODE= 644
DATAMODE= 664
@@ -101,8 +100,6 @@ install-packages:
(cd $(PKGDIR)/$$p ; umask 02 ; PYTHONPATH=$(PYTHONLIBDIR) $(PYTHON) $(SETUPCMD)); \
done
-finish:
-
clean:
distclean:
diff --git a/scripts/Makefile.in b/scripts/Makefile.in
index 49b82ec..cea250c 100644
--- a/scripts/Makefile.in
+++ b/scripts/Makefile.in
@@ -28,7 +28,6 @@ exec_prefix= @exec_prefix@
DESTDIR=
CC= @CC@
-CHMOD= @CHMOD@
INSTALL= @INSTALL@
DEFS= @DEFS@
@@ -49,7 +48,7 @@ SCRIPTS= bounces confirm driver join leave owner post request
# Modes for directories and executables created by the install
# process. Default to group-writable directories but
# user-only-writable for executables.
-DIRMODE= 775
+DIRMODE= 2775
EXEMODE= 755
FILEMODE= 644
INSTALL_PROGRAM=$(INSTALL) -m $(EXEMODE)
@@ -68,8 +67,6 @@ install:
$(INSTALL) -m $(FILEMODE) $(srcdir)/join $(DESTDIR)$(SCRIPTSDIR)/subscribe
$(INSTALL) -m $(FILEMODE) $(srcdir)/leave $(DESTDIR)$(SCRIPTSDIR)/unsubscribe
-finish:
-
clean:
distclean:
diff --git a/src/Makefile.in b/src/Makefile.in
index ce52356..7ed820b 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -28,7 +28,6 @@ bindir= @bindir@
DESTDIR=
CC= @CC@
-CHMOD= @CHMOD@
INSTALL= @INSTALL@
PYTHON= @PYTHON@
@@ -65,10 +64,9 @@ COMMON_FLAGS= -DPREFIX="\"$(prefix)\"" \
# Modes for directories and executables created by the install
# process. Default to group-writable directories but
# user-only-writable for executables.
-DIRMODE= 775
-EXEMODE= 755
+DIRMODE= 2775
+EXEMODE= 2755
INSTALL_PROGRAM=$(INSTALL) -m $(EXEMODE)
-DIRSETGID= chmod g+s
# Fixed definitions
@@ -112,20 +110,10 @@ install: all
do \
exe=$(DESTDIR)$(CGIDIR)/$$f$(CGIEXT); \
$(INSTALL_PROGRAM) $$f $$exe; \
- $(DIRSETGID) $$exe; \
done
for f in $(MAIL_PROGS); \
do \
$(INSTALL_PROGRAM) $$f $(DESTDIR)$(MAILDIR); \
- $(DIRSETGID) $(DESTDIR)$(MAILDIR)/$$f; \
- done
-
-finish:
- -for f in $(SUID_CGI_PROGS); \
- do \
- exe=$(DESTDIR)$(CGIDIR)/$$f$(CGIEXT); \
- chown $(MAILMAN_USER) $$exe; \
- chmod u+s $$exe; \
done
clean:
diff --git a/templates/Makefile.in b/templates/Makefile.in
index 3dfee3a..b23d7c1 100644
--- a/templates/Makefile.in
+++ b/templates/Makefile.in
@@ -28,7 +28,6 @@ exec_prefix= @exec_prefix@
DESTDIR=
CC= @CC@
-CHMOD= @CHMOD@
INSTALL= @INSTALL@
TRUE= @TRUE@
@@ -48,7 +47,7 @@ LANGUAGES= ar ast ca cs da de el en es et eu fi fr gl he hr hu ia it ja \
# Modes for directories and executables created by the install
# process. Default to group-writable directories but
# user-only-writable for executables.
-DIRMODE= 775
+DIRMODE= 2775
EXEMODE= 755
FILEMODE= 644
INSTALL_PROGRAM=$(INSTALL) -m $(EXEMODE)
@@ -61,15 +60,13 @@ all:
install:
for d in $(LANGUAGES); \
do \
- $(srcdir)/../mkinstalldirs $(DESTDIR)$(TEMPLATEDIR)/$$d; \
+ $(INSTALL) -d -m $(DIRMODE) $(DESTDIR)$(TEMPLATEDIR)/$$d; \
for f in $(srcdir)/$$d/*.html $(srcdir)/$$d/*.txt; \
do \
$(INSTALL) -m $(FILEMODE) $$f $(DESTDIR)$(TEMPLATEDIR)/$$d; \
done; \
done
-finish:
-
clean:
distclean:
diff --git a/tests/Makefile.in b/tests/Makefile.in
index 26d6e31..ca92425 100644
--- a/tests/Makefile.in
+++ b/tests/Makefile.in
@@ -28,7 +28,6 @@ exec_prefix= @exec_prefix@
DESTDIR=
CC= @CC@
-CHMOD= @CHMOD@
INSTALL= @INSTALL@
DEFS= @DEFS@
@@ -46,7 +45,7 @@ EXECS= $(srcdir)/onebounce.py $(srcdir)/fblast.py
# Modes for directories and executables created by the install
# process. Default to group-writable directories but
# user-only-writable for executables.
-DIRMODE= 775
+DIRMODE= 2775
EXEMODE= 755
FILEMODE= 644
INSTALL_PROGRAM=$(INSTALL) -m $(EXEMODE)
@@ -71,8 +70,6 @@ install:
(cd $$d; $(MAKE) DESTDIR=$(DESTDIR) install); \
done
-finish:
-
clean:
distclean:
diff --git a/tests/bounces/Makefile.in b/tests/bounces/Makefile.in
index 5798097..f7014cb 100644
--- a/tests/bounces/Makefile.in
+++ b/tests/bounces/Makefile.in
@@ -28,7 +28,6 @@ exec_prefix= @exec_prefix@
DESTDIR=
CC= @CC@
-CHMOD= @CHMOD@
INSTALL= @INSTALL@
DEFS= @DEFS@
@@ -46,7 +45,7 @@ BOUNCE_FILES= $(srcdir)/*.txt
# Modes for directories and executables created by the install
# process. Default to group-writable directories but
# user-only-writable for executables.
-DIRMODE= 775
+DIRMODE= 2775
EXEMODE= 755
FILEMODE= 644
INSTALL_PROGRAM=$(INSTALL) -m $(EXEMODE)
@@ -60,8 +59,6 @@ install:
$(INSTALL) -m $(FILEMODE) $$f $(DESTDIR)$(BOUNCEDIR); \
done
-finish:
-
clean:
distclean:
diff --git a/tests/msgs/Makefile.in b/tests/msgs/Makefile.in
index 736d721..edef5ae 100644
--- a/tests/msgs/Makefile.in
+++ b/tests/msgs/Makefile.in
@@ -28,7 +28,6 @@ exec_prefix= @exec_prefix@
DESTDIR=
CC= @CC@
-CHMOD= @CHMOD@
INSTALL= @INSTALL@
DEFS= @DEFS@
@@ -46,7 +45,7 @@ MSG_FILES= $(srcdir)/*.txt
# Modes for directories and executables created by the install
# process. Default to group-writable directories but
# user-only-writable for executables.
-DIRMODE= 775
+DIRMODE= 2775
EXEMODE= 755
FILEMODE= 644
INSTALL_PROGRAM=$(INSTALL) -m $(EXEMODE)
@@ -60,8 +59,6 @@ install:
$(INSTALL) -m $(FILEMODE) $$f $(DESTDIR)$(MSGSDIR); \
done
-finish:
-
clean:
distclean:

View File

@ -0,0 +1,109 @@
diff --git a/bin/mailmanctl b/bin/mailmanctl
index fa14a2c..e291df1 100644
--- a/bin/mailmanctl
+++ b/bin/mailmanctl
@@ -36,7 +36,7 @@ in the file data/master-qrunner.pid but you normally don't need to use this
pid directly. The `start', `stop', `restart', and `reopen' commands handle
everything for you.
-Usage: %(PROGRAM)s [options] [ start | stop | restart | reopen ]
+Usage: %(PROGRAM)s [options] [ start | stop | restart | reopen | status ]
Options:
@@ -90,6 +90,9 @@ Commands:
reopen - This will close all log files, causing them to be re-opened the
next time a message is written to them
+
+ status - This returns a string indicating the status of the master
+ qrunner
"""
import sys
@@ -190,6 +193,52 @@ def qrunner_state():
return 0
return 1
+def mailman_status():
+ # return status, pid
+ #
+ # These status values match the /etc/init.d status values
+ # (at least on Red Hat), try to return equivalent status if possible
+ # status is 0 if running,
+ # status is 1 if dead but pid file exists
+ # status is 2 if dead but subsys locked
+ # status is 3 if stopped (pid returned will be 0)
+ #
+ #
+ # We want any user to be able to query the status and this presents
+ # few interesting permission problems and is why we don't use
+ # qrunner_state(). The pidfile is only readable by the mailman owner
+ # and group, however the lockfile is world readable. So we will
+ # get the master pid from the lockfile. We try to determine if the
+ # master process exists by sending it a signal. If we don't have
+ # permission to signal the process, but the process exists we'll
+ # get a EPERM error, if the process does not exist then we'll get
+ # a ESRCH error.
+
+ try:
+ hostname, pid, tempfile = get_lock_data()
+ except IOError, e:
+ if e.errno == errno.ENOENT:
+ # Lock file didn't exist, can't be running
+ return 3, 0
+ else:
+ raise
+ if hostname <> socket.gethostname():
+ # not running on this host
+ return 3, 0
+ # Find out if the process exists by calling kill with a signal 0.
+ try:
+ os.kill(pid, 0)
+ except OSError, e:
+ if e.errno == errno.ESRCH:
+ # process does not exist
+ return 1, pid
+ elif e.errno == errno.EPERM:
+ # we don't have permission signal the process but it exists
+ return 0, pid
+ else:
+ raise
+ return 0, pid
+
def acquire_lock_1(force):
# Be sure we can acquire the master qrunner lock. If not, it means some
@@ -338,13 +387,15 @@ def main():
command = COMMASPACE.join(args)
usage(1, C_('Bad command: %(command)s'))
+ command = args[0].lower()
+
if checkprivs:
check_privs()
else:
- print C_('Warning! You may encounter permission problems.')
+ if command != 'status':
+ print C_('Warning! You may encounter permission problems.')
# Handle the commands
- command = args[0].lower()
if command == 'stop':
# Sent the master qrunner process a SIGINT, which is equivalent to
# giving cron/qrunner a ctrl-c or KeyboardInterrupt. This will
@@ -363,6 +414,14 @@ def main():
if not quiet:
print C_('Re-opening all log files')
kill_watcher(signal.SIGHUP)
+ elif command == 'status':
+ status, pid = mailman_status()
+ if not quiet:
+ if status == 0:
+ print C_("mailman (pid %(pid)d) is running...")
+ else:
+ print C_("mailman is stopped")
+ sys.exit(status)
elif command == 'start':
# First, complain loudly if there's no site list.
check_for_site_list()

132
mailman-2.1.11-cron.patch Normal file
View File

@ -0,0 +1,132 @@
diff --git a/cron/bumpdigests b/cron/bumpdigests
index 57cc45e..4002731 100755
--- a/cron/bumpdigests
+++ b/cron/bumpdigests
@@ -1,4 +1,4 @@
-#! @PYTHON@
+#! @PYTHON@ -S
#
# Copyright (C) 1998-2018 by the Free Software Foundation, Inc.
#
diff --git a/cron/checkdbs b/cron/checkdbs
index e776f15..c4d8179 100755
--- a/cron/checkdbs
+++ b/cron/checkdbs
@@ -1,4 +1,4 @@
-#! @PYTHON@
+#! @PYTHON@ -S
#
# Copyright (C) 1998-2018 by the Free Software Foundation, Inc.
#
diff --git a/cron/crontab.in.in b/cron/crontab.in.in
index 540dfc1..45c5022 100644
--- a/cron/crontab.in.in
+++ b/cron/crontab.in.in
@@ -1,27 +1,50 @@
+#
+# -- WARNING -- WARNING -- WARNING -- WARNING -- WARNING -- WARNING --
+# ------------------ EDIT THE CORRECT FILE -------------------------
+#
+# This file is copied to /etc/cron.d/mailman from
+# @prefix@/cron/crontab.in when the mailman service is started via its
+# init.d script and the file /etc/cron.d/mailman is removed when the
+# service is stopped. Therefore any edits made directly to
+# /etc/cron.d/mailman will be lost anytime the mailman service
+# restarts.
+#
+# To make changes edit the master copy @prefix@/cron/crontab.in and then
+# restart the service to pick up the changes (/sbin/service mailman restart).
+#
+# The reason this is done this way is because the mailman cron jobs
+# should only be invoked if the mailman service is enabled and not
+# just as a consequence of installing the rpm as was the case
+# previously. The file /etc/cron.d/mailman cannot simply be linked to
+# the master copy in @prefix@/cron because for security reasons cron
+# will not process crontab files that are links or writeable by
+# anybody else but root, thus the file must be copied into /etc/cron.d
+# with the right ownership and permissions.
+#
# At 8AM every day, mail reminders to admins as to pending requests.
# They are less likely to ignore these reminders if they're mailed
# early in the morning, but of course, this is local time... ;)
-0 8 * * * @PYTHON@ -S @prefix@/cron/checkdbs
+0 8 * * * @MAILMAN_USER@ @prefix@/cron/checkdbs
#
# At 9AM, send notifications to disabled members that are due to be
# reminded to re-enable their accounts.
-0 9 * * * @PYTHON@ -S @prefix@/cron/disabled
+0 9 * * * @MAILMAN_USER@ @prefix@/cron/disabled
#
# Noon, mail digests for lists that do periodic as well as threshhold delivery.
-0 12 * * * @PYTHON@ -S @prefix@/cron/senddigests
+0 12 * * * @MAILMAN_USER@ @prefix@/cron/senddigests
#
# 5 AM on the first of each month, mail out password reminders.
-0 5 1 * * @PYTHON@ -S @prefix@/cron/mailpasswds
+0 5 1 * * @MAILMAN_USER@ @prefix@/cron/mailpasswds
#
# Every 5 mins, try to gate news to mail. You can comment this one out
# if you don't want to allow gating, or don't have any going on right now,
# or want to exclusively use a callback strategy instead of polling.
-0,5,10,15,20,25,30,35,40,45,50,55 * * * * @PYTHON@ -S @prefix@/cron/gate_news
+0,5,10,15,20,25,30,35,40,45,50,55 * * * * @MAILMAN_USER@ @prefix@/cron/gate_news
#
# At 3:27am every night, regenerate the gzip'd archive file. Only
# turn this on if the internal archiver is used and
# GZIP_ARCHIVE_TXT_FILES is false in mm_cfg.py
-27 3 * * * @PYTHON@ -S @prefix@/cron/nightly_gzip
+27 3 * * * @MAILMAN_USER@ @prefix@/cron/nightly_gzip
#
# At 4:30AM daily, cull old entries from the 'bad' and 'shunt' queues.
-30 4 * * * @PYTHON@ -S @prefix@/cron/cull_bad_shunt
+30 4 * * * @MAILMAN_USER@ @prefix@/cron/cull_bad_shunt
diff --git a/cron/disabled b/cron/disabled
index ac62582..971563d 100755
--- a/cron/disabled
+++ b/cron/disabled
@@ -1,4 +1,4 @@
-#! @PYTHON@
+#! @PYTHON@ -S
#
# Copyright (C) 2001-2018 by the Free Software Foundation, Inc.
#
diff --git a/cron/gate_news b/cron/gate_news
index c66c09e..247c834 100755
--- a/cron/gate_news
+++ b/cron/gate_news
@@ -1,4 +1,4 @@
-#! @PYTHON@
+#! @PYTHON@ -S
#
# Copyright (C) 1998-2018 by the Free Software Foundation, Inc.
#
diff --git a/cron/mailpasswds b/cron/mailpasswds
index da64376..5d8d792 100755
--- a/cron/mailpasswds
+++ b/cron/mailpasswds
@@ -1,4 +1,4 @@
-#! @PYTHON@
+#! @PYTHON@ -S
#
# Copyright (C) 1998-2018 by the Free Software Foundation, Inc.
#
diff --git a/cron/nightly_gzip b/cron/nightly_gzip
index de493d0..8af0351 100755
--- a/cron/nightly_gzip
+++ b/cron/nightly_gzip
@@ -1,4 +1,4 @@
-#! @PYTHON@
+#! @PYTHON@ -S
#
# Copyright (C) 1998-2018 by the Free Software Foundation, Inc.
#
diff --git a/cron/senddigests b/cron/senddigests
index edf27a2..c64adc1 100755
--- a/cron/senddigests
+++ b/cron/senddigests
@@ -1,4 +1,4 @@
-#! @PYTHON@
+#! @PYTHON@ -S
#
# Copyright (C) 1998-2018 by the Free Software Foundation, Inc.
#

View File

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

243
mailman-2.1.13-FHS.patch Normal file
View File

@ -0,0 +1,243 @@
diff --git a/Mailman/Defaults.py.in b/Mailman/Defaults.py.in
index fb3f4f3..7dde965 100644
--- a/Mailman/Defaults.py.in
+++ b/Mailman/Defaults.py.in
@@ -1431,20 +1431,22 @@ AuthListPoster = 6 # List poster (Approved: <pw> header in posts only)
# Useful directories
LIST_DATA_DIR = os.path.join(VAR_PREFIX, 'lists')
-LOG_DIR = os.path.join(VAR_PREFIX, 'logs')
-LOCK_DIR = os.path.join(VAR_PREFIX, 'locks')
+LOG_DIR = '@LOG_DIR@'
+LOCK_DIR = '@LOCK_DIR@'
+CONFIG_DIR = '@CONFIG_DIR@'
DATA_DIR = os.path.join(VAR_PREFIX, 'data')
+PID_DIR = '@PID_DIR@'
SPAM_DIR = os.path.join(VAR_PREFIX, 'spam')
WRAPPER_DIR = os.path.join(EXEC_PREFIX, 'mail')
BIN_DIR = os.path.join(PREFIX, 'bin')
SCRIPTS_DIR = os.path.join(PREFIX, 'scripts')
-TEMPLATE_DIR = os.path.join(PREFIX, 'templates')
+TEMPLATE_DIR = '@TEMPLATE_DIR@'
MESSAGES_DIR = os.path.join(PREFIX, 'messages')
PUBLIC_ARCHIVE_FILE_DIR = os.path.join(VAR_PREFIX, 'archives', 'public')
PRIVATE_ARCHIVE_FILE_DIR = os.path.join(VAR_PREFIX, 'archives', 'private')
# Directories used by the qrunner subsystem
-QUEUE_DIR = os.path.join(VAR_PREFIX, 'qfiles')
+QUEUE_DIR = '@QUEUE_DIR@'
INQUEUE_DIR = os.path.join(QUEUE_DIR, 'in')
OUTQUEUE_DIR = os.path.join(QUEUE_DIR, 'out')
CMDQUEUE_DIR = os.path.join(QUEUE_DIR, 'commands')
@@ -1458,9 +1460,9 @@ RETRYQUEUE_DIR = os.path.join(QUEUE_DIR, 'retry')
MAILDIR_DIR = os.path.join(QUEUE_DIR, 'maildir')
# Other useful files
-PIDFILE = os.path.join(DATA_DIR, 'master-qrunner.pid')
-SITE_PW_FILE = os.path.join(DATA_DIR, 'adm.pw')
-LISTCREATOR_PW_FILE = os.path.join(DATA_DIR, 'creator.pw')
+PIDFILE = os.path.join(PID_DIR, 'master-qrunner.pid')
+SITE_PW_FILE = os.path.join(CONFIG_DIR, 'adm.pw')
+LISTCREATOR_PW_FILE = os.path.join(CONFIG_DIR, 'creator.pw')
# Import a bunch of version numbers
from Version import *
diff --git a/Mailman/MTA/Postfix.py b/Mailman/MTA/Postfix.py
index 801ddc0..8506b9b 100644
--- a/Mailman/MTA/Postfix.py
+++ b/Mailman/MTA/Postfix.py
@@ -32,8 +32,8 @@ from Mailman.MTA.Utils import makealiases
from Mailman.Logging.Syslog import syslog
LOCKFILE = os.path.join(mm_cfg.LOCK_DIR, 'creator')
-ALIASFILE = os.path.join(mm_cfg.DATA_DIR, 'aliases')
-VIRTFILE = os.path.join(mm_cfg.DATA_DIR, 'virtual-mailman')
+ALIASFILE = os.path.join(mm_cfg.CONFIG_DIR, 'aliases')
+VIRTFILE = os.path.join(mm_cfg.CONFIG_DIR, 'virtual-mailman')
# Desired mode for aliases(.db) and virtual-mailman(.db) for both creation
# and check_perms.
targetmode = S_IFREG | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH
diff --git a/Makefile.in b/Makefile.in
index eb40844..289aeee 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -28,6 +28,12 @@ bindir= @bindir@
prefix= @prefix@
exec_prefix= @exec_prefix@
var_prefix= @VAR_PREFIX@
+configdir= @CONFIG_DIR@
+lockdir= @LOCK_DIR@
+logdir= @LOG_DIR@
+piddir= @PID_DIR@
+queuedir= @QUEUE_DIR@
+templatedir= @TEMPLATE_DIR@
DESTDIR=
CC= @CC@
@@ -41,8 +47,11 @@ DEFS= @DEFS@
OPT= @OPT@
CFLAGS= @CFLAGS@ $(OPT) $(DEFS)
+FHS_DIRS= \
+ ${configdir} ${lockdir} ${logdir} ${piddir} ${queuedir} ${templatedir}
+
VAR_DIRS= \
- logs archives lists locks data spam qfiles \
+ archives lists data spam \
archives/private archives/public
ARCH_INDEP_DIRS= \
@@ -105,6 +114,15 @@ doinstall: $(SUBDIRS)
else true; \
fi; \
done
+ @for d in $(FHS_DIRS); \
+ do \
+ dir=$(DESTDIR)/$$d; \
+ if test ! -d $$dir; then \
+ echo "Creating directory $$dir"; \
+ $(INSTALL) -d -m $(DIRMODE) $$dir; \
+ else true; \
+ fi; \
+ done
chmod o-r $(DESTDIR)$(var_prefix)/archives/private
@for d in $(ARCH_INDEP_DIRS); \
do \
diff --git a/bin/check_perms b/bin/check_perms
index 137ebfb..1f45f84 100755
--- a/bin/check_perms
+++ b/bin/check_perms
@@ -183,7 +183,8 @@ def checkall():
print C_('checking mode for %(prefix)s')
dirs = {}
for d in (mm_cfg.PREFIX, mm_cfg.EXEC_PREFIX, mm_cfg.VAR_PREFIX,
- mm_cfg.LOG_DIR):
+ mm_cfg.CONFIG_DIR, mm_cfg.DATA_DIR, mm_cfg.LOCK_DIR,
+ mm_cfg.LOG_DIR, mm_cfg.QUEUE_DIR, mm_cfg.PID_DIR):
dirs[d] = True
for d in dirs.keys():
try:
diff --git a/configure.in b/configure.in
index f2eb1c0..c01129c 100644
--- a/configure.in
+++ b/configure.in
@@ -305,6 +305,72 @@ else
prefixcheck=$VAR_PREFIX
fi
+# Get the configuration file directory
+AC_SUBST(CONFIG_DIR)
+AC_MSG_CHECKING(for --with-config-dir)
+AC_ARG_WITH(config-dir, dnl
+[ --with-config-dir specify directory for configuration data other than [VAR_]PREFIX/data])
+case "$with_config_dir" in
+ yes|no|"") CONFIG_DIR="$VAR_PREFIX/data";;
+ *) CONFIG_DIR=$with_config_dir;;
+esac
+AC_MSG_RESULT($CONFIG_DIR)
+
+# Get the lock directory
+AC_SUBST(LOCK_DIR)
+AC_MSG_CHECKING(for --with-lock-dir)
+AC_ARG_WITH(lock-dir, dnl
+[ --with-lock-dir specify directory for lock files other than [VAR_]PREFIX/locks])
+case "$with_lock_dir" in
+ yes|no|"") LOCK_DIR="$VAR_PREFIX/locks";;
+ *) LOCK_DIR=$with_lock_dir;;
+esac
+AC_MSG_RESULT($LOCK_DIR)
+
+# Get the log directory
+AC_SUBST(LOG_DIR)
+AC_MSG_CHECKING(for --with-log-dir)
+AC_ARG_WITH(log-dir, dnl
+[ --with-log-dir specify directory for log files other than [VAR_]PREFIX/logs])
+case "$with_log_dir" in
+ yes|no|"") LOG_DIR="$VAR_PREFIX/logs";;
+ *) LOG_DIR=$with_log_dir;;
+esac
+AC_MSG_RESULT($LOG_DIR)
+
+# Get the pid directory
+AC_SUBST(PID_DIR)
+AC_MSG_CHECKING(for --with-pid-dir)
+AC_ARG_WITH(pid-dir, dnl
+[ --with-pid-dir specify directory for the pid file other than [VAR_]PREFIX/data])
+case "$with_pid_dir" in
+ yes|no|"") PID_DIR="$VAR_PREFIX/data";;
+ *) PID_DIR=$with_pid_dir;;
+esac
+AC_MSG_RESULT($PID_DIR)
+
+# Get the queue directory
+AC_SUBST(QUEUE_DIR)
+AC_MSG_CHECKING(for --with-queue-dir)
+AC_ARG_WITH(queue-dir, dnl
+[ --with-queue-dir specify directory for queue files other than [VAR_]PREFIX/qfiles])
+case "$with_queue_dir" in
+ yes|no|"") QUEUE_DIR="$VAR_PREFIX/qfiles";;
+ *) QUEUE_DIR=$with_queue_dir;;
+esac
+AC_MSG_RESULT($QUEUE_DIR)
+
+# Get the template directory
+AC_SUBST(TEMPLATE_DIR)
+AC_MSG_CHECKING(for --with-template-dir)
+AC_ARG_WITH(template-dir, dnl
+[ --with-template-dir specify directory for template files other than [VAR_]PREFIX/templates])
+case "$with_template_dir" in
+ yes|no|"") TEMPLATE_DIR="$VAR_PREFIX/templates";;
+ *) TEMPLATE_DIR=$with_template_dir;;
+esac
+AC_MSG_RESULT($TEMPLATE_DIR)
+
# new macro for finding group names
# returns a comma separated list of quoted group names
# the list is returned in the same order as specified with any duplicates removed
diff --git a/misc/Makefile.in b/misc/Makefile.in
index af99c04..df50a06 100644
--- a/misc/Makefile.in
+++ b/misc/Makefile.in
@@ -27,6 +27,12 @@ bindir= @bindir@
prefix= @prefix@
exec_prefix= @exec_prefix@
var_prefix= @VAR_PREFIX@
+configdir= @CONFIG_DIR@
+lockdir= @LOCK_DIR@
+logdir= @LOG_DIR@
+piddir= @PID_DIR@
+queuedir= @QUEUE_DIR@
+MAILMAN_GROUP= @MAILMAN_GROUP@
DESTDIR=
CC= @CC@
@@ -87,7 +93,7 @@ install-other:
$(INSTALL) -m $(FILEMODE) paths.py $$dir; \
done
$(INSTALL) -m $(EXEMODE) mailman $(DESTDIR)$(SCRIPTSDIR)
- $(INSTALL) -m $(FILEMODE) sitelist.cfg $(DESTDIR)$(DATADIR)
+ $(INSTALL) -m $(FILEMODE) sitelist.cfg $(DESTDIR)$(configdir)
install-packages:
if [ -z "$(EMAILPKG)" -a -d $(DESTDIR)$(PYTHONLIBDIR)/email ] ; \
diff --git a/templates/Makefile.in b/templates/Makefile.in
index b23d7c1..16930a2 100644
--- a/templates/Makefile.in
+++ b/templates/Makefile.in
@@ -25,6 +25,7 @@ srcdir= @srcdir@
bindir= @bindir@
prefix= @prefix@
exec_prefix= @exec_prefix@
+template_dir= @TEMPLATE_DIR@
DESTDIR=
CC= @CC@
@@ -37,7 +38,7 @@ DEFS= @DEFS@
OPT= @OPT@
CFLAGS= $(OPT) $(DEFS)
-TEMPLATEDIR= $(prefix)/templates
+TEMPLATEDIR= $(template_dir)
SHELL= /bin/sh

View File

@ -0,0 +1,21 @@
diff -up mailman-2.1.13/templates/en/article.html.archive-reply mailman-2.1.13/templates/en/article.html
--- mailman-2.1.13/templates/en/article.html.archive-reply 2009-12-22 19:00:43.000000000 +0100
+++ mailman-2.1.13/templates/en/article.html 2010-03-25 13:50:02.000000000 +0100
@@ -4,7 +4,7 @@
<TITLE> %(title)s
</TITLE>
<LINK REL="Index" HREF="index.html" >
- <LINK REL="made" HREF="mailto:%(email_url)s?Subject=%(subject_url)s&In-Reply-To=%(in_reply_to_url)s">
+ <LINK REL="made" HREF="mailto:%(email_url)s?Subject=Re:%%20%(subject_url)s&In-Reply-To=%(in_reply_to_url)s">
<META NAME="robots" CONTENT="index,nofollow">
<style type="text/css">
pre {
@@ -18,7 +18,7 @@
<BODY BGCOLOR="#ffffff">
<H1>%(subject_html)s</H1>
<B>%(author_html)s</B>
- <A HREF="mailto:%(email_url)s?Subject=%(subject_url)s&In-Reply-To=%(in_reply_to_url)s"
+ <A HREF="mailto:%(email_url)s?Subject=Re:%%20%(subject_url)s&In-Reply-To=%(in_reply_to_url)s"
TITLE="%(subject_html)s">%(email_html)s
</A><BR>
<I>%(datestr_html)s</I>

View File

@ -0,0 +1,25 @@
diff --git a/tests/onebounce.py b/tests/onebounce.py
index 846c4fa..85f3b98 100755
--- a/tests/onebounce.py
+++ b/tests/onebounce.py
@@ -1,4 +1,4 @@
-#! /usr/bin/env python
+#! /usr/bin/python
# Copyright (C) 2002-2018 by the Free Software Foundation, Inc.
#
diff --git a/configure.in b/configure.in
index eee7f3a..2250ade 100644
--- a/configure.in
+++ b/configure.in
@@ -892,6 +892,10 @@ cron/gate_news \
cron/mailpasswds \
cron/nightly_gzip \
cron/senddigests \
+contrib/check_perms_grsecurity.py \
+contrib/qmail-to-mailman.py \
+contrib/rotatelogs.py \
+contrib/sitemapgen
])
dnl Please make sure to leave a space at the end of the last entry.

View File

@ -0,0 +1,22 @@
diff --git a/bin/check_perms b/bin/check_perms
index 5ef3306..d50518a 100755
--- a/bin/check_perms
+++ b/bin/check_perms
@@ -70,7 +70,7 @@ class State:
STATE = State()
-DIRPERMS = S_ISGID | S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH
+DIRPERMS = S_IRWXU | S_IRGRP | S_IROTH | S_IXOTH
QFILEPERMS = S_ISGID | S_IRWXU | S_IRWXG
PYFILEPERMS = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH
ARTICLEFILEPERMS = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP
@@ -195,7 +195,7 @@ def checkall():
continue
if (mode & DIRPERMS) <> DIRPERMS:
STATE.ERRORS += 1
- print C_('directory must be at least 02775: %(d)s'),
+ print C_('directory must be at least 0755: %(d)s'),
if STATE.FIX:
print C_('(fixing)')
os.chmod(d, mode | DIRPERMS)

View File

@ -0,0 +1,16 @@
=== modified file 'Mailman/Queue/CommandRunner.py'
--- Mailman/Queue/CommandRunner.py 2018-06-17 23:47:34 +0000
+++ Mailman/Queue/CommandRunner.py 2021-03-31 21:53:20 +0000
@@ -100,6 +100,11 @@
# E.g the outer Content-Type: was text/html
return
body = part.get_payload(decode=True)
+ if (part.get_content_charset(None)):
+ body = unicode(body, part.get_content_charset(),
+ errors='replace').encode(
+ Utils.GetCharSet(self.msgdata['lang']),
+ errors='replace')
# text/plain parts better have string payloads
assert isinstance(body, StringType) or isinstance(body, UnicodeType)
lines = body.splitlines()

View File

@ -0,0 +1,13 @@
=== modified file 'Mailman/Cgi/options.py'
--- Mailman/Cgi/options.py 2019-03-06 17:48:32 +0000
+++ Mailman/Cgi/options.py 2020-04-20 03:10:16 +0000
@@ -173,7 +173,7 @@
try:
Utils.ValidateEmail(user)
except Errors.EmailAddressError:
- doc.addError(_('Illegal Email Address: %(safeuser)s'))
+ doc.addError(_('Illegal Email Address'))
loginpage(mlist, doc, None, language)
print doc.Format()
return

View File

@ -0,0 +1,22 @@
=== modified file 'Mailman/Cgi/private.py'
--- Mailman/Cgi/private.py 2019-03-06 17:48:32 +0000
+++ Mailman/Cgi/private.py 2020-05-07 13:53:40 +0000
@@ -162,13 +162,9 @@
if mlist.isMember(username):
mlist.MailUserPassword(username)
elif username:
- # Not a member
- if mlist.private_roster == 0:
- # Public rosters
- safeuser = Utils.websafe(username)
- message = Bold(FontSize('+1',
- _('No such member: %(safeuser)s.'))).Format()
- else:
+ # Not a member. Don't report address in any case. It leads to
+ # Content injection. Just log if roster is not public.
+ if mlist.private_roster != 0:
syslog('mischief',
'Reminder attempt of non-member w/ private rosters: %s',
username)

View File

@ -0,0 +1,48 @@
diff -ruN mailman-2.1.12-a/Mailman/Archiver/pipermail.py mailman-2.1.12-b/Mailman/Archiver/pipermail.py
--- mailman-2.1.12-a/Mailman/Archiver/pipermail.py 2009-02-23 22:23:35.000000000 +0100
+++ mailman-2.1.12-b/Mailman/Archiver/pipermail.py 2009-07-28 12:19:53.000000000 +0200
@@ -45,24 +45,27 @@
def fixAuthor(author):
"Canonicalize a name into Last, First format"
- # If there's a comma, guess that it's already in "Last, First" format
- if ',' in author:
+ try:
+ # If there's a comma, guess that it's already in "Last, First" format
+ if ',' in author:
+ return author
+ L = author.split()
+ i = len(L) - 1
+ if i == 0:
+ return author # The string's one word--forget it
+ if author.upper() == author or author.lower() == author:
+ # Damn, the name is all upper- or lower-case.
+ while i > 0 and L[i-1].lower() in smallNameParts:
+ i = i - 1
+ else:
+ # Mixed case; assume that small parts of the last name will be
+ # in lowercase, and check them against the list.
+ while i>0 and (L[i-1][0] in lowercase or
+ L[i-1].lower() in smallNameParts):
+ i = i - 1
+ author = SPACE.join(L[-1:] + L[i:-1]) + ', ' + SPACE.join(L[:i])
+ except UnicodeDecodeError:
return author
- L = author.split()
- i = len(L) - 1
- if i == 0:
- return author # The string's one word--forget it
- if author.upper() == author or author.lower() == author:
- # Damn, the name is all upper- or lower-case.
- while i > 0 and L[i-1].lower() in smallNameParts:
- i = i - 1
- else:
- # Mixed case; assume that small parts of the last name will be
- # in lowercase, and check them against the list.
- while i>0 and (L[i-1][0] in lowercase or
- L[i-1].lower() in smallNameParts):
- i = i - 1
- author = SPACE.join(L[-1:] + L[i:-1]) + ', ' + SPACE.join(L[:i])
return author
# Abstract class for databases

View File

@ -0,0 +1,14 @@
=== modified file 'Mailman/Handlers/Scrubber.py'
--- Mailman/Handlers/Scrubber.py 2018-06-17 23:47:34 +0000
+++ Mailman/Handlers/Scrubber.py 2018-11-10 18:57:54 +0000
@@ -87,6 +87,9 @@
all = guess_all_extensions(ctype, strict=False)
if ext in all:
return ext
+ if ctype.lower == 'application/octet-stream':
+ # For this type, all[0] is '.obj'. '.bin' is better.
+ return '.bin'
return all and all[0]

View File

@ -0,0 +1,78 @@
--- Mailman/Bouncers/SimpleMatch.py 2018-06-17 23:47:34 +0000
+++ Mailman/Bouncers/SimpleMatch.py 2020-01-17 00:03:34 +0000
@@ -25,6 +25,9 @@
def _c(pattern):
return re.compile(pattern, re.IGNORECASE)
+# Pattern to match any valid email address and not much more.
+VALID = _c(r'[\x21-\x3d\x3f\x41-\x7e]+@[a-z0-9._]+')
+
# This is a list of tuples of the form
#
# (start cre, end cre, address cre)
@@ -227,4 +230,4 @@
break
if addrs:
break
- return addrs.keys()
+ return [x for x in addrs.keys() if VALID.match(x)]
=== modified file 'Mailman/Bouncers/SimpleWarning.py'
--- Mailman/Bouncers/SimpleWarning.py 2018-06-17 23:47:34 +0000
+++ Mailman/Bouncers/SimpleWarning.py 2020-01-17 00:03:34 +0000
@@ -17,9 +17,10 @@
"""Recognizes simple heuristically delimited warnings."""
+import email
+
from Mailman.Bouncers.BouncerAPI import Stop
from Mailman.Bouncers.SimpleMatch import _c
-from Mailman.Bouncers.SimpleMatch import process as _process
@@ -67,8 +68,25 @@
def process(msg):
- if _process(msg, patterns):
- # It's a recognized warning so stop now
- return Stop
- else:
- return []
+ # We used to just import process from SimpleMatch, but with the change in
+ # SimpleMatch to return only vaild addresses, that doesn't work any more.
+ # So, we copy most of the process from SimpleMatch here.
+ addrs = {}
+ for scre, ecre, acre in patterns:
+ state = 0
+ for line in email.Iterators.body_line_iterator(msg, decode=True):
+ if state == 0:
+ if scre.search(line):
+ state = 1
+ if state == 1:
+ mo = acre.search(line)
+ if mo:
+ addr = mo.group('addr')
+ if addr:
+ addrs[addr.strip('<>')] = 1
+ elif ecre.search(line):
+ break
+ if addrs:
+ # It's a recognized warning so stop now
+ return Stop
+ return []
--- Mailman/Bouncers/SimpleMatch.py 2020-01-17 00:03:34 +0000
+++ Mailman/Bouncers/SimpleMatch.py 2020-01-17 03:25:09 +0000
@@ -26,7 +26,7 @@
return re.compile(pattern, re.IGNORECASE)
# Pattern to match any valid email address and not much more.
-VALID = _c(r'[\x21-\x3d\x3f\x41-\x7e]+@[a-z0-9._]+')
+VALID = _c(r'^[\x21-\x3d\x3f\x41-\x7e]+@[a-z0-9._]+$')
# This is a list of tuples of the form
#

47
mailman-crontab-edit Executable file
View File

@ -0,0 +1,47 @@
#!/usr/bin/python2
# This script inserts the mailman user name into the crontab entries after
# the 5 time/date fields so that it can be installed under /etc/cron.d
#
# usage: mailman-crontab-edit [-s src_file] [-u mailman_user] [-d dst_file]
# src_file defaults to stdin
# mailman_user defaults to mailman
# dst_file defaults to stdout
import sys, re, getopt
srcFile = None
dstFile = None
mmUser = None
opts, args = getopt.getopt(sys.argv[1:], "s:d:u:")
for o, a in opts:
if o == "-s":
srcFile = a
if o == "-d":
dstFile = a
if o == "-u":
mmUser = a
if srcFile:
inFD = open(srcFile)
else:
inFD = sys.stdin
if dstFile:
outFD = open(dstFile, mode='w')
else:
outFD = sys.stdout
if not mmUser:
mmUser = "mailman"
comment_re = re.compile(r'^\s*#')
time_date_re = re.compile(r'(^\s*(\S+\s+){5,5})')
for line in inFD:
if not comment_re.search(line):
match = time_date_re.search(line)
if match:
line = time_date_re.sub(r'\1 %s ' % mmUser, line)
print >>outFD, line,

293
mailman-migrate-fhs Executable file
View File

@ -0,0 +1,293 @@
#!/usr/bin/python2
import sys
import os
import re
import shutil
import getopt
from stat import *
#------------------------------------------------------------------------------
# Command Line Args
doit = True
verbose = False
quiet = False
warn = False
force = False
print_mapping = False
remove_files = False
remove_installation = False
# Scan Results
existing_files = {}
non_existing_files = {}
# Directory and File mappings
# This is the complete directory map, it includes both data files
# and run-time files
dir_map = {
'/var/mailman' : '/var/lib/mailman',
'/var/mailman/Mailman' : '/usr/lib/mailman/Mailman',
'/var/mailman/archives' : '/var/lib/mailman/archives',
'/var/mailman/bin' : '/usr/lib/mailman/bin',
'/var/mailman/cgi-bin' : '/usr/lib/mailman/cgi-bin',
'/var/mailman/cron' : '/usr/lib/mailman/cron',
'/var/mailman/data' : '/var/lib/mailman/data',
'/var/mailman/lists' : '/var/lib/mailman/lists',
'/var/mailman/locks' : '/var/lock/mailman',
'/var/mailman/logs' : '/var/log/mailman',
'/var/mailman/mail' : '/usr/lib/mailman/mail',
'/var/mailman/messages' : '/usr/lib/mailman/messages',
'/var/mailman/pythonlib' : '/usr/lib/mailman/pythonlib',
'/var/mailman/qfiles' : '/var/spool/mailman',
'/var/spool/mailman/qfiles' : '/var/spool/mailman',
'/var/mailman/scripts' : '/usr/lib/mailman/scripts',
'/var/mailman/spam' : '/var/lib/mailman/spam',
'/var/mailman/templates' : '/usr/lib/mailman/templates',
'/var/mailman/tests' : '/usr/lib/mailman/tests'
}
# These are directories that contain data files the user may
# want to preserve from an old installation and should be copied
# into the new directory location.
data_dir_map = {
'/var/mailman/archives' : '/var/lib/mailman/archives',
'/var/mailman/data' : '/var/lib/mailman/data',
'/var/mailman/lists' : '/var/lib/mailman/lists',
'/var/mailman/logs' : '/var/log/mailman',
'/var/mailman/qfiles' : '/var/spool/mailman',
'/var/spool/mailman/qfiles' : '/var/spool/mailman',
'/var/mailman/spam' : '/var/lib/mailman/spam',
}
# These are mappings for individual files. They represent files that
# cannot be mapped via their parent dirctories, they must be treated
# individually.
file_map = {
'/var/mailman/data/adm.pw' : '/etc/mailman/adm.pw',
'/var/mailman/data/creator.pw' : '/etc/mailman/creator.pw',
'/var/mailman/data/aliases' : '/etc/mailman/aliases',
'/var/mailman/data/virtual-mailman' : '/etc/mailman/virtual-mailman',
'/var/mailman/data/sitelist.cfg' : '/etc/mailman/sitelist.cfg',
'/var/mailman/data/master-qrunner.pid' : '/var/run/mailman/master-qrunner.pid'
}
#------------------------------------------------------------------------------
def DumpMapping():
'''Print out the directory and file mappings'''
print "Directory Mapping:"
for key in dir_map.keys():
print "%s --> %s" %(key, dir_map[key])
print "\nFile Mapping:"
for key in file_map.keys():
print "%s --> %s" %(key, file_map[key])
def RecordFile(src, dst):
'''If the src files (old) exists record this as a potential
file operation. File operations are grouped into two sets,
those where the dst (new) files exists and those where it does not
exist. This is done to prevent overwriting files'''
global existing_files, non_existing_files
if not os.path.exists(src):
return
if existing_files.has_key(src):
if warn:
print "WARNING: src file already seen (%s) and has dst match: (%s)" % (src, dst)
return
if non_existing_files.has_key(src):
if warn:
print "WARNING: src file already seen (%s) does not have dst match" % (src)
return
if os.path.exists(dst):
existing_files[src] = dst
else:
non_existing_files[src] = dst
def GetCopyFiles(old_root, new_root):
'''Recursively generate a list of src files (old) in the old_root
and pair each of them with their new dst path name'''
prefix_re = re.compile("^(%s)/*(.*)" % re.escape(old_root))
dst_files_existing = []
dst_files_non_existing = []
for root, dirs, files in os.walk(old_root):
match = prefix_re.match(root)
subdir = match.group(2)
for name in files:
oldpath = os.path.join(root, name)
newpath = os.path.join(new_root, subdir, name)
RecordFile(oldpath, newpath)
def CopyFile(src_path, dst_path):
'''Copy file, preserve its mode and ownership. If the dst directory
does not exist, create it preserving the mode and ownership of the
src direcotry'''
if not doit:
print "cp %s %s" % (src_path, dst_path)
return
src_dir = os.path.dirname(src_path)
dst_dir = os.path.dirname(dst_path)
if not os.path.isdir(dst_dir):
if os.path.exists(dst_dir):
print "ERROR: dst dir exists, but is not directory (%s)" % dst_dir
return
st = os.stat(src_dir)
os.makedirs(dst_dir, st[ST_MODE])
os.chown(dst_dir, st[ST_UID], st[ST_GID])
shutil.copy2(src_path, dst_path)
st = os.stat(src_path)
os.chown(dst_path, st[ST_UID], st[ST_GID])
def RemoveFile(path):
'''Remove the file'''
if not os.path.exists(path):
if warn:
print "WARNING: attempt to remove non-existent file (%s)" % path
return
if not os.path.isfile(path):
if warn:
print "WARNING: attempt to remove non-plain file (%s)" % path
return
if not doit:
print "rm %s" % (path)
return
os.unlink(path)
def RemoveDirs(top):
'''Delete everything reachable from the directory named in 'top',
assuming there are no symbolic links.
CAUTION: This is dangerous! For example, if top == '/', it
could delete all your disk files.'''
for root, dirs, files in os.walk(top, topdown=False):
for name in files:
path = os.path.join(root, name)
if not doit:
print "rm %s" % (path)
else:
os.remove(path)
for name in dirs:
path = os.path.join(root, name)
if not doit:
print "rmdir %s" % (path)
else:
os.rmdir(path)
def Usage():
print """
This script will help you copy mailman data files from the old
directory structure to the new FHS directory structure.
Mailman should not be running when you perform this!
/sbin/service mailman stop
This script is conservative, by default it will not overwrite
any file in the new directory on the assumption it is most recent
and most correct. If you want to force overwrites use -f.
Files are copied to the new directories, if you want to remove the
old data files use -r. Hint: copy first and test, once everything is
working remove the old files with -r. If you want to remove the entire
old installation use -R
migrate [-f] [-n] [-q] [-v] [-w] [-m] [-r] [-R]
-n don't execute, but show what would be done
-f force destination overwrites
-m print mapping
-r remove old data files
-R remove entire old installation
-q be quiet
-v be verbose
-w print warnings
-h help
"""
#------------------------------------------------------------------------------
try:
opts, args = getopt.getopt(sys.argv[1:], "nfvmqwhrR")
for o, a in opts:
if o == "-n":
doit = False
elif o == "-f":
force = True
elif o == "-v":
verbose = True
elif o == "-m":
print_mapping = True
elif o == "-q":
quiet = True
elif o == "-w":
warn = True
elif o == "-r":
remove_files = True
elif o == "-R":
remove_installation = True
elif o == "-h":
Usage()
sys.exit(1)
except getopt.GetoptError, err:
print err
Usage()
sys.exit(1)
if print_mapping:
DumpMapping()
sys.exit(0)
# Generate file list
for src_dir in data_dir_map.keys():
GetCopyFiles(src_dir, dir_map[src_dir])
for src_file in file_map.keys():
RecordFile(src_file, file_map[src_file])
# Copy files
for src in non_existing_files:
dst = non_existing_files[src]
CopyFile(src, dst)
if force:
for src in existing_files:
dst = existing_files[src]
CopyFile(src, dst)
else:
if len(existing_files) > 0 and not quiet:
print "\nThe following files already exist in the destination, they will NOT be copied"
print "To force overwriting invoke with -f\n"
for src in existing_files:
dst = existing_files[src]
print "# cp %s %s" %(src, dst)
# Remove old files
if remove_files:
for src in existing_files:
RemoveFile(src)
for src in non_existing_files:
RemoveFile(src)
if remove_installation:
for old_dir in dir_map.keys():
RemoveDirs(old_dir)
sys.exit(0)

View File

@ -0,0 +1,13 @@
diff --git a/Makefile.in b/Makefile.in
index dc2fc59..45988b4 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -129,7 +129,7 @@ doinstall: $(SUBDIRS)
do \
(cd $$d; $(MAKE) DESTDIR=$(DESTDIR) install); \
done
- $(PYTHON) -c 'from compileall import *; compile_dir("$(DESTDIR)$(prefix)/Mailman", ddir="$(prefix)/Mailman")'
+ $(PYTHON) -c 'from compileall import *; compile_dir("$(DESTDIR)$(prefix)/Mailman", 20, "$(prefix)", 1)'
# Only run bin/update if we aren't installing in DESTDIR, as this
# means there are probably no lists to deal with, and it wouldn't

View File

@ -0,0 +1,70 @@
diff --git a/contrib/courier-to-mailman.py b/contrib/courier-to-mailman.py
index 922401f..572b47d 100644
--- a/contrib/courier-to-mailman.py
+++ b/contrib/courier-to-mailman.py
@@ -1,4 +1,4 @@
-#! /usr/bin/python
+#! /usr/bin/python2
# Configuration variables - Change these for your site if necessary.
#
diff --git a/tests/onebounce.py b/tests/onebounce.py
index 85f3b98..b54d075 100755
--- a/tests/onebounce.py
+++ b/tests/onebounce.py
@@ -1,4 +1,4 @@
-#! /usr/bin/python
+#! /usr/bin/python2
# Copyright (C) 2002-2018 by the Free Software Foundation, Inc.
#
diff --git a/bin/msgfmt.py b/bin/msgfmt.py
index 8a2d4e6..27a40bf 100755
--- a/bin/msgfmt.py
+++ b/bin/msgfmt.py
@@ -1,4 +1,4 @@
-#! /usr/bin/env python
+#!/usr/bin/python2
# -*- coding: iso-8859-1 -*-
# Written by Martin v. Löwis <loewis@informatik.hu-berlin.de>
diff --git a/Mailman/Archiver/pipermail.py b/Mailman/Archiver/pipermail.py
index cfca480..3d6a9d6 100644
--- a/Mailman/Archiver/pipermail.py
+++ b/Mailman/Archiver/pipermail.py
@@ -1,4 +1,4 @@
-#! /usr/bin/env python
+#! /usr/bin/python2
from __future__ import nested_scopes
diff --git a/Mailman/Archiver/pipermail.py.unicode b/Mailman/Archiver/pipermail.py.unicode
index 62fb92e..a663829 100644
--- a/Mailman/Archiver/pipermail.py.unicode
+++ b/Mailman/Archiver/pipermail.py.unicode
@@ -1,4 +1,4 @@
-#! /usr/bin/env python
+#! /usr/bin/python2
from __future__ import nested_scopes
diff --git a/Mailman/Post.py b/Mailman/Post.py
index 7f86696..b4dcfb0 100644
--- a/Mailman/Post.py
+++ b/Mailman/Post.py
@@ -1,4 +1,4 @@
-#! /usr/bin/env python
+#! /usr/bin/python2
#
# Copyright (C) 2001-2018 by the Free Software Foundation, Inc.
#
diff --git a/tests/fblast.py b/tests/fblast.py
index 092e420..905401d 100644
--- a/tests/fblast.py
+++ b/tests/fblast.py
@@ -1,4 +1,4 @@
-#! /usr/bin/env python
+#! /usr/bin/python2
"""Throw email at Mailman as fast as you can.
This is not a unit test, it's a functional test, so you can't run it within

2
mailman-tmpfiles.conf Normal file
View File

@ -0,0 +1,2 @@
d /var/lock/mailman 0775 root mailman
d /run/mailman 0775 root mailman

13
mailman-update-cfg Executable file
View File

@ -0,0 +1,13 @@
#!/usr/bin/python2
# This script is needed, when SELinux is enabled:
# mailman_mail_t context cannot write to the directory
# @mmdir@/Mailman so when you change mm_cfg.py,
# mailman cannot create the .pyc
#
# This script is called in the init script, which is run in unconfined_t
# so the .pyc is created and the AVC denial is avoided. (bz#481446)
import py_compile
py_compile.compile("@mmdir@/Mailman/mm_cfg.py")

476
mailman.INSTALL.REDHAT.in Normal file
View File

@ -0,0 +1,476 @@
This file contains instructions for how to complete the installation
of mailman after you have installed the Red Hat mailman RPM. There are
certain items you will need to manually configure as the RPM is not
capable of doing every installation and confirguration task.
First, you should note that the RPM has installed mailman in the
following directory:
@prefix@
You may want to examine this directory to find additional mailman
documentation, or other mailman files.
IMPORTANT NOTE FOR USERS UPGRADING FROM A PREVIOUS RED HAT MAILMAN
INSTALLATION OR THOSE FAMILAR WITH "STANDARD MAILMAN INSTALLATIONS"
Earlier Red Hat mailman rpms installed all of the mailman files under
/var/mailman. This did not conform to the Filesystem Hierarchy
Standard (FHS) and created security violations when SELinux is
enabled. As of mailman-2.1.5-21 the following directory and file
changes occurred:
variable data (e.g. lists) is in @VAR_PREFIX@, library code,
executables, and scripts are located in @prefix@, lock files are in
@LOCK_DIR@, the pid file is in @PID_DIR@, qfiles are in @QUEUE_DIR@,
and configuration files have been moved to the new @CONFIG_DIR@.
If you previously had mailman installed and have edited files in
/var/mailman (e.g. configuration) you will need to move those changes
to their new locations.
A script has been provided to aid in the task of migrating your
mailman datafiles, it is contrib/migrate-fhs, run with -h for help
information.
The mapping of old locations to new locations is as follows:
Directory Mapping:
/var/mailman --> /var/lib/mailman
/var/mailman/Mailman --> /usr/lib/mailman/Mailman
/var/mailman/archives --> /var/lib/mailman/archives
/var/mailman/bin --> /usr/lib/mailman/bin
/var/mailman/cgi-bin --> /usr/lib/mailman/cgi-bin
/var/mailman/cron --> /usr/lib/mailman/cron
/var/mailman/data --> /var/lib/mailman/data
/var/mailman/lists --> /var/lib/mailman/lists
/var/mailman/locks --> /var/lock/mailman
/var/mailman/logs --> /var/log/mailman
/var/mailman/mail --> /usr/lib/mailman/mail
/var/mailman/messages --> /usr/lib/mailman/messages
/var/mailman/pythonlib --> /usr/lib/mailman/pythonlib
/var/mailman/qfiles --> /var/spool/mailman
/var/spool/mailman/qfiles --> /var/spool/mailman
/var/mailman/scripts --> /usr/lib/mailman/scripts
/var/mailman/spam --> /var/lib/mailman/spam
/var/mailman/templates --> /usr/lib/mailman/templates
/var/mailman/tests --> /usr/lib/mailman/tests
File Mapping:
/var/mailman/data/adm.pw --> /etc/mailman/adm.pw
/var/mailman/data/creator.pw --> /etc/mailman/creator.pw
/var/mailman/data/aliases --> /etc/mailman/aliases
/var/mailman/data/virtual-mailman --> /etc/mailman/virtual-mailman
/var/mailman/data/sitelist.cfg --> /etc/mailman/sitelist.cfg
/var/mailman/data/master-qrunner.pid --> /var/run/mailman/master-qrunner.pid
Discussion of directory and file relocation:
Two new directories were created and three existing directories which
were hardcoded are now configurable.
PID_DIR is used to hold the process id and is new because FHS wants
pid files to be located in /var/run. The FHS says when there is only a
single pid file it should be located in /var/run/<name>.pid, and when
there are multiple pid's files they should be located together in a
subdirectory, /var/run/<name>/. Currently mailman only has a single
pid file, but it does have multiple processes (qrunners). Also SELinux
security policy is easier to write if processes are segregated into
individual subdirectories. Therefore we elected to place the mailman
pid file in its own subdirectory, there is some debate if this is 100%
FHS compliant because there is only currently a single pid file, but
this gives us greater future flexibility and is in the spirit of FHS.
CONFIG_DIR is used to hold the site configuration files. FHS wants
configuration files stored in /etc/mailman. Previously configuration
files were mixed in with data files in DATA_DIR and with the run-time
code (e.g. Mailman/mm_cfg.py). CONFIG_DIR continues to exist but is
now restricted to data files (e.g. python pickle files). The password
files, alias files, and .cfg (e.g. sitelist.cfg) files have been moved
to CONFIG_DIR. mm_cfg.py which is the primary mailman configuration
file was presented a bit of a dilemma. In theory it should be located
in /etc/mailman, however it is executable code which argues it should
be located with the other executable files, it has traditionally lived
in $PREFIX/Mailman and experienced mailman admins will expect to find
it there. Modifying all the mm_cfg import statements and paths.py was
believed to be too invasive a change, and technically its part of the
"Mailman" package and moving it would take it out of the package
(although currently I don't think that presents any known
issues). Instead a compromise approach was adopted, mm_cfg.py is
symbolically linked into the /etc/mailman directory pointing to
$PREFIX/Mailman/mm_cfg.py. Thus mm_cfg.py "appears" in the
configuration directory but retains its traditional location, this was
deemed a reasonable compromise for the mailman 2.1.x timeframe.
sitelist.cfg has a symbolic link in its old location in the DATA_DIR
pointing to its new location in the CONFIG_DIR.
New Directories (can be specified as parameter to configure):
CONFIG_DIR: default=$VAR_PREFIX/data FHS=/etc/mailman
PID_DIR default=$VAR_PREFIX/data FHS=/var/run/mailman
Existing directories that can now be specified as parameter to configure:
LOCK_DIR: default=$VAR_PREFIX/locks FHS=/var/lock/mailman
LOG_DIR: default=$VAR_PREFIX/logs FHS=/var/log/mailman
QUEUE_DIR default=$VAR_PREFIX/qfiles FHS=/var/spool/mailman
You can find addition documentation in the
@DOC_DIR@/README.* files and/or
@prefix@/README.* files.
Mailman is an open source project and full documentation, current
sources, patches, etc. can be found at the following official mailman
web sites:
http://www.gnu.org/software/mailman/mailman.html
http://www.list.org
1. Final installation instructions:
Congratulations! You've installed the Mailman software. To get
everything running you need to hook Mailman up to both your web
server and your mail system.
- If you plan on running your MTA and web server on different
machines, sharing Mailman installations via NFS, be sure that
the clocks on those two machines are synchronized closely. You
might take a look at the file Mailman/LockFile.py; the constant
CLOCK_SLOP helps the locking mechanism compensate for clock skew
in this type of environment.
- Configure your web server. The RPM has made the assumption you
are running the apache web server (httpd). The RPM has installed
a mailman config file (@HTTPD_CONF_FILE@) in @HTTPD_CONF_DIR@.
You should edit the file to set your domain, see the
instructions in the config file.
Now restart your web server so the new settings take effect:
% /sbin/service httpd restart
- Create the site password using:
% @prefix@/bin/mmsitepass <your-site-password>
This password can be used anywhere that individual user or
mailing list administrator passwords are required, giving the
mailman site administrator the ability to adjust these things
when necessary.
You may also want to create a password for the site-wide "list
creator" role (someone other than the site administrator who as
privileges to create and remove lists through the web). Use the
-c option to mmsitepass to set this.
- Set the values for DEFAULT_EMAIL_HOST and DEFAULT_URL_HOST in
@prefix@/Mailman/mm_cfg.py file if the fqdn of the host you are
running mailman on is not the email and url host you need to use.
- Update Mailman list files to new verson by running:
@prefix@/bin/update
Users upgrading from previous releases of this package may need
to move their data or adjust the configuration files to point to
the locations where their data is.
- Create a "site-wide" mailing list (Note: this must be done
before starting the mailman daemon). This is the one that
password reminders will appear to come from. Usually this
should be the "mailman" mailing list, but if you need to change
this, be sure to change the MAILMAN_SITE_LIST variable in
mm_cfg.py (see below).
% @prefix@/bin/newlist mailman
Follow the prompts, and see the README file for more
information.
- Start the Mailman qrunner daemon
As of mailman version 2.1 mailman requires a service (daemon) to be
run for mailman to operate. RedHat does not ship RPM's that enable
services as part of package installation. You will need to enable
the mailman service if you want mailman to run.
To enable the mailman service after package installation you may run
the "serviceconf" GUI tool, or you may do the following on the
command line as root.
/sbin/service mailman start
To have the mailman service automatically start at certain run
levels (replace the runlevel below with your desired run levels, for
example to start mailman at run levels 3 and 5 runlevel would be 35:
/sbin/chkconfig --level runlevel mailman on
- You should then subscribe yourself to the mailman list.
2. Customize Mailman
You should do these steps using the account you installed Mailman
under in section 2 above.
- The file @prefix@/Mailman/Defaults.py contains a number of
defaults for your installation. If any of these are incorrect,
override them in @prefix@/Mailman/mm_cfg.py.
DO NOT EDIT Defaults.py!
Note: If you have upgraded your mailman installation RPM will
save a copy of your previous version of mm_cfg.py in
mm_cfg.py.rpmsave.
See the comments in Defaults.py for details. Once a list is
created, editing many of these variables will have no effect.
At that point, you'll need to configure your lists through the
web admin interface or through the command line script
@prefix@/bin/withlist or @prefix@/bin/config_list.
Note: Do *not* change HOME_DIR or MAILMAN_DIR. These are set
automatically by the configure script when the RPM was created.
- Create the site password using:
% @prefix@/bin/mmsitepass <your-site-password>
This password can be used anywhere that individual user or
mailing list administrator passwords are required, giving the
mailman site administrator the ability to adjust these things
when necessary.
You may also want to create a password for the site-wide "list
creator" role (someone other than the site administrator who as
privileges to create and remove lists through the web). Use the
-c option to mmsitepass to set this.
3. Troubleshooting
If you encounter problems with running Mailman, first check the
"Common Problems" section, below. If your problem is not covered
there, check both the FAQ file and the online FAQ Wizard.
Check for errors in the mailman log files which can be found in
@LOG_DIR@
Mailman logs errors to this file:
@LOG_DIR@/error
If you encounter an error, send an error report to
mailman-users@python.org. Include a description of what you're
doing to cause the problem, and the relevant lines from your
syslog. Also include information on your operating system, which
version of Python you're using, and which version of Mailman
you're installing.
4. Common Problems
Problem: All Mailman web pages give a 404 File not found error.
Solution: Your web server has not been set up properly for handling
Mailman's cgi commands. Make sure you've:
1) Configured the web server to give permissions to
@prefix@/cgi-bin
2) Restarted the web server properly.
Consult your web server's documentation for instructions
on how to do these things.
Problem: All Mailman web pages give an "Internal Server Error".
Solution: The likely problem is that you are using the wrong GID or
UID for CGI scripts. Check your syslog. If you see, for
example, a line like:
Attempt to exec script with invalid gid 51, expected 99
You need to reinstall Mailman, and specify $CGI_GID to be 51,
as described in the installation instructions.
Problem: I send mail to the list, and get back mail saying the
list is not found!
Solution: You probably didn't add the necessary aliases to the system
alias database, given to you when you ran the newlist
command. If you did add them, you likely did not update
the alias database, or your system requires you to run
newaliases explicitly. Refer to section 5 above for
more information.
Problem: I send mail to the list, and get back mail saying,
"unknown mailer error".
Solution: The likely problem is that you are using the wrong GID or
UID for mail. Check your syslog. If you see, for
example, a line like:
Attempt to exec script with invalid gid 51, expected 99
You need to reinstall Mailman, and specify $MAIL_GID to
be 51, as described in the installation
instructions. see notes on Postfix below, as by default
it will create these problems on installation.
Problem: I use Postfix for my MTA and the mail wrapper programs
are logging complaints about the wrong GID.
Solution: Create a separate aliases file for Postfix in its
main.cf config file under the variable "alias_maps". Put
the file somewhere in Mailman's home directory, or
somewhere else where the user mailman has write access
to it; *as user mailman* call Postfix's "postalias" on the
alias file.
% postalias <the alias file>
Also as user mailman, run
% python -c'import os; print os.getgid()'
This should print out the group id that Mailman should
be configured to expect when the mail wrapper programs
are run. Call it "thegid". Rebuild Mailman with
% ./configure --with-mail-gid=thegid
See also the "Using the Postfix mail server" section of
the mailman installation manual for more information on
connecting Postfix and Mailman. The manual is available
in several formats at /usr/share/doc/mailman-*/admin/www.
Problem: I send mail to the list, and get back mail saying,
"sh: mailman not available for sendmail programs"
Solution: Your system uses sendmail restricted shell (smrsh). You
need to configure smrsh by creating a symbolic link from
the mail wrapper (@prefix@/mail/mailman) to the directory
identifying executables allowed to run under smrsh.
Some common names for this directory are
/var/admin/sm.bin, /usr/admin/sm.bin or /etc/smrsh.
Note that on Debian Linux, the system makes
/usr/lib/sm.bin, which is wrong, you will need to create
the directory /usr/admin/sm.bin and add the link there.
Note further any aliases newaliases spits out will need
to be adjusted to point to the secure link to the
wrapper.
Problem: I messed up when I called configure. How do I clean
things up and re-install?
Solution: % make clean
% ./configure --with-the-right-options
% make install
-------------------- Other Useful Information -----------------
RPM Preserves User Modified Files
---------------------------------
The rpm during installation will preserve changes you have made to
configuration files and templates from a previous installation. This
is almost always what is desired. However you may want to check for
the existence of files with either the .rpmsave or the .rpmnew
extension and verify if any of these backup files created during the
RPM install exist and if you are indeed using the version of the file
you desire.
Note: The installation directory for non-data files changed from
@VAR_PREFIX@ to @prefix@ in mailman-2.1.5-20. Configuration files and
templates that were user modified in a previous installation will need
to manually move those changes from the earlier @VAR_PREFIX@ to the
new @prefix@ installation directory.
Here are a few commands that will aid you in this process:
List any rpm backup files in the mailman installation directory:
% find @prefix@ @VAR_PREFIX@ -name '*.rpm*'
List any configuration files NOT in the mailman installation directory
you might miss with the above command which also have the potental for
backup copies. Given this short list you'll have to look for a
matching backup file.
% rpm -qc mailman | egrep -v '@prefix@|@VAR_PREFIX@'
When rpm preserves a user modified file it installs the newest version
of the file by appending the .rpmnew extension to the file name thus
preserving the file but making the latest version avialable. If rpm
replaces a user modified file the file being replaced is renamed to
have the .rpmsave extension. RPM only performs these backup operations
if the file is marked as being a configuration file in the rpm spec
file, it is not performed in general on all files in the package.
Mailman Cron Jobs:
------------------
Mailman relies on the cron daemon to schedule periodic actions. These
are contained in a crontab file. Previous versions of the mailman RPM
from Red Hat created the cron jobs by running the crontab(1) command
during the RPM installation phase. The cron jobs are now handled
slightly differently. Rather than invoking crontab which loaded the
cron jobs into a private cron file a mailman crontab file is installed
into /etc/cron.d. The crontab file and the commands it runs were
modified from the upstream distribution so these commands would run
under the correct SELinux security profile.
Previously the cron jobs were installed when the RPM was
installed. This was less than optimal because the act of having the
mailman RPM installed on a system should not cause the cron jobs to
run. A better solution is to only run the mailman cron jobs if the
mailman service is enabled. This is accomplished by installing the
mailman crontab file in /etc/cron.d when the mailman service is
started by mailman init.d script (e.g. either at boot time or via
/sbin/service). When the mailman service is stopped the crontab file
is removed from /etc/cron.d. The crontab file is copied from
@prefix@/cron/crontab.in to /etc/cron.d/mailman. Thus if you edit the
cron jobs you will need to edit the master copy in @prefix@/cron
otherwise your edits will be lost the next time the mailman service is
started or restarted. To pick up any changes made to the crontab file
edit the master copy in @prefix@/cron and then use /sbin/service to
restart mailman (e.g. /sbin/service mailman restart). Some may wonder
why the crontab file in /etc/cron.d is not symbolically linked to the
master copy when the service starts and unlinked when it stops. The
reason is because newer versions of cron will refuse for security
reasons to run any crontabs which are links to other files or
writeable by anybody else except root.
Choosing your MTA (sendmail or postfix) on Red Hat Systems:
-----------------------------------------------------------
Red Hat ships two different MTA's, sendmail and postfix. Because the
sendmail and postfix rpms's share file names when installed the
conflict is accomodated by utilizing the "alternatives" mechanism
which manages a set of links. When one of the MTA's is selected via
/usr/sbin/alternatives links are established which point to the
correct files for that MTA. There are two ways to select your MTA:
The system-switch-mail package contains a GUI front end to the
alternatives mechanism and /usr/bin/system-switch-mail is an easy way
to select your MTA, or you can invoke alternatives directly like this:
% /usr/sbin/alternatives --config mta
Note: Selecting your preferred MTA is distinct from configuring the
MTA, you will need to consult the documentation for the MTA you
selected for information on how to configure it.
Local Variables:
mode: indented-text
indent-tabs-mode: nil
End:

8
mailman.logrotate Normal file
View File

@ -0,0 +1,8 @@
@LOG_DIR@/bounce @LOG_DIR@/digest @LOG_DIR@/error @LOG_DIR@/post @LOG_DIR@/smtp @LOG_DIR@/smtp-failure @LOG_DIR@/qrunner @LOG_DIR@/locks @LOG_DIR@/fromusenet @LOG_DIR@/subscribe @LOG_DIR@/vette {
missingok
sharedscripts
su root root
postrotate
@MMDIR@/bin/mailmanctl reopen >/dev/null 2>&1 || true
endscript
}

20
mailman.service Normal file
View File

@ -0,0 +1,20 @@
[Unit]
Description=GNU Mailing List Manager
After=syslog.target network.target
[Service]
ExecStartPre=/usr/lib/mailman/bin/mailman-update-cfg
ExecStartPre=/usr/bin/install -m644 -o root -g root /usr/lib/mailman/cron/crontab.in /etc/cron.d/mailman
ExecStartPre=/bin/touch /var/log/mailman/error
ExecStartPre=/bin/chown mailman:mailman /var/log/mailman/error
ExecStartPre=/bin/chmod 660 /var/log/mailman/error
ExecStart=/usr/lib/mailman/bin/mailmanctl -s start
ExecReload=/usr/lib/mailman/bin/mailmanctl restart
ExecStop=/usr/lib/mailman/bin/mailman-update-cfg
ExecStop=/usr/lib/mailman/bin/mailmanctl stop
ExecStop=/bin/sh -c 'echo -e "# DO NOT EDIT THIS FILE!\n#\n# Contents of this file managed by /etc/init.d/mailman\n# Master copy is /usr/lib/mailman/cron/crontab.in" > /etc/cron.d/mailman'
Type=forking
[Install]
WantedBy=multi-user.target

1280
mailman.spec Normal file

File diff suppressed because it is too large Load Diff

100
mm_cfg.py Normal file
View File

@ -0,0 +1,100 @@
# -*- python -*-
# Copyright (C) 1998,1999,2000,2001,2002 by the Free Software Foundation, Inc.
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
"""This module contains your site-specific settings.
From a brand new distribution it should be copied to mm_cfg.py. If you
already have an mm_cfg.py, be careful to add in only the new settings you
want. Mailman's installation procedure will never overwrite your mm_cfg.py
file.
The complete set of distributed defaults, with documentation, are in the file
Defaults.py. In mm_cfg.py, override only those you want to change, after the
from Defaults import *
line (see below).
Note that these are just default settings; many can be overridden via the
administrator and user interfaces on a per-list or per-user basis.
"""
###############################################
# Here's where we get the distributed defaults.
from Defaults import *
import pwd, grp
##################################################
# Put YOUR site-specific settings below this line.
#ATTENTION: when you use SELinux, mailman might not
#be able to recompile the configuration file
#due to policy settings. If this is the case,
#please run (as root) the supplied "mailman-update-cfg" script
##############################################################
# Here's where we override shipped defaults with settings #
# suitable for the RPM package. #
MAILMAN_UID = pwd.getpwnam('mailman')[2]
MAILMAN_GID = grp.getgrnam('mailman')[2]
##############################################################
# Set URL and email domain names #
#
# Mailman needs to know about (at least) two fully-qualified domain
# names (fqdn)
#
# 1) the hostname used in your urls (DEFAULT_URL_HOST)
# 2) the hostname used in email addresses for your domain (DEFAULT_EMAIL_HOST)
#
# For example, if people visit your Mailman system with
# "http://www.dom.ain/mailman" then your url fqdn is "www.dom.ain",
# and if people send mail to your system via "yourlist@dom.ain" then
# your email fqdn is "dom.ain". DEFAULT_URL_HOST controls the former,
# and DEFAULT_EMAIL_HOST controls the latter. Mailman also needs to
# know how to map from one to the other (this is especially important
# if you're running with virtual domains). You use
# "add_virtualhost(urlfqdn, emailfqdn)" to add new mappings.
# Default to using the FQDN of machine mailman is running on.
# If this is not correct for your installation delete the following 5
# lines that acquire the FQDN and manually edit the hosts instead.
from socket import *
try:
fqdn = getfqdn()
except:
fqdn = 'mm_cfg_has_unknown_host_domains'
DEFAULT_URL_HOST = fqdn
DEFAULT_EMAIL_HOST = fqdn
# Because we've overriden the virtual hosts above add_virtualhost
# MUST be called after they have been defined.
add_virtualhost(DEFAULT_URL_HOST, DEFAULT_EMAIL_HOST)
##############################################################
# Put YOUR site-specific configuration below, in mm_cfg.py . #
# See Defaults.py for explanations of the values. #
# Note - if you're looking for something that is imported from mm_cfg, but you
# didn't find it above, it's probably in Defaults.py.

1
sources Normal file
View File

@ -0,0 +1 @@
SHA1 (mailman-2.1.29.tgz) = 40fe97974a6f0805a01d55c6944565f238778238