[Mailman-Users] Re: Mailman-Users digest, Vol 1 #376 - 9 msgs

klm klm at digicool.com
Tue Nov 2 20:10:46 CET 1999

> Date: Mon, 01 Nov 1999 14:39:26 -0400
> From: "Joshua S. Freeman" <jfreeman at scansoft.com>
> To: mailman <mailman-users at python.org>
> Subject: [Mailman-Users] non-subscribed ex members receiving password reminders
> why does this happen?  how can I make it stop?

Simply enough, it's a bug.  If i recall correctly, it's been addressed in
more recent versions of mailman - the new version may even have a
procedure to wipe the orphaned password entries, or at least disregard
them if there's no corresponding account.

However, if like me you haven't had the time to upgrade*, below is a
script i just cobbled together to clean the passwords on my site.  Read
the module docstring at the top for details, including instructions for

Ken Manheimer
klm at digicool.com

(* Sigh - i haven't even gotten near hacking mailman code in a while - i'm
thankful that barry and others have been taking care of crucial stuff!)

8<---------------------------- cleanpasswds --------------------------->8

#!/usr/bin/env python

"""Identify and offer to delete orphaned passwords in any mailman lists.

I believe that more recent mailman versions rectify this problem, this is a 
quick and dirty hack to tide you over until you have time to upgrade.

To use this, put it in your ~mailman/bin dir as, eg, 'cleanpasswds', then
run as the mailman user with 'python bin/cleanpasswds'.  It will show any
orphaned passwords it finds for each list, and offer to remove them.

It's important to run as mailman, so list files maintain the right uid.

ken manheimer, klm at digicool.com 11/02/1999."""

import string

import paths

from Mailman.Utils import map_maillists
from Mailman.MailList import MailList

def mine(l, find=string.find, lower=string.lower):
    """Return a list of password entry ids lacking any corresponding acount."""
    got = []
    accts = l.members.copy()
    for i in l.passwords.keys():
        if not accts.has_key(lower(i)): got.append(i)
    return got

def query_clean(l):
    print l.real_name,
    got = mine(l)
    if not got:
        print "- No stale password entries found"
        print "- %s stale password entries:" % len(got)
        print got
        msg = "Delete these %s stale password entries? [y] " % l.real_name
        confirm = raw_input(msg)
        if not confirm or (string.lower(confirm) == 'y'):
            print "Deleting...",
            # We may block here on obtaining the lock.
            l = MailList(l._internal_name)
            for i in got:
                del l.passwords[i]
            print " done."

if __name__ == "__main__":
    map_maillists(query_clean, unlock=1)

More information about the Mailman-Users mailing list