[prev in list] [next in list] [prev in thread] [next in thread] 

List:       majordomo-workers
Subject:    Using majordomo 1.94.3 and qmail
From:       John R Levine <johnl () iecc ! com>
Date:       1997-07-18 1:05:08
[Download RAW message or body]

There seems to be considerable interest in how to make qmail coexist with 
majordomo.  Here's how I do it.  This may seem awfully complicated, but
any majordomo list needs a slew of mail aliases for the list, the
outgoing list (since majordomo uses the local MTA for actual
delivery), -request, -owner, and -approval.

I applied the majordomo+qmail patches floating around the net.  They're quite
small, and just force the majordomo strip option on (so subscriber addresses
are stored without and comments or extra punctuation), and disallow addresses
without @ signs.  There's a bunch of other stuff in that patch package 
which I didn't use.

I wanted to set up majordomo to be reasonably secure, at least so that 
people can't send mail to any of the lists other than via majordomo, 
i.e., no secret aliases you can send to if you know what their names are.

I made a majordom user which owns all the majordomo stuff.  Qmail lets
you override the default delivery instructions for a user, so I told
it to exclude majordom from the default, by listing it in
/var/qmail/users/exclude, and provided for majordom-* users by adding
this line to /var/qmail/users/append:

+majordom-:majordom:85:85:/var/majordomo:-::

(In qmail-ese, this means that majordom@iecc.com is an invalid
address, but majordom-blah@iecc.com will be delivered according to the
instructions in /var/majordomo/.qmail-blah, using the user ID of majordom.)

To create a list called, say, test@iecc.com, I do the following (or 
rather, my script does this):

- make /var/majordomo/lists/test, containing at the beginning:

> mjvalidate
> cd /usr/local/lib/majordomo-1.94.3; ./wrapper digest -r -C -l test-digest \
> majordom-testdigest-out
+list

The first is a security thing described later, the second is optional
if there's a digest, the third tells qmail that all following
addresses have to be actual addresses, no files or shell commands.

- make lists/config with reasonable defaults

- if there's a digest, make lists/test-digest with

> mjvalidate
+list

- if there's a digest, make lists/test-digest-config with reasonable
defaults and directories lists/test-digest.archive and digest/test-digest

- make outgoing alias /var/majordomo/.qmail-test-out a symlink to lists/test

- make /var/majordomo/.qmail-test-out-owner contain the list manager's
name

- make /var/majordomo/.qmail-test-out-owner-default run a script to
handle bounces.  (Qmail puts a per-recipient envelope address with the
recipient's address embedded so for each bounce you can tell which
address it was sent to.

- if there's a digest, make /var/majordomo/.qmail-test-digest-out a
symlink to the digest list, /var/majordomo/.qmail-test-digest-out-owner
and  /var/majordomo/.qmail-test-digest-out-owner-default similar to
the non-digest versions

- if there's a digest, add a line to a script file run every night by
cron to force out any waiting digest (see script below)

(the following have to be done as root, my script writes a shell
script to be run as su)

- make ~alias/.qmail-test, the list submission address, containing:

> cd /usr/local/lib/majordomo-1.94.3; ./wrapper resend -l test majordom-test-out

- make ~alias/.qmail-test-request, containing:

> cd /usr/local/lib/majordomo-1.94.3; ./wrapper majordomo -l test

- make ~alias/.qmail-test-owner, .qmail-owner-test, and
.qmail-test-approval all for the list owner

- if there's a digest, make the analogous files for test-digest,
test-digest-owner, owner-test-digest, test-digest-request, and test-digest-approval.


The mjvalidate script is very simple, it just reads the first header
which must be a Received: line and checks that the message came
locally from majordom, not from the network or any other user, and
exits 100 (which tells qmail to abandon the delivery) if the test
fails.


I automated the entire list creation process with the script below.
It has one more complication that I didn't mention before -- it does
virtual domains.  Qmail handles virtual domains by delivering
user@vdom.com to the address vdom-user (the exact prefix is
configurable.)  I have MJD running in four virtual domains, the setup
is the same as for the real domains except that the .qmail filenames
are changed appropriately and the calls to MJD use a "-C vdom.cf" to
set the config file appropriately for the domain.

This works very nicely.  I can create a new MJD list with or without a
digest in about two minutes.

Regards,
John Levine, johnl@iecc.com, Primary Perpetrator of "The Internet for Dummies",
Information Superhighwayman wanna-be, http://iecc.com/johnl, Sewer Commissioner
Finger for PGP key, f'print = 3A 5B D0 3F D9 A0 6A A4  2D AC 1E 9E A6 36 A3 47 

-- begin list creation script --
#!/bin/bash

case "$1" in -d) digest=yes; shift ;; esac

dom=${1:?"Need domain as first argument"}
list=${2:?"Need listname as second argument"}
manager=${3:-manager}

case "$dom" in
iecc)    conf= dconf= dir=lists  qmd=~alias/.qmail domain= dom= 
	 dig=digest ;; # special

gurus)   conf="-C gurus.cf" dir=gurus-lists qmd=~johnl/virtual/.qmail-gurus
	 dconf="-c gurus.cf" dig=gurus-digest domain=@gurus.com ;;

abuse) conf="-C abuse.cf" dir=abuse-lists qmd=~johnl/virtual/.qmail-abuse
	 dconf="-c abuse.cf" dig=abuse-digest domain=@abuse.net ;;

services) conf="-C services.cf" dir=services-lists qmd=~johnl/virtual/.qmail-services
	 dconf="-c services.cf" dig=services-digest domain=@services.net ;;

*) echo "Mystery domain $dom"; exit 1 ;;
esac

cd /var/majordomo

echo "making list"

if [ -s $dir/$list ]
then
	echo "list already exists, editing in checks"
else
	touch $dir/$list
fi

{
echo "| mjvalidate"
[ "$digest" ] &&
echo "| cd /usr/local/lib/majordomo-1.94.3; ./wrapper digest $dconf -r -C -l \
$list-digest majordom-$dom${list}digest-out" echo "+list"
egrep -v "mjvalidate|+list|lib/majordomo" $dir/$list
} > /tmp/l$$

cp /tmp/l$$ $dir/$list && rm /tmp/l$$
chmod 644 $dir/$list

# make the config file

if [ -s $dir/$list.config ]
then
	echo "config exists, not changed"
else
	echo "making config file"
	echo "subscribe_policy = open+confirm" > $dir/$list.config
	if [ "$digest" ]
	then
		echo "restrict_post = $list:$list-digest"
	else
		echo "restrict_post = $list"
	fi >> $dir/$list.config
fi

if [ "$digest" ]
then
	echo making digest files
	if [ -s $dir/$list-digest ]
	then
		echo "digest already exists, editing in checks"
	else
		touch $dir/$list-digest
	fi

	{
	echo "| mjvalidate"
	echo "+list"
	egrep -v "mjvalidate|+list" $dir/$list-digest
	} > /tmp/l$$

	cp /tmp/l$$ $dir/$list-digest && rm /tmp/l$$

	if [ -s $dir/$list-digest.config ]
	then
		echo "digest config exists, not changed"
	else
		echo making digest config file
		cat > $dir/$list-digest.config <<EOF
subscribe_policy = open+confirm
digest_issue      =   1
digest_volume     =   1
digest_name       =   $list-digest
message_fronter << END
In this issue:
-
-    _SUBJECTS_
-
END
reply_to          =   $list
EOF
	fi

	[ -d $dir/$list-digest.archive ] || mkdir -p $dir/$list-digest.archive
	echo "editing in nightly resend"

	grep -v "$list-digest" send-digests > /tmp/l$$
	echo "./wrapper digest $dconf -m -C -l $list-digest majordom-$dom${list}digest-out" \
>> /tmp/l$$  cp /tmp/l$$ send-digests && rm /tmp/l$$
	[ -d $dig/$list-digest ] || mkdir -p $dig/$list-digest
fi

echo "Make a $list.info file someday"

# now make the qmail files

# making majordomo aliases
rm -f .qmail-$dom$list-out
ln -s ~majordom/$dir/$list .qmail-$dom$list-out
echo $manager > .qmail-$dom$list-out-owner
echo "| ./mjbounce ${dom:-''} $list \"\$EXT4\"" > .qmail-$dom$list-out-owner-default

if [ "$digest" ]
then
rm -f .qmail-$dom${list}digest-out
ln -s ~majordom/$dir/$list-digest .qmail-$dom${list}digest-out
echo $manager > .qmail-$dom${list}digest-out-owner
echo "| ./mjbounce ${dom:-''} $list-digest \"\$EXT4\"" > \
.qmail-$dom${list}digest-out-owner-default fi

echo "making qmail file script for visible addresses"

cat > /tmp/make-qmail-$dom-$list << EOF
# submission address
echo "| cd /usr/local/lib/majordomo-1.94.3; ./wrapper resend $conf -l $list \
majordom-$dom$list-out" > $qmd-$list

# request
echo "| cd /usr/local/lib/majordomo-1.94.3; ./wrapper majordomo $conf -l $list" > \
$qmd-$list-request

# owner
echo $manager > $qmd-$list-owner
rm -f  $qmd-owner-$list $qmd-$list-approval
ln $qmd-$list-owner $qmd-owner-$list
ln $qmd-$list-owner $qmd-$list-approval
EOF

if [ "$digest" ]
then
	cat <<EOF >> /tmp/make-qmail-$dom-$list

# digest files
# submission address
rm -f $qmd-$list-digest
ln $qmd-$list $qmd-$list-digest

# request
echo "| cd /usr/local/lib/majordomo-1.94.3; ./wrapper majordomo $conf -l \
$list-digest" > $qmd-$list-digest-request

# owner
rm -f $qmd-$list-digest-owner $qmd-owner-$list-digest $qmd-$list-digest-approval
echo $manager > $qmd-$list-digest-owner
ln $qmd-$list-digest-owner $qmd-owner-$list-digest
ln $qmd-$list-digest-owner $qmd-$list-digest-approval
EOF
fi
--end list creation script--

--begin mjvalidate--
#!/usr/bin/perl5
# make sure this is direct from majordomo

$mjid = getpwnam("majordom");

$checkline = <STDIN>;

exit 0 if $checkline =~ /\(qmail \d+ invoked by uid $mjid\)/;

print "You cannot send mail to this address.\n";
exit 100;
--end mjvalidate--


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic