diff options
| author | bwarsaw | 2001-10-27 02:30:51 +0000 |
|---|---|---|
| committer | bwarsaw | 2001-10-27 02:30:51 +0000 |
| commit | 5cb873cf88b637d77654564b73c018986923ea26 (patch) | |
| tree | 697586beda6d4e0648f6b5f0633de60dea86a988 | |
| parent | f01a6bdf7e21005da0fd36b3d99b2e779795d39d (diff) | |
| download | mailman-5cb873cf88b637d77654564b73c018986923ea26.tar.gz mailman-5cb873cf88b637d77654564b73c018986923ea26.tar.zst mailman-5cb873cf88b637d77654564b73c018986923ea26.zip | |
David Champion's contribution for better Sendmail/Mailman integration
| -rw-r--r-- | contrib/mailman.mc | 143 | ||||
| -rw-r--r-- | contrib/mm-handler | 223 | ||||
| -rw-r--r-- | contrib/mm-handler.readme | 151 | ||||
| -rw-r--r-- | contrib/virtusertable | 37 |
4 files changed, 554 insertions, 0 deletions
diff --git a/contrib/mailman.mc b/contrib/mailman.mc new file mode 100644 index 000000000..fc39edbdc --- /dev/null +++ b/contrib/mailman.mc @@ -0,0 +1,143 @@ +dnl +dnl *** EXAMPLE *** sendmail.mc file for a Mailman list server using +dnl mm-handler to deal with list operations (in place of aliases). +dnl This is what I actually use on my site. +dnl +dnl $Id: mailman.mc 4287 2001-10-27 02:30:51Z bwarsaw $ +dnl + + +dnl +dnl First you need to define your general characteristics. You +dnl should know what these settings should be at your site -- I +dnl only know what they should be at mine. +dnl +OSTYPE(solaris2)dnl +DOMAIN(generic)dnl + +dnl +dnl You can keep the old alias files for back-compatibility, but it's +dnl probably better not to as this can become a point of confusion +dnl later. +dnl +define(`ALIAS_FILE', `/etc/mail/aliases,/etc/mail/lists') + +dnl +dnl I use procmail for local delivery, because it's smart to have a +dnl local delivery mailer, even if you don't (ordinarily) do any local +dnl delivery. The Solaris local delivery mailer is part of its sendmail +dnl package. I pkgrmed the sendmail packages so that system upgrades +dnl don't kill my sendmail.com sendmail, so mail.local is unavailable, +dnl so I throw procmail in here even though it never gets used. +dnl +define(`PROCMAIL_MAILER_PATH', `/opt/bin/procmail') +FEATURE(`local_procmail') +MAILER(`local') + +dnl +dnl Miscellaneous tuning. Not relevant to Mailman. +dnl +define(`confCONNECTION_RATE_THROTTLE', 5) +define(`confMAX_MESSAGE_SIZE', `5000000') +define(`confNO_RCPT_ACTION', `add-to-undisclosed') +define(`confME_TOO', `True') +define(`confDOUBLE_BOUNCE_ADDRESS', `mailer-daemon') + +dnl +dnl Privacy options. Also not relevant. +dnl +define(`confPRIVACY_FLAGS', `authwarnings,needvrfyhelo,noexpn,noreceipts,restrictmailq') + + +dnl +dnl Mm-handler works by mailertabling all addresses on your list +dnl server hostname(s) through the mm-handler mailer. Mailertable +dnl maps mail domains to mailer types. I want a mailertable to map +dnl listtest.uchicago.edu to the mm-handler mailer, but we need to +dnl specifically request this functionality in the .mc file. +dnl +FEATURE(`mailertable', `hash -o /etc/mail/mailertable') + +dnl +dnl This leads to an immediate and important side-effect: "local" +dnl addresses, and notably RFC-specified addresses such as postmaster, +dnl are assumed by sendmail to be lists! Since aliases are not processed +dnl for domaintabled domains, we must use a virtusertable to reroute +dnl such addresses. +dnl +FEATURE(`virtusertable', `hash -o /etc/mail/virtusertable') + +dnl +dnl By default, sendmail applies virtusertable mapping, if at all, for +dnl all interfaces for which it accepts mail -- i.e., all domains in +dnl $=w. Mm-handler relies on your having a single domain (hostname) +dnl that serves only lists, with no users. To avoid potential namespace +dnl conflicts, you need not to have this list domain included in $=w. +dnl As a result, virtuser mapping does not apply for the Mailman +dnl list domain. However, you can pre-empt this rule by defining +dnl $={VirtHost}: if there are domains in this class, they will be +dnl mapped before $=w is mapped. +dnl +dnl VIRTUSER_DOMAIN() defines this class. +dnl +VIRTUSER_DOMAIN(`nospam.uchicago.edu listtest.uchicago.edu listhost.uchicago.edu') + +dnl +dnl On a related point: by default, Sendmail probes for open IP +dnl interfaces, and adds their hostnames to $=w. Although Sendmail does +dnl virtusertable mapping for members of $=w, it doesn't do mailertable +dnl mapping for them, because they're considered "local". This tells +dnl Sendmail not to probe interfaces for local hosts, and it's critical +dnl if your Mailman domain is actually an IP address (with an A record, +dnl not just CNAME or MX) on your server. +dnl +define(`confDONT_PROBE_INTERFACES', `True') + + +dnl +dnl Even though my actual hostname is foobar, tell the world that I'm +dnl listtest.uchicago.edu. +dnl +FEATURE(`limited_masquerade') +MASQUERADE_AS(`listtest.uchicago.edu') + + +dnl +dnl Access control is a useful feature for blocking abusers and relays +dnl and such. +dnl +FEATURE(`access_db') + + +dnl +dnl This allows you to block access for individual recipents through +dnl the same access database as is used for blocking sender hosts and +dnl addresses. +dnl +FEATURE(`blacklist_recipients') + + +dnl +dnl Other local mailers... +dnl +MAILER(`smtp') +MAILER(`procmail') + + +dnl +dnl Our Mailman-specific local mailer. +dnl +MAILER_DEFINITIONS +#################################### +### New Mailer specifications ### +#################################### + +## Special flags! See +## http://www.sendmail.org/~ca/email/doc8.10/op-sh-5.html#sh-5.4 +## Note especially the absence of the "m" and "n" flags. THIS IS +## IMPORTANT: mm-handler assumes this behavior to avoid having to know +## too much about address parsing and other RFC-2822 mail details. + +Mmailman, P=/etc/mail/mm-handler, F=rDFMhlqSu, U=mailman:other, + S=EnvFromL, R=EnvToL/HdrToL, + A=mm-handler $h $u diff --git a/contrib/mm-handler b/contrib/mm-handler new file mode 100644 index 000000000..4e844298a --- /dev/null +++ b/contrib/mm-handler @@ -0,0 +1,223 @@ +#!/opt/bin/perl +## +## Sendmail mailer for Mailman +## + +## Simulates these aliases: +## testlist: "|/opt/pkgs/mailman/mail/wrapper post testlist" +## testlist-admin: "|/opt/pkgs/mailman/mail/wrapper mailowner testlist" +## testlist-request: "|/opt/pkgs/mailman/mail/wrapper mailcmd testlist" +## owner-testlist: testlist-admin +## testlist-owner: testlist-admin + +## Some assembly required. +$MMWRAPPER = "/opt/pkgs/mailman/mail/wrapper"; +$MMLISTDIR = "/var/mailman/lists"; +$SENDMAIL = "/usr/lib/sendmail -oem -oi"; +$VERSION = '$Id: mm-handler 4287 2001-10-27 02:30:51Z bwarsaw $'; + +## Comment this if you offer local user addresses. +$NOUSERS = "\nPersonal e-mail addresses are not offered by this server."; + +# uncomment for debugging.... +#$DEBUG = 1; + +use FileHandle; +use Sys::Hostname; +use Socket; + +($VERS_STR = $VERSION) =~ s/^\$\S+\s+(\S+),v\s+(\S+\s+\S+\s+\S+).*/\1 \2/; + +$BOUNDARY = sprintf("%08x-%d", time, time % $$); + +## Informative, non-standard rejection letter +sub mail_error { + my ($in, $to, $list, $server, $reason) = @_; + my $sendmail; + + if ($server && $server ne "") { + $servname = $server; + } else { + $servname = "This server"; + $server = &get_ip_addr; + } + + #$sendmail = new FileHandle ">/tmp/mm-$$"; + $sendmail = new FileHandle "|$SENDMAIL $to"; + if (!defined($sendmail)) { + print STDERR "$0: cannot exec \"$SENDMAIL\"\n"; + exit (-1); + } + + $sendmail->print ("From: MAILER-DAEMON\@$server +To: $to +Subject: Returned mail: List unknown +Mime-Version: 1.0 +Content-type: multipart/mixed; boundary=\"$BOUNDARY\" +Content-Disposition: inline + +--$BOUNDARY +Content-Type: text/plain; charset=us-ascii +Content-Description: Error processing your mail +Content-Disposition: inline + +Your mail for $list could not be sent: + $reason + +For a list of publicly-advertised mailing lists hosted on this server, +visit this URL: + http://$server/ + +If this does not resolve your problem, you may write to: + postmaster\@$server +or + mailman-owner\@$server + + +$servname delivers e-mail to registered mailing lists +and to the administrative addresses defined and required by IETF +Request for Comments (RFC) 2142 [1]. +$NOUSERS + +The Internet Engineering Task Force [2] (IETF) oversees the development +of open standards for the Internet community, including the protocols +and formats employed by Internet mail systems. + +For your convenience, your original mail is attached. + + +[1] Crocker, D. \"Mailbox Names for Common Services, Roles and + Functions\". http://www.ietf.org/rfc/rfc2142.txt + +[2] http://www.ietf.org/ + +--$BOUNDARY +Content-Type: message/rfc822 +Content-Description: Your undelivered mail +Content-Disposition: attachment + +"); + + while ($_ = <$in>) { + $sendmail->print ($_); + } + + $sendmail->print ("\n"); + $sendmail->print ("--$BOUNDARY--\n"); + + close($sendmail); +} + +## Get my IP address, in case my sendmail doesn't tell me my name. +sub get_ip_addr { + my $host = hostname; + my $ip = gethostbyname($host); + return inet_ntoa($ip); +} + +## Split an address into its base list name and the appropriate command +## for the relevant function. +sub split_addr { + my ($addr) = @_; + my ($list, $cmd); + + if ($addr =~ /(.*)-admin$/ + || $addr =~ /(.*)-owner$/ + || $addr =~ /^owner-(.*)$/) { + $list = $1; + $cmd = "mailowner"; + } elsif ($addr =~ /(.*)-request$/) { + $list = $1; + $cmd = "mailcmd"; + } else { + $list = $addr; + $cmd = "post"; + } + + return ($list, $cmd); +} + +## The time, formatted as for an mbox's "From_" line. +sub mboxdate { + my ($time) = @_; + my @days = qw(Sun Mon Tue Wed Thu Fri Sat); + my @months = qw(Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec); + my ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst) = + localtime($time); + + ## Two-digit year handling complies with RFC 2822 (section 4.3), + ## with the addition that three-digit years are accommodated. + if ($year < 50) { + $year += 2000; + } elsif ($year < 1900) { + $year += 1900; + } + + return sprintf ("%s %s %2d %02d:%02d:%02d %d", + $days[$wday], $months[$mon], $mday, + $hour, $min, $sec, $year); +} + +BEGIN: { + $sender = undef; + $server = undef; + @to = (); + while ($#ARGV >= 0) { + if ($ARGV[0] eq "-r") { + $sender = $ARGV[1]; + shift @ARGV; + } elsif (!defined($server)) { + $server = $ARGV[0]; + } else { + push(@to, $ARGV[0]); + } + shift @ARGV; + } + + if ($DEBUG) { + $to = join(',', @to); + print STDERR "to: $to\n"; + print STDERR "sender: $sender\n"; + print STDERR "server: $server\n"; + exit(-1); + } + +ADDR: for $addr (@to) { + $prev = undef; + $list = $addr; + + $cmd= "post"; + if (! -f "$MMLISTDIR/$list/config.db") { + ($list, $cmd) = &split_addr($list); + if (! -f "$MMLISTDIR/$list/config.db") { + $was_to = $addr; + $was_to .= "\@$server" if ("$server" ne ""); + mail_error(\*STDIN, $sender, $was_to, $server, + "no list named \"$list\" is known by $server"); + next ADDR; + } + } + + $wrapper = new FileHandle "|$MMWRAPPER $cmd $list"; + if (!defined($wrapper)) { + ## Defer? + print STDERR "$0: cannot exec ", + "\"$MMWRAPPER $cmd $list\": deferring\n"; + exit (-1); + } + + # Don't need these without the "n" flag on the mailer def.... + #$date = &mboxdate(time); + #$wrapper->print ("From $sender $date\n"); + + # ...because we use these instead. + $from_ = <STDIN>; + $wrapper->print ($from_); + + $wrapper->print ("X-Mailman-Handler: $VERSION\n"); + while (<STDIN>) { + $wrapper->print ($_); + } + close($wrapper); + } +} diff --git a/contrib/mm-handler.readme b/contrib/mm-handler.readme new file mode 100644 index 000000000..a406e33e3 --- /dev/null +++ b/contrib/mm-handler.readme @@ -0,0 +1,151 @@ +Contributed by David Champion <dgc@uchicago.edu> +See also ../README.SENDMAIL + +What? +----- +Mm-handler is a mail delivery agent (MDA) -- a "mailer", in Sendmail +lingo. Its function is to assume authority for messages destined to +Mailman lists, so that they're off sendmail's hands, and you (the site +administrator) don't need to maintain databases of aliases and such. It +takes a small bit of work to set up, but once that's done, you'll never +need to mess with aliases for Mailman's sake again. + +When? +----- +The only further catch is that mm-handler is only really useful when +it mostly "owns" its mail domain (the hostname part after an e-mail +address's "@" symbol) -- when you can dedicate the mail domain to +Mailman. If you have a limited set of exceptions -- a few users, for +example -- you can still use it, but for sites with a dynamic or even +mix of users (or forwarders) and lists, it might not gain you much. + +How do you know whether mm-handler is appropriate for you? Let's look +at some examples. If you're running lists off your primary DNS domain +name, you probably have a mix of lists and users in your namespace. Take +python.org, for example: it hosts Mailman lists, and it hosts users' +personal accounts. There aren't a whole bunch of either, but the ratio +is probably fairly near 1:1. Mm-handler is not very useful here, because +there's no simple way to separate user addresses from list addresses -- +not to mention that mm-handler is written in perl, so that's just bad +form. + +This begs two different, complementary situations. A hypothetical +domain, incidents.int, is used mostly for mailing lists. It's a +front-end site, and not a general user mail service. There might be +a couple of user addresses -- system administrators and such -- but +these are few in number and easily adjusted manually by the site +administrator. The 250 mailing lists at the site are much more dynamic, +and a much bigger pain to keep track of by editing an alias file. This +site can easily benefit from mm-handler. + +Inversely, mail.aero, another hypothetical domain, provides POP mail +service to employees of the aerospace industry. Its addresses are +almost entirely users, although it maintains a few mailing lists for +convenience. This site has nothing to gain from mm-handler. It's much +easier to maintain an alias file of 10 lists than to dedicate the domain +to Mailman, and put all 10,000 aerospace workers in a user table. + +Those are the trickier cases. The case where mm-handler really works +best is when you can dedicate a single hostname under your DNS domain +to mailing lists, and host no user accounts there. At the University of +Chicago, we do this with listhost.uchicago.edu. SourceForge does this, +too, although I don't believe they use Sendmail. + +If your site is like that, you should read on. + +How? +---- +Set-up isn't all that complicated. I've included a file here called +"mailman.mc". This is the m4 file that I use on my list server, and you +can likely use it with few changes at your site. It's well-annotated; +the rationale for each parameter (or set of parameters) is provided in +m4 (ahem) comments. + +So, the simple steps are as follows: + +1. Copy mailman.mc, and make any changes you need at your site. You + DEFINITELY need some changes. There are hostnames in there that you + need to adjust, and chances are that you'll need to change some other + parameters (like the host OS), too. [1] + +2. Install mm-handler. Because my server's sendmail-related files live + in /etc/mail, I keep mm-handler there, too. YMMV. + +3. Edit mm-handler, and make any changes you need at your site. You + probably want to change $MMWRAPPER and $MMLISTDIR at line 14, and you + *might* want to take a look at the helpful boilerplate text beginning + at line 64. (This text is sent whenever someone tries to send mail to + a nonexistent list address on your mail domain.) + +4. You should set up a virtusertable. (See mailman.mc for an + explanation.) There's an example of a good, minimal virtusertable + in this distribution. The virtusertable begins as a text file named + "virtusertable", stored in the same directory as all the other + Sendmail files, but it's converted to a map file for Sendmail's use. + Install the virtusertable, and (re)make the map file. [2] + +5. You absolutely must have a mailertable, or all of this goes nowhere. + Like virtusertable, the mailertable is a map that begins as text and + gets converted. It's named "mailertable", and it's probably pretty + simple. Mine looks like this: + + listtest.uchicago.edu mailman:listtest.uchicago.edu + + This says: assign all incoming mail (that was not intercepted by the + virtusertable) and that is in the listtest.uchicago.edu domain to the + "mailman" mailer, and tell the "mailman" mailer that the hostname + we're using is "listtest.uchicago.edu". You can support multiple + virtual hosts using mm-handler just by placing corresponding lines in + mailertable. + + Be sure to make this map, too! + +6. The mailer definition (see the end of mailman.mc, or your own .mc + file) for mm-handler sets the user/group that mm-handler will run + under. (I use mailman:other.) Be sure that mm-handler is executable + by this user or group. You almost certainly need the user to be the + same as the Mailman user, and this user is almost always called + "mailman", so you probably shouldn't change the defaults. + +7. Generate your new sendmail.cf file. See the sendmail documentation if + you're not familiar with this procedure. [1] + +8. Stop sendmail on your list server, if you haven't already. Install + the new sendmail.cf file wherever your sendmail.cf file belongs. + (This depends on how sendmail was compiled, but most systems support + using /etc/sendmail.cf.) + +9. Cross your fingers and restart sendmail. + +A. Barry warns that Mailman now needs you to modify your + Mailman/mm_cfg.py file, adding this line: + + MTA = None + + This tells Mailman that it doesn't need to do anything special when + it creates or deletes mailing lists through the web. For more + information, take a look at the comments for this variable in your + Defaults.py file (but never edit this file -- always edit mm_cfg.py + instead!). + +That's it! With any luck, you're fully functional. + +-- +[1] The .mc file is the standard, supported way of configuring sendmail. + I'm not going to get into this here, and I'm not going to tell + you how to write raw sendmail.cf stuff, because if you need to do + it this way then you need something more comprehensive than I can + provide. If you need help with the .mc -> .cf process, I recommend + these links: + + http://www.sendmail.org/~ca/email/setup1.html + http://www.sendmail.org/~ca/email/doc8.9/README.cf.html + http://www.hserus.net/sendmail.html + +[2] This is often done with something like "makemap hash + /etc/virtusertable </etc/virtusertable", but it could be different + on your server. Consult the sendmail documentation if you do not + know. + +-- +$Id: mm-handler.readme 4287 2001-10-27 02:30:51Z bwarsaw $ diff --git a/contrib/virtusertable b/contrib/virtusertable new file mode 100644 index 000000000..eb5eb744b --- /dev/null +++ b/contrib/virtusertable @@ -0,0 +1,37 @@ +## +## Example virtusertable for use with a Mailman site running mm-handler. +## +## $Id: virtusertable 4287 2001-10-27 02:30:51Z bwarsaw $ +## + +## +## My server's hostname is nospam, but we don't honor that as a +## Mailman mail domain. Anything @nospam.uchicago.edu should be +## forwarded to our master Mailman admin address. +## +@nospam.uchicago.edu mailman-owner@midway.uchicago.edu + +## +## Redirect mail to the standard Mailman admin addresses to the +## master admin address. (Midway.uchicago.edu is our site's central +## mail-routing server, and it carries aliases for maintenance groups. +## Not a good plan to entrust Mailman maintenance mail to Mailman.) +## +mailman@listhost.uchicago.edu mailman-owner@midway.uchicago.edu +mailman-owner@listhost.uchicago.edu mailman-owner@midway.uchicago.edu + +## +## These addresses are required or recommended either by convention +## or by RFC 2142, "Mailbox Names for Common Services, Roles and +## Functions". Honor them. +## +MAILER-DAEMON@listhost.uchicago.edu mailman-owner@midway.uchicago.edu +postmaster@listhost.uchicago.edu mailman-owner@midway.uchicago.edu +webmaster@listhost.uchicago.edu mailman-owner@midway.uchicago.edu +abuse@listhost.uchicago.edu sun-admin@midway.uchicago.edu +root@listhost.uchicago.edu sun-admin@midway.uchicago.edu + +## +## If I had a need, I could put user accounts in here, too. +## +dgc@listhost.uchicago.edu dgc@where.my.mail.really.goes |
