diff options
| author | Barry Warsaw | 2011-06-16 16:27:13 -0400 |
|---|---|---|
| committer | Barry Warsaw | 2011-06-16 16:27:13 -0400 |
| commit | 3c99f28d219596434e8547df95e7041e2cf21fb7 (patch) | |
| tree | 287cc4ee058c29228bd4201cc89c7411983fa2b8 | |
| parent | 8a7ef34b079786ddeba73e8beba11af660d9433e (diff) | |
| download | mailman-3c99f28d219596434e8547df95e7041e2cf21fb7.tar.gz mailman-3c99f28d219596434e8547df95e7041e2cf21fb7.tar.zst mailman-3c99f28d219596434e8547df95e7041e2cf21fb7.zip | |
| -rw-r--r-- | contrib/README | 4 | ||||
| -rw-r--r-- | contrib/README.check_perms_grsecurity | 14 | ||||
| -rw-r--r-- | contrib/README.mm-handler | 215 | ||||
| -rw-r--r-- | contrib/README.mmdsr | 45 | ||||
| -rw-r--r-- | contrib/auto | 116 | ||||
| -rw-r--r-- | contrib/check_perms_grsecurity.py | 182 | ||||
| -rw-r--r-- | contrib/fblast.py | 60 | ||||
| -rw-r--r-- | contrib/mailman.mc | 143 | ||||
| -rw-r--r-- | contrib/majordomo2mailman.pl | 691 | ||||
| -rw-r--r-- | contrib/mm-handler | 236 | ||||
| -rw-r--r-- | contrib/mmdsr | 572 | ||||
| -rw-r--r-- | contrib/qmail-to-mailman.py | 116 | ||||
| -rw-r--r-- | contrib/rotatelogs.py | 104 | ||||
| -rw-r--r-- | contrib/virtusertable | 37 |
14 files changed, 0 insertions, 2535 deletions
diff --git a/contrib/README b/contrib/README deleted file mode 100644 index 3e4750329..000000000 --- a/contrib/README +++ /dev/null @@ -1,4 +0,0 @@ -This directory contains unofficial contributed scripts and extensions -to Mailman. They are unsupported by the Mailman developers. If you -have questions or problems with them, please contact the contribution -author directly. diff --git a/contrib/README.check_perms_grsecurity b/contrib/README.check_perms_grsecurity deleted file mode 100644 index 6d1d0389e..000000000 --- a/contrib/README.check_perms_grsecurity +++ /dev/null @@ -1,14 +0,0 @@ -The check_perms_grsecurity.py script, if copied in your installed -~mailman/bin/ directory and run from there will modify permissions of -files so that Mailman with extra restrictions imposed by linux kernel security -patches like securelinux/openwall in 2.2.x or grsecurity in 2.4.x - -The way it works is that it makes sure that the UID of any script that -touches config.pck is `mailman'. What this means however is that -scripts in ~mailman/bin will now only work if run as user mailman or -root (the script then changes its UID and GID to mailman). -To make grsecurity happy, we remove the group writeable bit on a directories -that contain binaries. - -Enjoy -Marc MERLIN <marc_soft@merlins.org>/<marc_bts@vasoftware.com> - 2001/12/10 diff --git a/contrib/README.mm-handler b/contrib/README.mm-handler deleted file mode 100644 index 3c4864a7b..000000000 --- a/contrib/README.mm-handler +++ /dev/null @@ -1,215 +0,0 @@ -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. - - -The following note is provided by Kevin McNamee <kevin.mcnamee(at)symsoft.se> -regarding solving a problem with mail to list addresses being rejected for -"user unknown". Reference: -<http://mail.python.org/pipermail/mailman-users/2006-February/049235.html> - - -"User unknown" analysis -======================= -If the "user unknown" problem arises, then sendmail is not -recognising your domain as a "mailman" domain. -The problem could be that your mailman.mydomain.com is defined as a -CNAME not a real DNS record. - -A hint from a tutorial about Masquerading: -http://www.feep.net/sendmail/tutorial/config/masquerading.html -"This address must be an address record in DNS, not simply -a CNAME, or the remote end will canonicalize the address back -to the original name." - -First confirm the problem -# sendmail -bv testlist<at>mailman.mydomain.com -testlist<at>mailman.mydomain.com... User unknown - -Then confirm that mailertable is operational -# sendmail -d -bv jbloggs<at>hotmail.com | egrep "map_rewrite|mailertable" -map_lookup(host, hotmail.com) => host_map_lookup(hotmail.com) => -map_rewrite(hotmail.com), av = -map_rewrite => hotmail.com. -map_lookup(mailertable, hotmail.com) => NOT FOUND (0) -map_lookup(mailertable, .com) => NOT FOUND (0) -map_lookup(mailertable, .) => NOT FOUND (0) - -Then confirm that your domain (CNAME) is being canonicalised: -# sendmail -d -bv testlist<at>mailman.mydomain.com | egrep -"map_rewrite|mailertable" -map_lookup(host, mailman.mydomain.com) => -host_map_lookup(mailman.mydomain.com) => map_rewrite(aserver.mydomain.com), -av = -map_rewrite => aserver.mydomain.com. - -Sendmail has done an nslookup and found the real name of your domain which -would not match your settings in mailertable (if sendmail got that far). - -If you remove the CNAME and create a real subdomain, then the problem will -go away: -# sendmail -bv testlist<at>mailman.mydomain.com -testlist<at>mailman.mydomain.com... deliverable: mailer mailman, host -testlist<at>mailman.mydomain.com, user testlist - -You will still need to create a new CNAME in your sub-domain for Apache to -work. - -Conclusion: -It is very important to make clear in the Mailman installation instructions -that a REAL subdomain is needed. Those of us not familiar with DNS (or -sendmail for that matter) can succeed in getting the whole Mailman -installation working including the (Apache) web-interface and subscription -management using just a CNAME and then wonder why we cannot send mail to our -list. Hope this is of use. - -Ed. note: the above "conclusion" applies in this mm-handler case, but it -normally does not apply if list mail is delivered via aliases. - --- -$Id: README.mm-handler 7780 2006-02-20 03:33:19Z msapiro $ diff --git a/contrib/README.mmdsr b/contrib/README.mmdsr deleted file mode 100644 index 5159171e6..000000000 --- a/contrib/README.mmdsr +++ /dev/null @@ -1,45 +0,0 @@ -Daily Status Report script... - -The mmdsr script was created by Brad Knowles to produce a daily status report -for mailman. It was initially posted at -<http://sourceforge.net/tracker/index.php?func=detail&aid=1123383&group_id=103&atid=300103> -which see for possible patches and other enhancements. - -Here goes the original mmdsr.readme by Brad ... - -======================================================================== -This is a basic Bourne shell script that I quickly hacked together for -my own purposes, designed to be fired off at 23:59 every night, going -through a variety of Mailman log files looking for entries specific -to that date, summarizing the activities, and indicating problems or -certain types of activity that might be of interest to someone trying -to administer the server. - -It also does an "ls -la" of /usr/local/mailman/qfiles/*, so that you -can see what is in the queue at the time of the execution of the script. - -This daily report will get e-mailed to the admin, or posted to a "reports" -mailing list, where they can be archived and kept for future reference. -If you don't define an address where the output e-mail should be sent, -it will instead be printed to the standard output (thus allowing you to -do something else with it). - - -Once I'd gone through a few revisions of my own on this tool, I -thought that I would release the code to the public and get comments -and suggestions from others in the Mailman community. This program is -currently being used actively on the mail servers for python.org (where -the mailman-users and other Mailman-related mailing lists are hosted), -as well as many others. - -Note that this script needs to be configured once to know where standard -commands are located, where log files are kept, etc... (see the top -500 lines or so of the script), but after that you don't need to feed -it any input, or capture the output to be sent anywhere. This script -takes care of all of that. All you should need to do is to call this -script from a cron job at 23:59 (local time) every night. - - -When looking at this script, perhaps during configuration, please keep -in mind that it is heavily commented at the top, and everything should -hopefully be self-evident. diff --git a/contrib/auto b/contrib/auto deleted file mode 100644 index eaa8ab461..000000000 --- a/contrib/auto +++ /dev/null @@ -1,116 +0,0 @@ -# -*- python -*- -# -# Copyright (C) 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - -"""Automatically send a message to a mailing list. -""" - -# To use with Postfix, set the following in your main.cf file: -# -# recipient_delimiter = + -# luser_relay = mm+$user@yourdomain.com -# owner_request_special = no - -import sys -import os -import time - -import paths -from Mailman import mm_cfg -from Mailman import Utils -from Mailman import MailList -from Mailman import Errors -from Mailman.Queue.sbcache import get_switchboard -from Mailman.Logging.Utils import LogStdErr - -# Error code if it's really not a Mailman list addr destination -EX_NOUSER = 67 - -LogStdErr('auto', 'auto') - -DISPOSE_MAP = {None : 'tolist', - 'request': 'torequest', - 'admin' : 'toadmin', - 'owner' : 'toadmin', - } - - - -def fqdn_listname(listname, hostname): - return ('%s@%s' % (listname, hostname)).lower() - - - -def main(): - # Postfix sets some environment variables based on information gleaned - # from the original message. This is the most direct way to figure out - # which list the message was intended for. - extension = os.environ.get('EXTENSION', '').lower() - i = extension.rfind('-') - if i < 0: - listname = extension - subdest = 'tolist' - else: - missing = [] - listname = extension[:i] - subdest = DISPOSE_MAP.get(extension[i+1:], missing) - if not Utils.list_exists(listname) or subdest is missing: - # must be a list that has a `-' in it's name - listname = extension - subdest = 'tolist' - if not listname: - print >> sys.stderr, 'Empty list name (someone being subversive?)' - return EX_NOUSER - try: - mlist = MailList.MailList(listname, lock=0) - except Errors.MMListError: - print >> sys.stderr, 'List not found:', listname - return EX_NOUSER - - # Make sure that the domain part of the incoming address matches the - # domain of the mailing list. Actually, it's possible that one or the - # other is more fully qualified, and thus longer. So we split the domains - # by dots, reverse them and make sure that whatever parts /are/ defined - # for both are equivalent. - domain = os.environ.get('DOMAIN', '').lower() - domainp = domain.split('.') - hostname = mlist.host_name.split('.') - domainp.reverse() - hostname.reverse() - for ca, cb in zip(domainp, hostname): - if ca <> cb: - print >> sys.stderr, 'Domain mismatch: %s@%s (expected @%s)' \ - % (listname, domain, mlist.host_name) - return EX_NOUSER - - if subdest is None: - print >> sys.stderr, 'Bad sub-destination:', extension - return EX_NOUSER - - inq = get_switchboard(mm_cfg.INQUEUE_DIR) - inq.enqueue(sys.stdin.read(), - listname=listname, - received_time=time.time(), - _plaintext=1, - **{subdest: 1}) - return 0 - - - -if __name__ == '__main__': - code = main() - sys.exit(code) diff --git a/contrib/check_perms_grsecurity.py b/contrib/check_perms_grsecurity.py deleted file mode 100644 index 3d0b66e1a..000000000 --- a/contrib/check_perms_grsecurity.py +++ /dev/null @@ -1,182 +0,0 @@ -#! @PYTHON@ -# -# Copyright (C) 1998-2007 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, -# USA. - -"""Fixes for running Mailman under the `secure-linux' patch or grsecurity. - -Run check_perms -f and only then check_perms_grsecurity.py -f -Note that you will have to re-run this script after a mailman upgrade and -that check_perms will undo part of what this script does - -If you use Solar Designer's secure-linux patch, it prevents a process from -linking (hard link) to a file it doesn't own. -Grsecurity (http://grsecurity.net/) can have the same restriction depending -on how it was built, including other restrictions like preventing you to run -a program if it is located in a directory writable by a non root user. - -As a result Mailman has to be changed so that the whole tree is owned by -Mailman, and the CGIs and some of the programs in the bin tree (the ones -that lock config.pck files) are SUID Mailman. The idea is that config.pck -files have to be owned by the mailman UID and only touched by programs that -are UID mailman. -At the same time, We have to make sure that at least 3 directories under -~mailman aren't writable by mailman: mail, cgi-bin, and bin - -Binary commands that are changed to be SUID mailman are also made unreadable -and unrunnable by people who aren't in the mailman group. This shouldn't -affect much since most of those commands would fail work if you weren't part -of the mailman group anyway. -Scripts in ~mailman/bin/ are not made suid or sgid, they need to be run by -user mailman or root to work. - -Marc <marc_soft@merlins.org>/<marc_bts@vasoftware.com> -2000/10/27 - Initial version for secure_linux/openwall and mailman 2.0 -2001/12/09 - Updated version for grsecurity and mailman 2.1 -""" - -import sys -import os -import paths -import re -import glob -import pwd -import grp -from Mailman import mm_cfg -from Mailman.mm_cfg import MAILMAN_USER, MAILMAN_GROUP -from stat import * - -# Directories that we don't want writable by mailman. -dirstochownroot= ( 'mail', 'cgi-bin', 'bin' ) - -# Those are the programs that we patch so that they insist being run under the -# mailman uid or as root. -binfilestopatch= ( 'add_members', 'change_pw', 'check_db', 'clone_member', - 'config_list', 'newlist', 'qrunner', 'remove_members', - 'rmlist', 'sync_members', 'update', 'withlist' ) - -def main(argv): - binpath = paths.prefix + '/bin/' - droplib = binpath + 'CheckFixUid.py' - - if len(argv) < 2 or argv[1] != "-f": - print __doc__ - sys.exit(1) - - print "Making select directories owned and writable by root only" - gid = grp.getgrnam(MAILMAN_GROUP)[2] - for dir in dirstochownroot: - dirpath = paths.prefix + '/' + dir - os.chown(dirpath, 0, gid) - os.chmod(dirpath, 02755) - print dirpath - - print - - file = paths.prefix + '/data/last_mailman_version' - print "Making" + file + "owned by mailman (not root)" - uid = pwd.getpwnam(MAILMAN_USER)[2] - gid = grp.getgrnam(MAILMAN_GROUP)[2] - os.chown(file, uid, gid) - print - - if not os.path.exists(droplib): - print "Creating " + droplib - fp = open(droplib, 'w', 0644) - fp.write("""import sys -import os -import grp, pwd -from Mailman.mm_cfg import MAILMAN_USER, MAILMAN_GROUP - -class CheckFixUid: - uid = pwd.getpwnam(MAILMAN_USER)[2] - gid = grp.getgrnam(MAILMAN_GROUP)[2] - if os.geteuid() == 0: - os.setgid(gid) - os.setuid(uid) - if os.geteuid() != uid: - print "You need to run this script as root or mailman because it was configured to run" - print "on a linux system with a security patch which restricts hard links" - sys.exit() -""") - fp.close() - else: - print "Skipping creation of " + droplib - - - print "\nMaking cgis setuid mailman" - cgis = glob.glob(paths.prefix + '/cgi-bin/*') - - for file in cgis: - print file - os.chown(file, uid, gid) - os.chmod(file, 06755) - - print "\nMaking mail wrapper setuid mailman" - file= paths.prefix + '/mail/mailman' - os.chown(file, uid, gid) - os.chmod(file, 06755) - print file - - print "\nEnsuring that all config.db/pck files are owned by Mailman" - cdbs = glob.glob(paths.prefix + '/lists/*/config.db*') - cpcks = glob.glob(paths.prefix + '/lists/*/config.pck*') - - for file in cdbs + cpcks: - stat = os.stat(file) - if (stat[ST_UID] != uid or stat[ST_GID] != gid): - print file - os.chown(file, uid, gid) - - print "\nPatching mailman scripts to change the uid to mailman" - - for script in binfilestopatch: - filefd = open(script, "r") - file = filefd.readlines() - filefd.close() - - patched = 0 - try: - file.index("import CheckFixUid\n") - print "Not patching " + script + ", already patched" - except ValueError: - file.insert(file.index("import paths\n")+1, "import CheckFixUid\n") - for i in range(len(file)-1, 0, -1): - object=re.compile("^([ ]*)main\(").search(file[i]) - # Special hack to support patching of update - object2=re.compile("^([ ]*).*=[ ]*main\(").search(file[i]) - if object: - print "Patching " + script - file.insert(i, - object.group(1) + "CheckFixUid.CheckFixUid()\n") - patched=1 - break - if object2: - print "Patching " + script - file.insert(i, - object2.group(1) + "CheckFixUid.CheckFixUid()\n") - patched=1 - break - - if patched==0: - print "Warning, file "+script+" couldn't be patched." - print "If you use it, mailman may not function properly" - else: - filefd=open(script, "w") - filefd.writelines(file) - -main(sys.argv) diff --git a/contrib/fblast.py b/contrib/fblast.py deleted file mode 100644 index 50368b3be..000000000 --- a/contrib/fblast.py +++ /dev/null @@ -1,60 +0,0 @@ -"""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 -the unit test framework (hence its filename doesn't start with `test_'). -Here's how I use this one: - -- set up a dummy list - -- add an alias to your MTA, say `devnull' that pipes its messages to, you - guessed it, /dev/null - -- make this address a member of your list - -- add another address to `accept_these_non_members', let's call it ok@dom.ain - -- change the FROMADDR variable to ok@dom.ain - -- change the LISTADDR variable to point to your list - -- run this program like so: python fblast.py N - where N is the number of seconds to sleep before sending the next msg - -- let this run until you're tired of it, then hit ^C -""" - -FROMADDR = 'ok@dom.ain' -LISTADDR = 'list@dom.ain' - -import sys -import time -import smtplib - -conn = smtplib.SMTP() -conn.connect() - -snooze = int(sys.argv[1]) - -try: - i = 1 - while 1: - sys.stdout.write('.') - sys.stdout.flush() - i += 1 - if i % 50 == 0: - print - for j in range(10): - conn.sendmail(FROMADDR, [LISTADDR], """\ -From: %(FROMADDR)s -To: $(LISTADDR)s -Subject: test %(num)d -X-No-Archive: yes - -testing %(num)d -""" % {'num' : i, - 'FROMADDR': FROMADDR, - 'LISTADDR': LISTADDR, - }) - time.sleep(snooze) -finally: - conn.quit() diff --git a/contrib/mailman.mc b/contrib/mailman.mc deleted file mode 100644 index fc39edbdc..000000000 --- a/contrib/mailman.mc +++ /dev/null @@ -1,143 +0,0 @@ -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/majordomo2mailman.pl b/contrib/majordomo2mailman.pl deleted file mode 100644 index c874862e7..000000000 --- a/contrib/majordomo2mailman.pl +++ /dev/null @@ -1,691 +0,0 @@ -#!/usr/bin/perl -w - -# majordomo2mailman.pl - Migrate Majordomo mailing lists to Mailman 2.0 -# Copyright (C) 2002 Heiko Rommel (rommel@suse.de) - -# BAW: Note this probably needs to be upgraded to work with MM2.1 - -# -# License: -# -# 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 1, or (at your option) -# any later version. - -# -# Warranty: -# -# There's absolutely no warranty. -# - -# comments on possible debug messages during the conversion: -# -# "not an valid email address" : those addresses are rejected, i.e. not imported into the Mailman list -# "not a numeric value" : such a value will be converted to 0 (z.B. maxlength) -# "already subscribed" : will only once be subscribed on the Mailman list -# "...umbrella..." or "...taboo..." -> Mailman-Admin-Guide - -use strict; -use Getopt::Long; -use Fcntl; -use POSIX qw (tmpnam); - -use vars qw ( - $majordomo $mydomain $myurl - $aliasin $listdir - $aliasout $mailmanbin - $umbrella_member_suffix $private - $newsserver $newsprefix - $susehack $susearchuser - $help $debug $update $all $usagemsg - *FH - %mlaliases %mlowners %mlapprovers - %defaultmlconf %mlconf - %defaultmmconf %mmconf -); - -# -# adjust your site-specific settings here -# - -$mydomain = "my.domain"; -$majordomo = "majordomo"; # the master Majordomo address for your site -$aliasin = "/var/lib/majordomo/aliases"; -$listdir = "/var/lib/majordomo/lists"; -$aliasout = "/tmp/aliases"; -$myurl = "http://my.domain/mailman/"; -$mailmanbin = "/usr/lib/mailman/bin"; -$umbrella_member_suffix = "-owner"; -$private = "yes"; # is this a private/Intranet site ? -$newsserver = "news.my.domain"; -$newsprefix = "intern."; - -$susehack = "no"; -$susearchuser = "archdummy"; - -# -# 0) -# parse the command line arguments -# - -$usagemsg = "usage: majordomo2mailman [-h|--help] [-d|--debug] [-u|--update] < (-a|--all) | list-of-mailinglists >"; - -GetOptions( - "h|help" => \$help, - "d|debug" => \$debug, - "a|all" => \$all, - "u|update" => \$update -) or die "$usagemsg\n"; - -if (defined($help)) { die "$usagemsg\n"; } - -if ((not defined($all)) and (@ARGV<1)) { die "$usagemsg\n"; } - -if ($<) { die "this script must be run as root!\n"; } - -# -# 1) -# build a list of all aliases and extract the name of mailing lists plus their owners -# - -%mlaliases = %mlowners = %mlapprovers = (); - -open (FH, "< $aliasin") or die "can't open $aliasin\n"; - -while (<FH>) { - # first, build a list of all active aliases and their resolution - if (/^([^\#:]+)\s*:\s*(.*)$/) { - $mlaliases{$1} = $2; - } -} - -my $mlalias; -for $mlalias (keys %mlaliases) { - # if we encounter an alias with :include: as expansion - # it is save to assume that the alias has the form - # <mailinglist>-outgoing - - # that way we find the names of all active mailing lists - if ($mlaliases{$mlalias} =~ /\:include\:/) { - my $ml; - ($ml = $mlalias) =~ s/-outgoing//g; - $mlowners{$ml} = $mlaliases{"owner-$ml"}; - $mlapprovers{$ml} = $mlaliases{"$ml-approval"}; - } -} - -close (FH); - -# -# 2) -# for each list read the Majordomo configuration params -# and create a Mailman clone -# - -my $ml; -for $ml ((defined ($all)) ? sort keys %mlowners : @ARGV) { - - init_defaultmlconf($ml); - %mlconf = %defaultmlconf; - - init_defaultmmconf($ml); - %mmconf = %defaultmmconf; - - my @privileged; # addresses that are mentioned in restrict_post - my @members; - my ($primaryowner, @secondaryowner); - my ($primaryapprover, @secondaryapprover); - - my ($skey, $terminator); - my $filename; - my @args; - - # - # a) - # parse the configuration file - # - - open (FH, "< $listdir/$ml.config") or die "can't open $listdir/$ml.config\n"; - - while (<FH>) { - # key = value ? - if (/^\s*([^=\#\s]+)\s*=\s*(.*)\s*$/) { - $mlconf{$1} = $2; - } - # key << EOF - # value - # EOF ? - elsif (/^\s*([^<\#\s]+)\s*<<\s*(.*)\s*$/) { - ($skey, $terminator) = ($1, $2); - while (<FH>) { - last if (/^$terminator\s*$/); - $mlconf{$skey} .= $_; - } - chomp $mlconf{$skey}; - } - } - - close (FH); - - # - # b) - # test if there are so-called flag files (clue that this is an old-style Majordomo lists) - # and overwrite previously parsed values - # (stolen from majordomo::config_parse.pl: handle_flag_files()) - # - - if ( -e "$listdir/$ml.private") { - $mlconf{"get_access"} = "closed"; - $mlconf{"index_access"} = "closed"; - $mlconf{"who_access"} = "closed"; - $mlconf{"which_access"} = "closed"; - } - - $mlconf{"subscribe_policy"} = "closed" if ( -e "$listdir/$ml.closed"); - $mlconf{"unsubscribe_policy"} = "closed" if ( -e "$listdir/$ml.closed"); - - if ( -e "$listdir/$ml.auto" && -e "$listdir/$ml.closed") { - print STDERR "sowohl $ml.auto als auch $ml.closed existieren. Wähle $ml.closed\n"; - } - else { - $mlconf{"subscribe_policy"} = "auto" if ( -e"$listdir/$ml.auto"); - $mlconf{"unsubscribe_policy"} = "auto" if ( -e"$listdir/$ml.auto"); - } - - $mlconf{"strip"} = 1 if ( -e "$listdir/$ml.strip"); - $mlconf{"noadvertise"} = "/.*/" if ( -e "$listdir/$ml.hidden"); - - # admin_passwd: - $filename = "$listdir/" . $mlconf{"admin_passwd"}; - if ( -e "$listdir/$ml.passwd" ) { - $mlconf{"admin_passwd"} = read_from_file("$listdir/$ml.passwd"); - } - elsif ( -e "$filename" ) { - $mlconf{"admin_passwd"} = read_from_file("$filename"); - } - # else take it verbatim - - # approve_passwd: - $filename = "$listdir/" . $mlconf{"approve_passwd"}; - if ( -e "$listdir/$ml.passwd" ) { - $mlconf{"approve_passwd"} = read_from_file("$listdir/$ml.passwd"); - } - elsif ( -e "$filename" ) { - $mlconf{"approve_passwd"} = read_from_file("$filename"); - } - # else take it verbatim - - # - # c) - # add some information from additional configuration files - # - - # restrict_post - if (defined ($mlconf{"restrict_post"})) { - @privileged = (); - for $filename (split /\s+/, $mlconf{"restrict_post"}) { - open (FH, "< $listdir/$filename") or die "can't open $listdir/$filename\n"; - push (@privileged, <FH>); - chomp @privileged; - close (FH); - } - } - - if ($susehack =~ m/yes/i) { - @privileged = grep(!/$susearchuser\@$mydomain/i, @privileged); - } - - $mlconf{"privileged"} = \@privileged; - - # members - @members = (); - open (FH, "< $listdir/$ml") or die "can't open $listdir/$ml\n"; - push (@members, <FH>); - chomp @members; - close (FH); - - $mlconf{"gated"} = "no"; - - if ($susehack =~ m/yes/i) { - if (grep(/$susearchuser\@$mydomain/i, @members)) { - $mlconf{"gated"} = "yes"; - } - @members = grep(!/$susearchuser\@$mydomain/i, @members); - } - - $mlconf{"members"} = \@members; - - # intro message - if (open (FH, "< $listdir/$ml.intro")) { - { local $/; $mlconf{"intro"} = <FH>; } - } - else { $mlconf{"intro"} = ""; } - - # info message - if (open (FH, "< $listdir/$ml.info")) { - { local $/; $mlconf{"info"} = <FH>; } - } - else { $mlconf{"info"} = ""; } - - # - # d) - # take over some other params into the configuration table - # - - $mlconf{"name"} = "$ml"; - - ($primaryowner, @secondaryowner) = - expand_alias (split (/\s*,\s*/, aliassub($mlowners{$ml}))); - - ($primaryapprover, @secondaryapprover) = - expand_alias (split (/\s*,\s*/, aliassub($mlapprovers{$ml}))); - - $mlconf{"primaryowner"} = $primaryowner; - $mlconf{"secondaryowner"} = \@secondaryowner; - - $mlconf{"primaryapprover"} = $primaryapprover; - $mlconf{"secondaryapprover"} = \@secondaryapprover; - - # - # debugging output - # - - if (defined ($debug)) { - print "##################### $ml ####################\n"; - for $skey (sort keys %mlconf) { - if (defined ($mlconf{$skey})) { print "$skey = $mlconf{$skey}\n"; } - else { print "$skey = (?)\n"; } - } - my $priv; - for $priv (@privileged) { - print "\t$ml: $priv\n"; - } - } - - # - # e) - # with the help of Mailman commands - create a new list and subscribe the old staff - # - - if (defined($update)) { - print "updating configuration of \"$ml\"\n"; - } - else { - # Mailman lists can initially be only created with one owner - @args = ("$mailmanbin/newlist", "-q", "-o", "$aliasout", "$ml", $mlconf{"primaryowner"}, $mlconf{"admin_passwd"}); - system (@args) == 0 or die "system @args failed: $?"; - } - - # Mailman accepts only subscriber lists > 0 - if (@members > 0) { - $filename = tmpnam(); - open (FH, "> $filename") or die "can't open $filename\n"; - for $skey (@members) { - print FH "$skey" . "\n"; - } - close (FH); - @args = ("$mailmanbin/add_members", "-n", "$filename", "--welcome-msg=n", "$ml"); - system (@args) == 0 or die "system @args failed: $?"; - } - - # - # f) - # "translate" the Majordomo list configuration - # - - m2m(); - - # write the Mailman config - - $filename = tmpnam(); - - open (FH, "> $filename") or die "can't open $filename\n"; - for $skey (sort keys %mmconf) { - print FH "$skey = " . $mmconf{$skey} . "\n"; - } - close (FH); - - @args = ("$mailmanbin/config_list", "-i", "$filename", "$ml"); - system (@args) == 0 or die "system @args failed: $?"; - - unlink($filename) or print STDERR "unable to unlink \"$filename\"!\n"; - -} - -exit 0; - -############# -# subs -############# - -# -# I don't know how to write Perl code -# therefor I need this stupid procedure to cleanly read a value from file -# - -sub read_from_file { - my $value; - local *FH; - - open (FH, "< $_[0]") or die "can't open $_[0]\n"; - $value = <FH>; - chomp $value; - close (FH); - - return $value; -} - - -# -# add "@$mydomain" to each element that does not contain a "@" -# - -sub expand_alias { - return map { (not $_ =~ /@/) ? $_ .= "\@$mydomain" : $_ } @_; -} - -# -# replace the typical owner-majordomo aliases -# - -sub aliassub { - my $string = $_[0]; - - $string =~ s/(owner-$majordomo|$majordomo-owner)/mailman-owner/gi; - - return $string; -} - -# -# default values of Majordomo mailing lists -# (stolen from majordomo::config_parse.pl: %known_keys) -# - -sub init_defaultmlconf { - my $ml = $_[0]; - - %defaultmlconf=( - 'welcome', "yes", - 'announcements', "yes", - 'get_access', "open", - 'index_access', "open", - 'who_access', "open", - 'which_access', "open", - 'info_access', "open", - 'intro_access', "open", - 'advertise', "", - 'noadvertise', "", - 'description', "", - 'subscribe_policy', "open", - 'unsubscribe_policy', "open", - 'mungedomain', "no", - 'admin_passwd', "$ml.admin", - 'strip', "yes", - 'date_info', "yes", - 'date_intro', "yes", - 'archive_dir', "", - 'moderate', "no", - 'moderator', "", - 'approve_passwd', "$ml.pass", - 'sender', "owner-$ml", - 'maxlength', "40000", - 'precedence', "bulk", - 'reply_to', "", - 'restrict_post', "", - 'purge_received', "no", - 'administrivia', "yes", - 'resend_host', "", - 'debug', "no", - 'message_fronter', "", - 'message_footer', "", - 'message_headers', "", - 'subject_prefix', "", - 'taboo_headers', "", - 'taboo_body', "", - 'digest_volume', "1", - 'digest_issue', "1", - 'digest_work_dir', "", - 'digest_name', "$ml", - 'digest_archive', "", - 'digest_rm_footer', "", - 'digest_rm_fronter', "", - 'digest_maxlines', "", - 'digest_maxdays', "", - 'comments', "" - ); -} - - -# -# Mailman mailing list params that are not derived from Majordomo mailing lists params -# (e.g. bounce_matching_headers+forbbiden_posters vs. taboo_headers+taboo_body) -# If you need one of this params to be variable remove it here and add some code to the -# main procedure; additionally, you should compare it with what you have in -# /usr/lib/mailman/Mailman/mm_cfg.py -# - -sub init_defaultmmconf { - - %defaultmmconf=( - 'goodbye_msg', "\'\'", - 'umbrella_list', "0", - 'umbrella_member_suffix', "\'$umbrella_member_suffix\'", - 'send_reminders', "0", - 'admin_immed_notify', "1", - 'admin_notify_mchanges', "0", - 'dont_respond_to_post_requests', "0", - 'obscure_addresses', "1", - 'require_explicit_destination', "1", - 'acceptable_aliases', "\"\"\"\n\"\"\"\n", - 'max_num_recipients', "10", - 'forbidden_posters', "[]", - 'bounce_matching_headers', "\"\"\"\n\"\"\"\n", - 'anonymous_list', "0", - 'nondigestable', "1", - 'digestable', "1", - 'digest_is_default', "0", - 'mime_is_default_digest', "0", - 'digest_size_threshhold', "40", - 'digest_send_periodic', "1", - 'digest_header', "\'\'", - 'bounce_processing', "1", - 'minimum_removal_date', "4", - 'minimum_post_count_before_bounce_action', "3", - 'max_posts_between_bounces', "5", - 'automatic_bounce_action', "3", - 'archive_private', "0", - 'clobber_date', "1", - 'archive_volume_frequency', "1", - 'autorespond_postings', "0", - 'autoresponse_postings_text', "\'\'", - 'autorespond_admin', "0", - 'autoresponse_admin_text', "\'\'", - 'autorespond_requests', "0", - 'autoresponse_request_text', "\'\'", - 'autoresponse_graceperiod', "90" - ); -} - -# -# convert a Majordomo mailing list configuration (%mlconf) into a -# Mailman mailing list configuration (%mmconf) -# only those params are affected which can be derived from Majordomo -# mailing list configurations -# - -sub m2m { - - my $elem; - my $admin; - - $mmconf{"real_name"} = "\'" . $mlconf{"name"} . "\'"; - - # Mailman does not know the difference between owner and approver - for $admin (($mlconf{"primaryowner"}, @{$mlconf{"secondaryowner"}}, - $mlconf{"primaryapprover"}, @{$mlconf{"secondarapprover"}})) { - # merging owners and approvers may result in a loop: - if (lc($admin) ne lc("owner-" . $mlconf{"name"} . "\@" . $mydomain)) { - $mmconf{"owner"} .= ",\'" . "$admin" . "\'"; - } - } - $mmconf{"owner"} =~ s/^,//g; - $mmconf{"owner"} = "\[" . $mmconf{"owner"} . "\]"; - - # remove characters that will break Python - ($mmconf{"description"} = $mlconf{"description"}) =~ s/\'/\\\'/g; - $mmconf{"description"} = "\'" . $mmconf{"description"} . "\'"; - - $mmconf{"info"} = "\"\"\"\n" . $mlconf{"info"} . "\"\"\"\n"; - - $mmconf{"subject_prefix"} = "\'" . $mlconf{"subject_prefix"} . "\'"; - - $mmconf{"welcome_msg"} = "\"\"\"\n" . $mlconf{"intro"} . "\"\"\"\n"; - - # I don't know how to handle this because the reply_to param in the lists - # I had were not configured consistently - if ($mlconf{"reply_to"} =~ /\S+/) { - if ($mlconf{"name"} . "\@" =~ m/$mlconf{"reply_to"}/i) { - $mmconf{"reply_goes_to_list"} = "1"; - $mmconf{"reply_to_address"} = "\'\'"; - } - else { - $mmconf{"reply_goes_to_list"} = "2"; - $mmconf{"reply_to_address"} = "\'" . $mlconf{"reply_to"} . "\'"; - } - } - else { - $mmconf{"reply_goes_to_list"} = "0"; - $mmconf{"reply_to_address"} = "\'\'"; - } - - $mmconf{"administrivia"} = ($mlconf{"administrivia"} =~ m/yes/i) ? "1" : "0"; - $mmconf{"send_welcome_msg"} = ($mlconf{"welcome"} =~ m/yes/i) ? "1" : "0"; - - $mmconf{"max_message_size"} = int ($mlconf{"maxlength"} / 1000); - - $mmconf{"host_name"} = ($mlconf{"resend_host"} =~ /\S+/) ? - $mlconf{"resend_host"} : "\'" . $mydomain . "\'"; - - $mmconf{"web_page_url"} = "\'" . $myurl . "\'"; - - # problematic since Mailman does not know access patterns - # I assume, that if there was given a noadvertise pattern, the - # list shouldn't be visible at all - $mmconf{"advertised"} = ($mlconf{"noadvertise"} =~ /\.\*/) ? "0" : "1"; - - # confirm+approval is much to long winded for private sites - $mmconf{"subscribe_policy"} = - ($mlconf{"subscribe_policy"} =~ m/(open|auto)/i) ? "1" : - ($private =~ m/yes/i) ? "2" : "3"; - - # in case this is a private site allow list visiblity at most - $mmconf{"private_roster"} = - ($mlconf{"who_access"} =~ m/open/i and not $private =~ m/yes/i) ? "0" : - ($mlconf{"who_access"} =~ m/open|list/i) ? "1" : "2"; - - $mmconf{"moderated"} = ($mlconf{"moderate"} =~ m/yes/i) ? "1" : "0"; - # there is no way to a set a separate moderator in Mailman - - # external, since lengthy - mm_posters(); - - if ($mlconf{"message_fronter"} =~ /\S+/) { - $mmconf{"msg_header"} = "\"\"\"\n" . $mlconf{"message_fronter"} . "\"\"\"\n"; - } - else { - $mmconf{"msg_header"} = "\'\'"; - } - - if ($mlconf{"message_footer"} =~ /\S+/) { - $mmconf{"msg_footer"} = "\"\"\"\n" . $mlconf{"message_footer"} . "\"\"\"\n"; - } - else { - $mmconf{"msg_footer"} = "\'\'"; - } - - # gateway to news - $mmconf{"nntp_host"} = "\'" . $newsserver . "\'"; - $mmconf{"linked_newsgroup"} = "\'" . $newsprefix . $mlconf{"name"} . "\'"; - - if ($mlconf{"gated"} =~ m/yes/i) { - $mmconf{"gateway_to_news"} = "1"; - $mmconf{"gateway_to_mail"} = "1"; - $mmconf{"archive"} = "1"; - } - else { - $mmconf{"gateway_to_news"} = "0"; - $mmconf{"gateway_to_mail"} = "0"; - $mmconf{"archive"} = "0"; - } - - # print warnings if this seems to be an umbrella list - for $elem (@{$mlconf{"privileged"}}, @{$mlconf{"members"}}) { - $elem =~ s/\@$mydomain//gi; - if (defined($mlaliases{$elem . $umbrella_member_suffix})) { - print STDERR "\"" . $mlconf{"name"} . - "\" possibly forms part off/is an umbrella list, since \"$elem\" is a local mailing list alias\n"; - } - } - - # print warnings if we encountered a Taboo-Header or Taboo-Body - if ($mlconf{"taboo_headers"} =~ /\S+/ or $mlconf{"taboo_body"} =~ /\S+/) { - print STDERR "\"" . $mlconf{"name"} . "\" taboo_headers or taboo_body seem to be set - please check manually.\n"; - } -} - -# -# with some set theory on the member and priviliged list try to determine the params -# $mmconf{"member_posting_only"} and $mmconf{"posters"} -# - -sub mm_posters { - if ($mlconf{"restrict_post"} =~ /\S+/) { - my %privileged = (); - my %members = (); - my $key; - - foreach $key (@{$mlconf{"privileged"}}) { $privileged{$key} = "OK"; } - foreach $key (@{$mlconf{"members"}}) { $members{$key} = "OK"; } - - # are all members privileged, too ? - my $included = 1; - foreach $key (keys %members) { - if (not exists $privileged{$key}) { - $included = 0; - last; - } - } - if ($included) { - $mmconf{"member_posting_only"} = "1"; - - # posters = privileged - members: - my %diff = %privileged; - foreach $key (keys %members) { - delete $diff{$key} if exists $members{$key}; - } - - $mmconf{"posters"} = ""; - for $key (sort keys %diff) { - $mmconf{"posters"} .= ",\'" . $key . "\'"; - } - $mmconf{"posters"} =~ s/^,//g; - $mmconf{"posters"} = "[" . $mmconf{"posters"} . "]"; - } - else { - $mmconf{"member_posting_only"} = "0"; - - # posters = privileged: - $mmconf{"posters"} = ""; - for $key (sort keys %privileged) { - $mmconf{"posters"} .= ",\'" . $key . "\'"; - } - $mmconf{"posters"} =~ s/^,//g; - $mmconf{"posters"} = "[" . $mmconf{"posters"} . "]"; - } - } - else { - $mmconf{"member_posting_only"} = "0"; - $mmconf{"posters"} = "[]"; - } -} - diff --git a/contrib/mm-handler b/contrib/mm-handler deleted file mode 100644 index 0535cbfb8..000000000 --- a/contrib/mm-handler +++ /dev/null @@ -1,236 +0,0 @@ -#!/usr/local/bin/perl -## -## Sendmail mailer for Mailman -## -## Simulates these aliases: -## -##testlist: "|/home/mailman/mail/mailman post testlist" -##testlist-admin: "|/home/mailman/mail/mailman admin testlist" -##testlist-bounces: "|/home/mailman/mail/mailman bounces testlist" -##testlist-confirm: "|/home/mailman/mail/mailman confirm testlist" -##testlist-join: "|/home/mailman/mail/mailman join testlist" -##testlist-leave: "|/home/mailman/mail/mailman leave testlist" -##testlist-owner: "|/home/mailman/mail/mailman owner testlist" -##testlist-request: "|/home/mailman/mail/mailman request testlist" -##testlist-subscribe: "|/home/mailman/mail/mailman subscribe testlist" -##testlist-unsubscribe: "|/home/mailman/mail/mailman unsubscribe testlist" -##owner-testlist: testlist-owner - -## Some assembly required. -$MMWRAPPER = "/home/mailman/mail/mailman"; -$MMLISTDIR = "/home/mailman/lists"; -$SENDMAIL = "/usr/lib/sendmail -oem -oi"; -$VERSION = '$Id: mm-handler 5100 2002-04-05 19:41:09Z 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); - my @validfields = qw(admin bounces confirm join leave owner request - subscribe unsubscribe); - - if ($addr =~ /(.*)-(.*)\+.*$/) { - $list = $1; - $cmd = "$2"; - } else { - $addr =~ /(.*)-(.*)$/; - $list = $1; - $cmd = $2; - } - if (grep /^$cmd$/, @validfields) { - if ($list eq "owner") { - $list = $cmd; - $cmd = "owner"; - } - } 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.pck") { - ($list, $cmd) = &split_addr($list); - if (! -f "$MMLISTDIR/$list/config.pck") { - $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/mmdsr b/contrib/mmdsr deleted file mode 100644 index 25c52e0f7..000000000 --- a/contrib/mmdsr +++ /dev/null @@ -1,572 +0,0 @@ -#!/bin/sh -############################################################################### -# mmdsr -- Mailman Daily Status Report (cron job, run at 23:59) -############################################################################### -# Copyright (c) 2005, Brad Knowles -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions -# are met: -# -# Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# -# Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# -# The name of the author or other contributors may not be used -# to endorse or promote products derived from this software without -# specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -# POSSIBILITY OF SUCH DAMAGE. -############################################################################### - -############################################################################### -# Version history -############################################################################### -# 0.0.1 Initial creation by Brad Knowles <brad@stop.mail-abuse.org> -# Created on: Tue Feb 15 04:01:20 PST 2005 -# -# 0.0.2 Update by Brad Knowles <brad@stop.mail-abuse.org> -# Updated on: Wed Feb 16 18:55:52 CET 2005 -# Feedback from Tom G. Christensen (tgc99): -# > The current UID grab command doesn't work on Solaris -# > (2.6 & 8 tested). -# > -# > I'd recommend this instead: -# > ps -o user -p $$|tail -1 -# > -# > This is tested and works on RH 6.2, RH 7.3, RHEL 2.1, -# > RHEL3, FC3, FreeBSD 4.9, Solaris 2.6, 8. -# -# 0.0.3 Update by Brad Knowles <brad@stop.mail-abuse.org> -# Updated on: Sun Mar 13 01:15:24 CET 2005 -# Noted errors from grep when trying to search a nonexistant -# file. Added "-s" option to compensate, and extra code to -# notify the admin if the log file doesn't exist. -# -# 0.0.4 Update by Brad Knowles <brad@stop.mail-abuse.org> -# Updated on: Sun Mar 13 01:58:37 CET 2005 -# Eliminate some extra cruft from the "fromusenet" logs. -# -# 0.0.5 Update by Brad Knowles <brad@stop.mail-abuse.org> -# Updated on: Wed Apr 13 00:54:42 CEST 2005 -# Eliminate a lot of extra cruft from the "error" & "vette" logs. -# Eliminate more cruft from the "fromusenet" logs. -# -# 0.0.6 Update by Brad Knowles <brad@stop.mail-abuse.org> -# Updated on: Thu Apr 14 03:07:08 CEST 2005 -# Eliminate even more cruft from the "fromusenet" logs. -# Eliminate more cruft from the "vette" logs. -# Eliminate cruft from the "mischief" logs. -# -# 0.0.7 Update by Brad Knowles <brad@stop.mail-abuse.org> -# Updated on: Sun May 1 22:29:13 CEST 2005 [guess] -# The "error" log "no such list" errors didn't need to be -# quite so "compressed", open them up to be more readable. -# Also eliminate all use of "xargs", use "fmt -w 75" instead. -# -# 0.0.8 Update by Brad Knowles <brad@stop.mail-abuse.org> -# Updated on: Sun May 1 23:09:13 CEST 2005 -# Clean up code for queue subdirectories to check. -# -# 0.0.9 Update by Brad Knowles <brad@stop.mail-abuse.org> -# Updated on: Wed May 11 01:23:40 CEST 2005 -# Eliminate date/time stamps from the rest of the logs, -# then pipe through `sort | uniq -c | sort -nr` -# so that all possible duplicates are eliminated. -# -# 0.0.10 Update by Brad Knowles <brad@stop.mail-abuse.org> -# Updated on: Tue Jul 12 16:53:49 CDT 2005 -# Add code to do summary of normal list activity -# -# 0.0.11 Update by Brad Knowles <brad@stop.mail-abuse.org> -# Updated on: Tue Sep 6 15:44:19 CEST 2005 -# Tweaked display of Mailman/qfiles subdirectories -# so as to avoid displaying more than $MAX_LINES -# output, which really helps if you have thousands -# of bounces sitting around, etc.... -# Also slightly tweaked display of fromusenet logs -# to split summary from errors. -# -# 0.0.12 Update by Brad Knowles <brad@stop.mail-abuse.org> -# Updated on: Thu Sep 22 22:37:35 CEST 2005 -# Bugs found by Mark Sapiro and Adrian Wells. -# Mark suggested splitting the Mailman log directory -# from the rest of the Mailman source and queues, -# as well as making sure to clean up all temp files. -# Adrian discovered that there was a log file format -# change between Mailman 2.1.5 and 2.1.6, which broke -# hourly statistics. -# -# 0.0.13 Update by Brad Knowles <brad@stop.mail-abuse.org> -# Updated on: Mon Dec 26 05:54:27 CET 2005 -# Bugs found by Tom G. Christensen (tgc99): -# > ps output on solaris is full of whitespace but a further -# > echo get's rid of it. -# > The lines in the smtp log are sometimes broken up by a -# > newline (right before the msgid) which throws of the -# > summary. Piping it through sed first will rejoin the broken -# > lines. -# > Use $AWK instead of awk. -# Enhancements from Mark Sapiro: -# > The vette log summary lists posts held for moderation -# > individually under "Other Errors:". The following patch -# > (watch out for wrapped lines) summarizes them by list instead. -# -# 0.0.14 Update by Brad Knowles <brad@stop.mail-abuse.org> -# Updated on: Thu Dec 29 08:17:38 CET 2005 -# Added code to check /usr/local/mailman/data for -# moderation hold queue -# -# 0.0.15 Update by Brad Knowles <brad@stop.mail-abuse.org> -# Updated on: Thu Jan 26 02:39:38 CET 2006 -# Tweaked display of summary data in the "smtp-failure" log, -# and "other" category in the "vette" log, so as to reduce -# the spewage when things go wonky, mostly by removing -# unique-ifying data like message-id or sender address. -# Also tweaked moderation queue information, to tell us -# how many Python pickle files are in the data directory, -# as opposed to just doing a directory listing and skipping -# the files in the middle if there are too many -- now we -# know how many are being skipped. -# -# 0.0.16 Update by Brad Knowles <brad@stop.mail-abuse.org> -# Updated on: Sun Jan 29 11:45:58 CET 2006 -# Mark found a couple of typos that I somehow let slip -# through. Thanks! - -############################################################################### -# Set up locations of standard commands, directories, etc.... -# You may need to modify these for your platform or installation. -############################################################################### - -AWK="/usr/bin/awk" -BASENAME="/usr/bin/basename" -CAT="/bin/cat" -DATE="/bin/date" -EGREP="/bin/egrep" -FMT="/usr/bin/fmt" -GREP="/bin/grep" -HEAD="/usr/bin/head" -LS="/bin/ls" -PS="/bin/ps" -RM="/bin/rm" -SED="/bin/sed" -SENDMAIL="/usr/sbin/sendmail" -SLEEP="/bin/sleep" -SORT="/usr/bin/sort" -TAIL="/usr/bin/tail" -TOUCH="/bin/touch" -TR="/usr/bin/tr" -UNIQ="/usr/bin/uniq" -XARGS="/usr/bin/xargs" -WC="/usr/bin/wc" - -############################################################################### -# Directory for temporary files -############################################################################### -TMPDIR="/tmp" - -############################################################################### -# Mailman queue directory -############################################################################### -QUEUEDIR="/usr/local/mailman/qfiles" - -############################################################################### -# Mailman log directory -############################################################################### -LOGDIR="/usr/local/mailman/logs" - -############################################################################### -# Mailman data directory -############################################################################### -DATADIR="/usr/local/mailman/data" - -############################################################################### -# Maximum number of subdirectory entries to display in report -############################################################################### -MAX_QUEUE_LINES=20 - -############################################################################### -# Maximum number of moderation queue pickle files to display in report -############################################################################### -MAX_DATA_LINES=100 - -############################################################################### -# Mailman Log files to check for errors. -# No need to specify path, only log file name. -############################################################################### -ERR_LOGS="error fromusenet locks mischief post qrunner smtp-failure vette" - -############################################################################### -# Mailman Log files to summarize. -# No need to specify path, only log file name. -############################################################################### -SUM_LOGS="fromusenet post smtp" - -############################################################################### -# Mailman queue subdirectories to check. No need to specify path, only name. -############################################################################### -SUBDIRS="archive bounces commands in news out retry shunt virgin" - -############################################################################### -# Specify recipients for report. If none, then simply print to "STDOUT". -# Specify sender address for report. Not used if recipient list is empty. -############################################################################### - -SENDER="INSERT.YOUR.SENDER.ADDRESS@HERE" -RCPTS="INSERT.YOUR.RECIPIENTS.ADDRESSES@HERE" - -############################################################################### -# If you run this program in cron at 23:59:00, you need to sleep sixty -# seconds to make sure that you capture all the logs for the previous day. -# Comment this line out to disable sleeping altogether. -############################################################################### - -SLEEPTIME=60 - -############################################################################### -# What user id is Mailman installed under? -# How do we determine what UID this program is running as? -# NB: There will probably be SysV vs. BSD semantic differences here. -# Be careful. Make sure the command you specify actually works. -# The command string specified here may seem arcane, but should pull -# out the information we need, and throw away everything else. If -# there is an easier cross-platform way to do it, please let me know. -############################################################################### - -GRABUID=`$PS -o user -p $$ | $TAIL -1` -MYUID=`echo $GRABUID` -RUNAS="mailman" - -############################################################################### -# No modifications below this line should be required. -############################################################################### - -DAY=`$DATE '+%b %d'` -YEAR=`$DATE '+%Y'` - -PROG=`$BASENAME $0` - -if [ "${MYUID}" != "${RUNAS}" -a "${MYUID}" != "root" ] ; then - echo "ERROR: You must be root or ${RUNAS} to run $PROG." - exit 1 -fi - -if [ "${SLEEPTIME}" != "" -a "${RCPTS}x" != "${SENDER}x" ] ; then - if [ $SLEEPTIME -gt 0 ] ; then - $SLEEP $SLEEPTIME - fi -fi - -TMP="$TMPDIR/.$PROG.$$" -TMPLOG="$TMP.log" -$RM -f $TMP -$TOUCH $TMP - -if [ "${RCPTS}x" != "x" ] ; then - echo "From: ${SENDER}" >> $TMP - echo "To: ${RCPTS}" >> $TMP - echo "Subject: Mailman Daily Status Report: $DAY $YEAR" >> $TMP - echo "" >> $TMP -fi - -echo " Mailman Daily Status Report: $DAY $YEAR" >> $TMP -echo "" >> $TMP -echo "" >> $TMP - -echo "******************************" >> $TMP -echo "Log File Summary" >> $TMP -echo "******************************" >> $TMP -echo "" >> $TMP - -for LOG in $SUM_LOGS -do - - $RM -f $TMPLOG - $TOUCH $TMPLOG - echo "Log file: $LOG" >> $TMP - echo "==============================" >> $TMP - - if [ -f "$LOGDIR/${LOG}" ] ; then - $SED -e :a -e '$!N;s/\n //;ta' -e 'P;D' $LOGDIR/$LOG | $GREP -si "^$DAY [0-9][0-9:]* $YEAR" >> $TMPLOG - - if [ "${LOG}" = "post" ] ; then - - echo "" >> $TMP - echo "Hourly Summary of Posts" >> $TMP - echo "-----------------------" >> $TMP - - $SED -e 's/^[A-Z][a-z][a-z] *[0-9]* //' -e 's/:.*$//' $TMPLOG | $UNIQ -c | $SORT -n +1 | $AWK '{ printf( "%8d %02d:00-%02d:59\n", $1, $2, $2 ) }' >> $TMP - - echo "" >> $TMP - echo "Post Count by List" >> $TMP - echo "------------------" >> $TMP - - $SED -e 's/^.* post to //' -e 's/ .*$//' $TMPLOG | $SORT | $UNIQ -c | $SORT -nr >> $TMP - - echo "" >> $TMP - echo "Post Count by Sender" >> $TMP - echo "--------------------" >> $TMP - - $SED -e 's/^.* from //' -e 's/,.*$//' $TMPLOG | $SORT | $UNIQ -c | $SORT -nr >> $TMP - - elif [ "${LOG}" = "fromusenet" ] ; then - - GRPS=`$EGREP -vi '(watermark:|nothing new| posted to |: \[[0-9\.]*\])' $TMPLOG | $GREP -i ' gating ' | $AWK '{ print $7 }' | $SORT -u | $FMT -w 75` - - for GRP in $GRPS - do - echo "" >> $TMP - echo "$GRP Article #'s Gated:" >> $TMP - echo "------------------------------" >> $TMP - $EGREP -vi '(watermark:|nothing new| posted to |: \[[0-9\.]*\])' $TMPLOG | $GREP -i " gating " | $GREP -i " $GRP " | $SED -e 's/^.*\[//' -e 's/\]$//' -e 's/\.\./ /' | $TR ' ' '\n' | $SORT -u | $FMT -w 75 >> $TMP - done - - elif [ "${LOG}" = "smtp" ] ; then - - echo "" >> $TMP - echo "Hourly Summary of Messages Sent" >> $TMP - echo "-------------------------------" >> $TMP - $SED -e 's/^[A-Z][a-z][a-z] *[0-9]* //' -e 's/:.* for / /' -e 's/ recips,.*$//' $TMPLOG | $AWK '{ val=int($1); sum[val]+=$2 } END { for (i=0; i<24; i++) { printf "%8d %02d:00-%02d:59\n", sum[i], i, i } }' >> $TMP - - else - - $SED 's/^.* ([0-9]*) //' $TMPLOG | $SORT | $UNIQ -c | $SORT -nr >> $TMP - - fi - - else - - echo " ### Log file ${LOG} does not exist ### " >> $TMP - - fi - - echo "" >> $TMP - -done - -echo "******************************" >> $TMP -echo "Log File Squawks" >> $TMP -echo "******************************" >> $TMP -echo "" >> $TMP - -for LOG in $ERR_LOGS -do - $RM -f $TMPLOG - $TOUCH $TMPLOG - echo "Log file: $LOG" >> $TMP - echo "==============================" >> $TMP - $GREP -si "^$DAY [0-9][0-9:]* $YEAR" $LOGDIR/$LOG >> $TMPLOG - - if [ -f "$LOGDIR/${LOG}" ] ; then - - if [ "${LOG}" = "error" ] ; then - - echo "Uncaught Runner Exceptions:" >> $TMP - echo "------------------------------" >> $TMP - $GREP 'Uncaught runner exception' $TMPLOG | $SED 's/^.*exception: //' | $SORT | $UNIQ -c | $SORT -nr >> $TMP - - echo "" >> $TMP - echo "No Such List:" >> $TMP - echo "------------------------------" >> $TMP - $GREP 'No such list' $TMPLOG | $SED -e 's/^.* "//' -e 's/".*$//' | $SORT | $UNIQ -c | $SORT -nr >> $TMP - - CNT=`$GREP -i 'shunting' $TMPLOG | $WC -l` - if [ "${CNT}x" != "x" ] ; then - if [ ${CNT} -gt 0 ] ; then - echo "" >> $TMP - echo "Shunting Count: $CNT" >> $TMP - echo "------------------------------" >> $TMP - fi - fi - - echo "" >> $TMP - echo "Other Errors:" >> $TMP - echo "------------------------------" >> $TMP - $EGREP -vi '(Uncaught runner exception|No such list|Ignoring unparseable message|Traceback|shunting)' $TMPLOG | $SED 's/^.* ([0-9]*) //' | $SORT | $UNIQ -c | $SORT -nr >> $TMP - - elif [ "${LOG}" = "fromusenet" ] ; then - - $EGREP -vi '(watermark:|nothing new| posted to |: \[[0-9\.]*\])' $TMPLOG | $GREP -vi " gating " | $SED 's/^.* ([0-9]*) //' | $SORT | $UNIQ -c | $SORT -nr >> $TMP - - elif [ "${LOG}" = "mischief" ] ; then - - echo "" >> $TMP - echo "Login failure with private rosters (by user):" >> $TMP - echo "------------------------------" >> $TMP - $GREP -i 'Login failure with private rosters' $TMPLOG | $AWK '{ print $NF }' | $SORT | $UNIQ -c | $SORT -nr >> $TMP - - echo "" >> $TMP - echo "Unsub attempt of non-member (by user):" >> $TMP - echo "------------------------------" >> $TMP - $GREP -i 'Unsub attempt of non-member' $TMPLOG | $AWK '{ print $NF }' | $SORT | $UNIQ -c | $SORT -nr >> $TMP - - echo "" >> $TMP - echo "Reminder attempt of non-member (by user):" >> $TMP - echo "------------------------------" >> $TMP - $GREP -i 'Reminder attempt of non-member' $TMPLOG | $AWK '{ print $NF }' | $SORT | $UNIQ -c | $SORT -nr >> $TMP - - echo "" >> $TMP - echo "Other Messages:" >> $TMP - echo "------------------------------" >> $TMP - $EGREP -vi '(Login failure with private rosters|Unsub attempt of non-member|Reminder attempt of non-member)' $TMPLOG | $SED 's/^.* ([0-9]*) //' | $SORT | $UNIQ -c | $SORT -nr >> $TMP - - elif [ "${LOG}" = "post" ] ; then - - $GREP -vi 'success' $TMPLOG | $SED 's/^.* ([0-9]*) //' | $SORT | $UNIQ -c | $SORT -nr >> $TMP - - elif [ "${LOG}" = "vette" ] ; then - - echo "" >> $TMP - echo "Message held -- Post by non-member (by list):" >> $TMP - echo "------------------------------" >> $TMP - $GREP 'Post by non-member' $TMPLOG | $AWK '{ print $6 }' | $SORT | $UNIQ -c | $SORT -nr >> $TMP - - echo "" >> $TMP - echo "Message held -- Suspicious header (by list):" >> $TMP - echo "------------------------------" >> $TMP - $GREP -i 'suspicious header' $TMPLOG | $AWK '{ print $6 }' | $SORT | $UNIQ -c | $SORT -nr >> $TMP - - echo "" >> $TMP - echo "Discarded posting (by list):" >> $TMP - echo "------------------------------" >> $TMP - $GREP -i 'Discarded posting' $TMPLOG | $AWK '{ print $6 }' | $SED 's/:$//' | $SORT | $UNIQ -c | $SORT -nr >> $TMP - - echo "" >> $TMP - echo "Bulk/Junk message discarded (by list):" >> $TMP - echo "------------------------------" >> $TMP - $EGREP -i '(bulk|junk) message discarded' $TMPLOG | $AWK '{ print $NF }' | $SORT | $UNIQ -c | $SORT -nr >> $TMP - - echo "" >> $TMP - echo "Implicit destination (by list):" >> $TMP - echo "------------------------------" >> $TMP - $GREP -i 'Message has implicit destination' $TMPLOG | $AWK '{ print $6 }' | $SORT | $UNIQ -c | $SORT -nr >> $TMP - - echo "" >> $TMP - echo "Post to moderated newsgroup (by list):" >> $TMP - echo "------------------------------" >> $TMP - $GREP -i 'Posting to a moderated newsgroup' $TMPLOG | $AWK '{ print $6 }' | $SORT | $UNIQ -c | $SORT -nr >> $TMP - - echo "" >> $TMP - echo "Post to moderated list (by list):" >> $TMP - echo "------------------------------" >> $TMP - $GREP -i 'Post to moderated list' $TMPLOG | $AWK '{ print $6 }' | $SORT | $UNIQ -c | $SORT -nr >> $TMP - - echo "" >> $TMP - echo "Other Errors:" >> $TMP - echo "------------------------------" >> $TMP - $EGREP -vi '(Post by non-member|suspicious header|message approved|Discarded posting|bulk message discarded|junk message discarded|Message has implicit destination|Posting to a moderated newsgroup|Post to moderated list|Message discarded, msgid)' $TMPLOG | $SED -e 's/^.* ([0-9]*) //' -e 's/, message-id=<[^> ]*>:/:/' | $SORT | $UNIQ -c | $SORT -nr >> $TMP - - elif [ "${LOG}" = "smtp-failure" ] ; then - - $SED 's/^.* ([0-9]*) //' $TMPLOG | $SED 's/delivery to [^@ ]*@[^@ ]* failed with code/delivery failed with code/g' | $SORT | $UNIQ -c | $SORT -nr >> $TMP - - else - - $SED 's/^.* ([0-9]*) //' $TMPLOG | $SORT | $UNIQ -c | $SORT -nr >> $TMP - - fi - else - - echo " ### Log file ${LOG} does not exist ### " >> $TMP - - fi - echo "" >> $TMP - -done - -echo "******************************" >> $TMP -echo "Queue Directory Contents" >> $TMP -echo "******************************" >> $TMP -echo "" >> $TMP - -cd $QUEUEDIR -for DIR in $SUBDIRS -do - - $RM -f $TMPLOG - $TOUCH $TMPLOG - $LS -la $DIR >> $TMPLOG - LINES=`$WC -l < $TMPLOG` - LINES=`expr $LINES - 3` - - echo "Subdirectory: $DIR" >> $TMP - echo "==============================" >> $TMP - echo "Entries: $LINES" >> $TMP - echo "------------------------------" >> $TMP - - if [ $LINES -le $MAX_QUEUE_LINES ] ; then - $CAT $TMPLOG >> $TMP - else - $HEAD $TMPLOG >> $TMP - echo "" >> $TMP - echo " More than $MAX_QUEUE_LINES total entries, skipping ..." >> $TMP - echo "" >> $TMP - $TAIL $TMPLOG >> $TMP - fi - echo "" >> $TMP - -done - -echo "******************************" >> $TMP -echo "Data Directory Contents" >> $TMP -echo " (Python pickle files only)" >> $TMP -echo "******************************" >> $TMP - -cd $DATADIR - -$RM -f $TMPLOG -$TOUCH $TMPLOG -$LS -la | $GREP -i '\.pck$' >> $TMPLOG -LINES=`$WC -l < $TMPLOG` - -echo "Python pickle files: $LINES" >> $TMP -echo "==============================" >> $TMP -echo "" >> $TMP - -if [ $LINES -le $MAX_DATA_LINES ] ; then - $CAT $TMPLOG >> $TMP -else - $HEAD $TMPLOG >> $TMP - echo "" >> $TMP - echo " More than $MAX_DATA_LINES total entries, skipping ..." >> $TMP - echo "" >> $TMP - $TAIL $TMPLOG >> $TMP -fi -echo "" >> $TMP - -echo "******************************" >> $TMP -echo "Moderation Queue Summary" >> $TMP -echo "******************************" >> $TMP -echo "" >> $TMP - -$AWK '{ print $NF }' $TMPLOG | $GREP -i '^heldmsg-' | $SED -e 's/^heldmsg-//' -e 's/-[0-9]*\.pck$//' | $SORT | $UNIQ -c | $SORT -nr >> $TMP -echo "" >> $TMP - -############################################################################### -# Okay, we're done with all the code stuff, now handle the output -############################################################################### - -if [ "${RCPTS}x" != "x" ] ; then - $SENDMAIL -t -f$SENDER < $TMP -else - $CAT $TMP -fi - -$RM $TMP $TMPLOG diff --git a/contrib/qmail-to-mailman.py b/contrib/qmail-to-mailman.py deleted file mode 100644 index 3e4e19d5b..000000000 --- a/contrib/qmail-to-mailman.py +++ /dev/null @@ -1,116 +0,0 @@ -#! @PYTHON@ - -# Configuration variables - Change these for your site if necessary. -MailmanHome = "@prefix@"; # Mailman home directory. -MailmanVar = "@VAR_PREFIX@"; # Mailman directory for mutable data. -MailmanOwner = "postmaster@localhost"; # Postmaster and abuse mail recepient. -# End of configuration variables. - -# qmail-to-mailman.py -# -# Interface mailman to a qmail virtual domain. Does not require the creation -# of _any_ aliases to connect lists to your mail system. -# -# Bruce Perens, bruce@perens.com, March 1999. -# This is free software under the GNU General Public License. -# -# This script is meant to be called from ~mailman/.qmail-default . It catches -# all mail to a virtual domain, in my case "lists.hams.com". It looks at the -# recepient for each mail message and decides if the mail is addressed to a -# valid list or not, and bounces the message with a helpful suggestion if it's -# not addressed to a list. It decides if it is a posting, a list command, or -# mail to the list administrator, by checking for the -admin, -owner, and -# -request addresses. It will recognize a list as soon as the list is created, -# there is no need to add _any_ aliases for any list. It recognizes mail to -# postmaster, mailman-owner, abuse, mailer-daemon, root, and owner, and -# routes those mails to MailmanOwner as defined in the configuration -# variables, above. -# -# INSTALLATION: -# -# Install this file as ~mailman/qmail-to-mailman.py -# -# To configure a virtual domain to connect to mailman, create these files: -# -# ~mailman/.qmail-default -# |preline @PYTHON@ @prefix@/mail-in.py -# -# /var/qmail/control/virtualdomains: -# DOMAIN.COM:mailman -# -# Note: "preline" is a QMail program which ensures a Unix "From " header is -# on the message. Archiving will break without this. -# -# Replace DOMAIN.COM above with the name of the domain to be connected to -# Mailman. Note that _all_ mail to that domain will go to Mailman, so you -# don't want to put the name of your main domain here. In my case, I created -# lists.hams.com for Mailman, and I use hams.com as my regular domain. -# -# After you edit /var/qmail/control/virtualdomains, kill and restart qmail. -# - -import sys, os, re, string - -def main(): - os.nice(5) # Handle mailing lists at non-interactive priority. - - os.chdir(MailmanVar + "/lists") - - try: - local = os.environ["LOCAL"] - except: - # This might happen if we're not using qmail. - sys.stderr.write("LOCAL not set in environment?\n") - sys.exit(100) - - local = string.lower(local) - local = re.sub("^mailman-","",local) - - names = ("root", "postmaster", "mailer-daemon", "mailman-owner", "owner", - "abuse") - for i in names: - if i == local: - os.execv("/var/qmail/bin/qmail-inject", - ("/var/qmail/bin/qmail-inject", MailmanOwner)) - sys.exit(0) - - type = "post" - types = (("-admin$", "bounces"), - ("-bounces$", "bounces"), - ("-join$", "join"), - ("-leave$", "leave"), - ("-owner$", "owner"), - ("-request$", "request")) - - for i in types: - if re.search(i[0],local): - type = i[1] - local = re.sub(i[0],"",local) - - if os.path.exists(local): - os.execv(MailmanHome + "/mail/mailman", - (MailmanHome + "/mail/mailman", type, local)) - else: - bounce() - sys.exit(111) - -def bounce(): - bounce_message = """\ -TO ACCESS THE MAILING LIST SYSTEM: Start your web browser on -http://%s/ -That web page will help you subscribe or unsubscribe, and will -give you directions on how to post to each mailing list.\n""" - sys.stderr.write(bounce_message % (os.environ["HOST"])) - sys.exit(100) - -try: - sys.exit(main()) -except SystemExit, argument: - sys.exit(argument) - -except Exception, argument: - info = sys.exc_info() - trace = info[2] - sys.stderr.write("%s %s\n" % (sys.exc_type, argument)) - sys.stderr.write("Line %d\n" % (trace.tb_lineno)) - sys.exit(111) # Soft failure, try again later. diff --git a/contrib/rotatelogs.py b/contrib/rotatelogs.py deleted file mode 100644 index 168acb567..000000000 --- a/contrib/rotatelogs.py +++ /dev/null @@ -1,104 +0,0 @@ -#! @PYTHON@ -# -# Copyright (C) 2000-2007 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, -# USA. - -"""Check the error logs and send any which have information in them. - -If any log entries exist, a message is sent to the mailman owner address -and the logs are rotated. -""" - -# GETTING STARTED -# -# Run this program as root from cron, preferably at least daily. Running -# as root is optional, but will preserve the various modes and ownerships -# of log files in "~mailman/logs". If any entries are in "errors" or -# "smtp-errors", they will be mailed to the mailman owner address. -# -# Set COMPRESS_LOGFILES_WITH in mm_cfg.py to "gzip" to get rotated logfiles -# to be compressed. -# -# Hacked from some existing Mailman code by -# Sean Reifschneider <jafo-mailman@tummy.com> -# Please direct questions on this to the above address. -# - -showLines = 100 # lines of log messages to display before truncating - -import sys, os, string, time, errno -import paths -from Mailman import mm_cfg, Utils -import fileinput, socket, time, stat - -# Work around known problems with some RedHat cron daemons -import signal -signal.signal(signal.SIGCHLD, signal.SIG_DFL) - - -newLogfiles = [] -text = [] -text.append('Mailman Log Report') -text.append('Generated: %s' % time.ctime(time.time())) -text.append('Host: %s' % socket.gethostname()) -text.append('') - -logDate = time.strftime('%Y%m%d-%H%M%S', time.localtime(time.time())) -textSend = 0 -for log in ( 'error', 'smtp-failures' ): - fileName = os.path.join(mm_cfg.LOG_DIR, log) - - # rotate file if it contains any data - stats = os.stat(fileName) - if stats[stat.ST_SIZE] < 1: continue - fileNameNew = '%s.%s' % ( fileName, logDate ) - newLogfiles.append(fileNameNew) - os.rename(fileName, fileNameNew) - open(fileName, 'w') - os.chmod(fileName, stat.S_IMODE(stats[stat.ST_MODE])) - try: os.chown(fileName, stats[stat.ST_UID], stats[stat.ST_GID]) - except OSError: pass # permission denied, DOH! - - textSend = 1 - tmp = '# FILE: %s #' % fileNameNew - text.append('#' * len(tmp)) - text.append(tmp) - text.append('#' * len(tmp)) - text.append('') - - linesLeft = showLines # e-mail first linesLeft of log files - for line in fileinput.input(fileNameNew): - if linesLeft == 0: - text.append('[... truncated ...]') - break - linesLeft = linesLeft - 1 - line = string.rstrip(line) - text.append(line) - text.append('') - -# send message if we've actually found anything -if textSend: - text = string.join(text, '\n') + '\n' - siteowner = Utils.get_site_email() - Utils.SendTextToUser( - 'Mailman Log Report -- %s' % time.ctime(time.time()), - text, siteowner, siteowner) - -# compress any log-files we made -if hasattr(mm_cfg, 'COMPRESS_LOGFILES_WITH') and mm_cfg.COMPRESS_LOGFILES_WITH: - for file in newLogfiles: - os.system(mm_cfg.COMPRESS_LOGFILES_WITH % file) diff --git a/contrib/virtusertable b/contrib/virtusertable deleted file mode 100644 index eb5eb744b..000000000 --- a/contrib/virtusertable +++ /dev/null @@ -1,37 +0,0 @@ -## -## 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 |
