diff options
Diffstat (limited to 'bin/change_pw')
-rw-r--r-- | bin/change_pw | 209 |
1 files changed, 209 insertions, 0 deletions
diff --git a/bin/change_pw b/bin/change_pw new file mode 100644 index 00000000..0e365e08 --- /dev/null +++ b/bin/change_pw @@ -0,0 +1,209 @@ +#! @PYTHON@ +# +# Copyright (C) 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +"""Change a list's password. + +Prior to Mailman 2.1, list passwords were kept in crypt'd format -- usually. +Some Python installations didn't have the crypt module available, so they'd +fall back to md5. Then suddenly the Python installation might grow a crypt +module and all list passwords would be broken. + +In Mailman 2.1, all list and site passwords are stored in SHA1 hexdigest +form. This breaks list passwords for all existing pre-Mailman 2.1 lists, and +since those passwords aren't stored anywhere in plain text, they cannot be +retrieved and updated. + +Thus, this script generates new passwords for a list, and optionally sends it +to all the owners of the list. + +Usage: change_pw [options] + +Options: + + --all / -a + Change the password for all lists. + + --domain=domain + -d domain + Change the password for all lists in the virtual domain `domain'. It + is okay to give multiple -d options. + + --listname=listname + -l listname + Change the password only for the named list. It is okay to give + multiple -l options. + + --password=newpassword + -p newpassword + Use the supplied plain text password `newpassword' as the new password + for any lists that are being changed (as specified by the -a, -d, and + -l options). If not given, lists will be assigned a randomly + generated new password. + + --quiet / -q + Don't notify list owners of the new password. You'll have to have + some other way of letting the list owners know the new password + (presumably out-of-band). + + --help / -h + Print this help message and exit. +""" + +import sys +import sha +import getopt + +import paths +from Mailman import mm_cfg +from Mailman import Utils +from Mailman import MailList +from Mailman import Errors +from Mailman import Message +from Mailman import i18n + +_ = i18n._ + +SPACE = ' ' + + + +def usage(code, msg=''): + if code: + fd = sys.stderr + else: + fd = sys.stdout + print >> fd, _(__doc__) + if msg: + print >> fd, msg + sys.exit(code) + + + +_listcache = {} + +def openlist(listname): + missing = [] + mlist = _listcache.get(listname, missing) + if mlist is missing: + try: + mlist = MailList.MailList(listname, lock=0) + except Errors.MMListError, e: + usage(1, _('No such list "%(listname)s"\n%(e)s')) + _listcache[listname] = mlist + return mlist + + + +def main(): + # Parse options + try: + opts, args = getopt.getopt( + sys.argv[1:], 'ad:l:p:qh', + ['all', 'domain=', 'listname=', 'password=', 'quiet', 'help']) + except getopt.error, msg: + usage(1, msg) + + # defaults + listnames = {} + domains = {} + password = None + quiet = 0 + + for opt, arg in opts: + if opt in ('-h', '--help'): + usage(0) + elif opt in ('-a', '--all'): + for name in Utils.list_names(): + listnames[name] = 1 + elif opt in ('-d', '--domain'): + domains[arg] = 1 + elif opt in ('-l', '--listname'): + listnames[arg] = 1 + elif opt in ('-p', '--password'): + password = arg + elif opt in ('-q', '--quiet'): + quiet = 1 + + if args: + strargs = SPACE.join(args) + usage(1, _('Bad arguments: %(strargs)s')) + + if password is not None: + if not password: + usage(1, _('Empty list passwords are not allowed')) + shapassword = sha.new(password).hexdigest() + + if domains: + for name in Utils.list_names(): + mlist = openlist(name) + if domains.has_key(mlist.host_name): + listnames[name] = 1 + + if not listnames: + print >> sys.stderr, _('Nothing to do.') + sys.exit(0) + + # Set the password on the lists + for listname in listnames.keys(): + mlist = openlist(listname) + mlist.Lock() + try: + if password is None: + randompw = Utils.MakeRandomPassword(8) + shapassword = sha.new(randompw).hexdigest() + notifypassword = randompw + else: + notifypassword = password + + mlist.password = shapassword + mlist.Save() + finally: + mlist.Unlock() + + # Notification + print _('New %(listname)s password: %(notifypassword)s') + if not quiet: + otrans = i18n.get_translation() + i18n.set_language(mlist.preferred_language) + try: + hostname = mlist.host_name + adminurl = mlist.GetScriptURL('admin', absolute=1) + msg = Message.UserNotification( + mlist.owner[:], Utils.get_site_email(), + _('Your new %(listname)s list password'), + _('''\ +The site administrator at %(hostname)s has changed the password for your +mailing list %(listname)s. It is now + + %(notifypassword)s + +Please be sure to use this for all future list administration. You may want +to log in now to your list and change the password to something more to your +liking. Visit your list admin page at + + %(adminurl)s +'''), + mlist.preferred_language) + finally: + i18n.set_translation(otrans) + msg.send(mlist) + + + +if __name__ == '__main__': + main() |