[Mailman-Developers] Separating executables from data

Dick Porter dick@acm.org
Mon, 3 May 1999 10:23:58 +0100


--oOB74oR0WcNeq9Zb
Content-Type: text/plain; charset=us-ascii


Attached is a patch against v1.0b11 which allows me to configure mailman
with all executables installed on a read-only filesystem.

The patch also has a few tests in configure.in nobbled, because I build
on a different machine to the one that runs lists. (The mailman uid and gid
tests seem to be superfluous anyway, as the only time the results are used
in the code is in a Makefile rule that is never called). The FQDN and URL
parameters have been hard-coded to a fixed string that I then edit with sed
on the target machine when I install the RPM. I have left these changes in for
completeness.

I also include my RPM spec file. It has some vaguely interesting parts that
are probably specific to my configuration (ie executables have to be in
a directory owned by root and not writable by anyone else, due to 
Trusted Path Execution patches, and the mm_cfg.py has to be on a writable
filesystem, hence the symlink into /etc)

Even if these patches don't make it into the code, I'd appreciate it if someone
could point out any potential problems with my configuration :-)

- Dick

PS I would have submitted these patches by jitterbug, but I couldn't see any
way of attaching files there.




--oOB74oR0WcNeq9Zb
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="mailman-1.0b11-uid+spool.patch"

diff -ur -x configure mailman-1.0b11-orig/Mailman/Defaults.py.in mailman-1.0b11/Mailman/Defaults.py.in
--- mailman-1.0b11-orig/Mailman/Defaults.py.in	Tue Mar 30 19:42:22 1999
+++ mailman-1.0b11/Mailman/Defaults.py.in	Thu Apr 29 11:54:07 1999
@@ -249,6 +249,7 @@
 PYTHON  	= '@PYTHON@'
 PREFIX  	= '@prefix@'
 EXEC_PREFIX	= '@exec_prefix@'
+SPOOL_PREFIX	= '@SPOOL_PREFIX@'
 
 # Work around a bogus autoconf 2.12 bug
 if EXEC_PREFIX == '${prefix}':
@@ -283,17 +284,17 @@
 ConcealSubscription = 16
 
 
-LIST_DATA_DIR	= os.path.join(PREFIX, 'lists')
+LIST_DATA_DIR	= os.path.join(SPOOL_PREFIX, 'lists')
 HTML_DIR	= os.path.join(PREFIX, 'public_html')
 CGI_DIR 	= os.path.join(EXEC_PREFIX, 'cgi-bin')
-LOG_DIR 	= os.path.join(PREFIX, 'logs')
-LOCK_DIR	= os.path.join(PREFIX, 'locks')
-DATA_DIR	= os.path.join(PREFIX, 'data')
+LOG_DIR 	= os.path.join(SPOOL_PREFIX, 'logs')
+LOCK_DIR	= os.path.join(SPOOL_PREFIX, 'locks')
+DATA_DIR	= os.path.join(SPOOL_PREFIX, 'data')
 WRAPPER_DIR	= os.path.join(EXEC_PREFIX, 'mail')
 SCRIPTS_DIR	= os.path.join(PREFIX, 'scripts')
 TEMPLATE_DIR	= os.path.join(PREFIX, 'templates')
-PUBLIC_ARCHIVE_FILE_DIR 	= os.path.join(PREFIX, 'archives/public')
-PRIVATE_ARCHIVE_FILE_DIR	= os.path.join(PREFIX, 'archives/private')
+PUBLIC_ARCHIVE_FILE_DIR 	= os.path.join(SPOOL_PREFIX, 'archives/public')
+PRIVATE_ARCHIVE_FILE_DIR	= os.path.join(SPOOL_PREFIX, 'archives/private')
 
 # The Mailman version, also set by configure
 VERSION           = "1.0b11"
diff -ur -x configure mailman-1.0b11-orig/Makefile.in mailman-1.0b11/Makefile.in
--- mailman-1.0b11-orig/Makefile.in	Tue Mar 23 16:56:40 1999
+++ mailman-1.0b11/Makefile.in	Thu Apr 29 13:47:24 1999
@@ -27,6 +27,7 @@
 bindir=		@bindir@
 prefix=		@prefix@
 exec_prefix=	@exec_prefix@
+SPOOL_PREFIX=	@SPOOL_PREFIX@
 
 CC=		@CC@
 INSTALL=	@INSTALL@
@@ -41,11 +42,11 @@
 OPT=		@OPT@
 CFLAGS=		$(OPT) $(DEFS)
 
-ARCH_INDEP_DIRS=	logs archives bin \
-	lists locks templates scripts filters cron data \
-	archives/private archives/public \
+ARCH_INDEP_DIRS=	bin \
+	templates scripts filters cron \
 	Mailman Mailman/Cgi Mailman/Logging Mailman/Archiver Mailman/pythonlib
 ARCH_DEP_DIRS=	cgi-bin mail
+SPOOL_DIRS=	logs archives lists locks data archives/private archives/public
 
 # Directories make should decend into
 SUBDIRS=	bin cron filters mail misc Mailman scripts src templates
@@ -84,7 +85,19 @@
 	    else true; \
 	    fi; \
 	done
-	chmod o-r $(prefix)/archives/private
+	@echo "Creating spool directories..."
+	@for d in $(SPOOL_DIRS); \
+	do \
+	    dir=$(SPOOL_PREFIX)/$$d; \
+	    if test ! -d $$dir; then \
+		echo "Creating directory hierarchy $$dir"; \
+		./mkinstalldirs $$dir; \
+		chmod $(DIRMODE) $$dir; \
+		$(DIRSETGID) $$dir; \
+	    else true; \
+	    fi; \
+	done
+	chmod o-r $(SPOOL_PREFIX)/archives/private
 	@echo "Creating architecture dependent directories..."
 	@for d in $(ARCH_DEP_DIRS); \
 	do \
@@ -101,7 +114,7 @@
 	do \
 	    (cd $$d; $(MAKE) install); \
 	done
-	$(PYTHON) -c 'import compileall; compileall.compile_dir("$(prefix)")'
+	#$(PYTHON) -c 'import compileall; compileall.compile_dir("$(prefix)")'
 	@echo "*****"
 	@echo "***** If you are installing over an old installation, please"
 	@echo "***** run \"make update\".  See the UPGRADING file for details."
diff -ur -x configure mailman-1.0b11-orig/configure.in mailman-1.0b11/configure.in
--- mailman-1.0b11-orig/configure.in	Sun Feb 28 00:24:21 1999
+++ mailman-1.0b11/configure.in	Thu Apr 29 11:54:07 1999
@@ -167,82 +167,82 @@
 rm -f conftest.out conftest.py])
 
 # User `mailman' must exist
-AC_MSG_CHECKING(for mailman UID)
-MM_FIND_USER_ID(MAILMAN_UID, mailman)
-if test -z "$MAILMAN_UID"
-then
-    AC_MSG_ERROR([
-***** No \"mailman\" user found!
-***** Your system must have a \"mailman\" user defined (usually
-***** in your /etc/passwd file).  Please see the INSTALL file
-***** file details.])
-fi
+#AC_MSG_CHECKING(for mailman UID)
+#MM_FIND_USER_ID(MAILMAN_UID, mailman)
+#if test -z "$MAILMAN_UID"
+#then
+#    AC_MSG_ERROR([
+#***** No \"mailman\" user found!
+#***** Your system must have a \"mailman\" user defined (usually
+#***** in your /etc/passwd file).  Please see the INSTALL file
+#***** file details.])
+#fi
 
 
 # Group `mailman' must exist
-AC_MSG_CHECKING(for mailman GID)
-MM_FIND_GROUP_ID(MAILMAN_GID, mailman)
-if test -z "$MAILMAN_GID"
-then
-    AC_MSG_ERROR([
-***** No \"mailman\" group found!
-***** Your system must have a \"mailman\" group defined (usually
-***** in your /etc/group file).  Please see the INSTALL file
-***** file details.])
-fi
+#AC_MSG_CHECKING(for mailman GID)
+#MM_FIND_GROUP_ID(MAILMAN_GID, mailman)
+#if test -z "$MAILMAN_GID"
+#then
+#    AC_MSG_ERROR([
+#***** No \"mailman\" group found!
+#***** Your system must have a \"mailman\" group defined (usually
+#***** in your /etc/group file).  Please see the INSTALL file
+#***** file details.])
+#fi
 
 
 # Now make sure that $prefix is set up correctly.  It must be group
 # owned by `mailman', it must have the group sticky bit set, and it
 # must be a+rx
-if test "$prefix" = "NONE"
-then
-    prefixcheck=$ac_default_prefix
-else
-    prefixcheck=$prefix
-fi
-
-AC_MSG_CHECKING(permissions on $prefixcheck)
-changequote(,)
-cat > conftest.py <<EOF
-import os, grp, string
-from stat import *
-prefix = "$prefixcheck"
-mailmangid = $MAILMAN_GID
-problems = []
-try: statdata = os.stat(prefix)
-except os.error:
-    problems.append("Directory doesn't exist: " + prefix)
-else:    
-    mode = statdata[ST_MODE]
-    gid = statdata[ST_GID]
-    if mailmangid <> gid:
-	problems.append("Directory must be owned by group mailman: " + prefix)
-    if (mode & S_ISGID) <> S_ISGID:
-	problems.append("Set-gid bit must be set for directory: " +prefix)
-    perms = S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH
-    if (mode & perms) <> perms:
-	problems.append("Permissions should be at least 0775: " + prefix)
-if not problems:
-    msg = "okay\n"
-else:
-    msg = '***** ' + string.join(problems, '\n***** ') + '\n'
-fp = open("conftest.out", "w")
-fp.write(msg)
-fp.close()
-EOF
-changequote([, ])
-$PYTHON conftest.py
-status=`cat conftest.out`
-rm -f conftest.out conftest.py
-if test "$status" != "okay"
-then
-    AC_MSG_ERROR([
-***** Installation directory $prefixcheck is not configured properly!
-$status])
-fi
-
-AC_MSG_RESULT(okay)
+#if test "$prefix" = "NONE"
+#then
+#    prefixcheck=$ac_default_prefix
+#else
+#    prefixcheck=$prefix
+#fi
+
+#AC_MSG_CHECKING(permissions on $prefixcheck)
+#changequote(,)
+#cat > conftest.py <<EOF
+#import os, grp, string
+#from stat import *
+#prefix = "$prefixcheck"
+#mailmangid = $MAILMAN_GID
+#problems = []
+#try: statdata = os.stat(prefix)
+#except os.error:
+#    problems.append("Directory doesn't exist: " + prefix)
+#else:    
+#    mode = statdata[ST_MODE]
+#    gid = statdata[ST_GID]
+#    if mailmangid <> gid:
+#	problems.append("Directory must be owned by group mailman: " + prefix)
+#    if (mode & S_ISGID) <> S_ISGID:
+#	problems.append("Set-gid bit must be set for directory: " +prefix)
+#    perms = S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH
+#    if (mode & perms) <> perms:
+#	problems.append("Permissions should be at least 0775: " + prefix)
+#if not problems:
+#    msg = "okay\n"
+#else:
+#    msg = '***** ' + string.join(problems, '\n***** ') + '\n'
+#fp = open("conftest.out", "w")
+#fp.write(msg)
+#fp.close()
+#EOF
+#changequote([, ])
+#$PYTHON conftest.py
+#status=`cat conftest.out`
+#rm -f conftest.out conftest.py
+#if test "$status" != "okay"
+#then
+#    AC_MSG_ERROR([
+#***** Installation directory $prefixcheck is not configured properly!
+#$status])
+#fi
+#
+#AC_MSG_RESULT(okay)
 
 
 # Now find the UIDs and GIDs
@@ -314,47 +314,49 @@
 # figure out the DEFAULT_HOST_NAME and DEFAULT_URL
 AC_SUBST(FQDN)
 AC_SUBST(URL)
-changequote(,)
-cat > conftest.py <<EOF
+#changequote(,)
+#cat > conftest.py <<EOF
 # attempt to figure out the default hostname and URL
-from socket import *
-import string
-fqdn = None
-www = None
-host, aliases, ipaddrs = gethostbyaddr(gethostbyname(gethostname()))
-aliases.insert(0, host)
-for h in aliases:
-    parts = string.split(h, '.')
-    if len(parts) > 1:
-        if parts[0] == 'www':
-            www = h
-        elif not fqdn:
-            fqdn = h
-fp = open('conftest.out', 'w')
-if not www and fqdn:
-    fp.write('%s\n%s\n' % (fqdn, fqdn))
-elif www:
-    dhn = string.join(string.split(www, '.')[1:], '.')
-    fp.write('%s\n%s\n' % (dhn, www))
-else:
-    fp.write('please.change.me\nwww.please.change.me\n')
-fp.close()
-EOF
-$PYTHON conftest.py
-changequote([, ])
-AC_MSG_CHECKING(for default fully qualified host name)
-if test -z "$FQDN"
-then
-    FQDN=`head -1 conftest.out`
-fi
-AC_MSG_RESULT($FQDN)
-AC_MSG_CHECKING(for default URL host component)
-if test -z "$URL"
-then
-    URL=`tail -1 conftest.out`
-fi
-AC_MSG_RESULT($URL)
-rm -f conftest.out conftest.py
+#from socket import *
+#import string
+#fqdn = None
+#www = None
+#host, aliases, ipaddrs = gethostbyaddr(gethostbyname(gethostname()))
+#aliases.insert(0, host)
+#for h in aliases:
+#    parts = string.split(h, '.')
+#    if len(parts) > 1:
+#        if parts[0] == 'www':
+#            www = h
+#        elif not fqdn:
+#            fqdn = h
+#fp = open('conftest.out', 'w')
+#if not www and fqdn:
+#    fp.write('%s\n%s\n' % (fqdn, fqdn))
+#elif www:
+#    dhn = string.join(string.split(www, '.')[1:], '.')
+#    fp.write('%s\n%s\n' % (dhn, www))
+#else:
+#    fp.write('please.change.me\nwww.please.change.me\n')
+#fp.close()
+#EOF
+#$PYTHON conftest.py
+#changequote([, ])
+#AC_MSG_CHECKING(for default fully qualified host name)
+#if test -z "$FQDN"
+#then
+#    FQDN=`head -1 conftest.out`
+#fi
+#AC_MSG_RESULT($FQDN)
+#AC_MSG_CHECKING(for default URL host component)
+#if test -z "$URL"
+#then
+#    URL=`tail -1 conftest.out`
+#fi
+#AC_MSG_RESULT($URL)
+#rm -f conftest.out conftest.py
+FQDN='$DOMAINNAME'
+URL='$HOSTNAME'
 
 # Checks for libraries.
 AC_CHECK_FUNCS(strerror)
@@ -370,6 +372,19 @@
 
 # Checks for library functions.
 AC_FUNC_VPRINTF
+
+# Check for spool prefix, to place writable files in a different hierarchy
+# to scripts.
+AC_SUBST(SPOOL_PREFIX)
+AC_ARG_WITH(spool-prefix, dnl
+[  --spool-prefix	specify destination for writable files])
+if test -z "$with_spool_prefix"
+then
+	SPOOL_PREFIX=$prefix
+	with_spool_prefix='no'
+else
+	SPOOL_PREFIX=$with_spool_prefix
+fi
 
 dnl Output everything
 AC_OUTPUT([misc/paths.py Mailman/Defaults.py Mailman/mm_cfg.py.dist

--oOB74oR0WcNeq9Zb
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="mailman.spec"

Summary: Mailman mailing list manager
Name: mailman
Version: 1.0b11
Release: 1
Source: http://www.list.org/mailman.tar.gz
Patch0: mailman-1.0b11-uid+spool.patch
Buildroot: /tmp/mailman-build/
Copyright: GPL
Group: Mail/List
Prereq: python

%description
Mailman mailing list manager

%prep
%setup
%patch0 -p1 -b .uid

%build
autoconf
CFLAGS="$RPM_OPT_FLAGS" LDFLAGS=-s ./configure --prefix=/usr/share/mailman --exec-prefix=/usr/lib/mailman --with-spool-prefix=/var/spool/mailman --with-mail-gid=99
make

%install
rm -rf $RPM_BUILD_ROOT
export RPM_BUILD_ROOT
mkdir -p $RPM_BUILD_ROOT/etc/mailman

make exec_prefix=$RPM_BUILD_ROOT/usr/lib/mailman prefix=$RPM_BUILD_ROOT/usr/share/mailman SPOOL_PREFIX=$RPM_BUILD_ROOT/var/spool/mailman install

mv $RPM_BUILD_ROOT/usr/share/mailman/Mailman/mm_cfg.py $RPM_BUILD_ROOT/etc/mailman
ln -s /etc/mailman/mm_cfg.py $RPM_BUILD_ROOT/usr/share/mailman/Mailman/mm_cfg.py
cp $RPM_BUILD_ROOT/etc/mailman/mm_cfg.py $RPM_BUILD_ROOT/etc/mailman/mm_cfg.py-base

%clean
rm -rf $RPM_BUILD_ROOT

%post
/usr/bin/python -c 'import compileall; compileall.compile_dir("/usr/share/mailman")' >/dev/null 2>&1 
/usr/bin/python -c 'import compileall; compileall.compile_dir("/usr/lib/mailman/mail")' >/dev/null 2>&1 

%files
%defattr(-, root, root, 755)
/etc/mailman/mm_cfg.py
/etc/mailman/mm_cfg.py-base

/usr/share/mailman/Mailman
/usr/share/mailman/bin
/usr/share/mailman/cron
/usr/share/mailman/filters
/usr/share/mailman/scripts
/usr/share/mailman/templates

%dir /usr/lib/mailman/cgi-bin
%dir /usr/lib/mailman/mail
#/usr/lib/mailman/mail/paths.py

%defattr(2755, root, mailman, 755)
/usr/lib/mailman/cgi-bin/*
/usr/lib/mailman/mail/wrapper

%attr(2755, nobody, mailman) %dir /var/spool/mailman/archives
%attr(2751, nobody, mailman) %dir /var/spool/mailman/archives/private
%attr(2755, nobody, mailman) %dir /var/spool/mailman/archives/public

%attr(2755, nobody, mailman) %dir /var/spool/mailman/data
%attr(2755, nobody, mailman) %dir /var/spool/mailman/lists
%attr(2755, nobody, mailman) %dir /var/spool/mailman/logs
%attr(2755, nobody, mailman) %dir /var/spool/mailman/locks


--oOB74oR0WcNeq9Zb--