diff options
| author | bwarsaw | 2007-01-05 06:47:39 +0000 |
|---|---|---|
| committer | bwarsaw | 2007-01-05 06:47:39 +0000 |
| commit | 9af2533eb89e48683c049c5007737f7e94bbcdc1 (patch) | |
| tree | 54853dcccee453eae60916af4e612b3004cc736f /Mailman/bin | |
| parent | d7da90ebc8aeee180ba470c002f7e37ef7df1089 (diff) | |
| download | mailman-9af2533eb89e48683c049c5007737f7e94bbcdc1.tar.gz mailman-9af2533eb89e48683c049c5007737f7e94bbcdc1.tar.zst mailman-9af2533eb89e48683c049c5007737f7e94bbcdc1.zip | |
Clean up file permissions and umask settings. Now we set the umask to 007
during early initialization so that we're guaranteed to get the right value
regardless of the shell umask used to invoke the command line script. While
we're at it, we can remove almost all individual umask settings previously in
the code, and make file permissions consistently -rw-rw---- (IOW, files are no
longer other readable).
The only subsystem that wasn't changed was the archiver, because it uses its
own umask settings to ensure that private archives have the proper
permissions. Eventually we'll mess with this, but if it ain't broken...
Note that check_perms complains about directory permissions, but I think
check_perms can be fixed (or perhaps, even removed?!). If we decide to use
LMTPRunner and HTTPRunner exclusively then no outside process will be touching
our files potentially with the incorrect permissions, umask, owner, or group.
If we control all of our own touch points then I think we can lock out
'other'.
Another open question is whether Utils.set_global_password() can have its
umask setting removed. It locks permissions down so even the group can't
write to the site password file, but the default umask of 007 might be good
enough even for this file.
Utils.makedirs() now takes an optional mode argument, which defaults to 02775
for backward compatibility. First, the default mode can probably be changed
to 02770 (see above). Second, all code that was tweaking the umask in order
to do a platform compatible os.mkdir() has now been refactored to use
Utils.makedirs().
Another tricky thing was getting SQLite via SQLAlchemy to create its
data/mailman.db file with the proper permissions. From the comment in
dbcontext.py:
# XXX By design of SQLite, database file creation does not honor
# umask. See their ticket #1193:
# http://www.sqlite.org/cvstrac/tktview?tn=1193,31
More details in that file, but the work around is to essentially 'touch' the
database file if 'sqlite' is the scheme of the SQLAlchemy URL. This little
pre-touch sets the right umask honoring permission and won't hurt if the file
already exists. SQLite will happily keep the existing permissions, and in
fact that ticket referenced above recommends doing things this way.
In the Mailman.database.initialize(), create a global lock that prevents more
than one process from entering this init function at the same time. It's
probably not strictly necessary given that I believe all the operations in
dbcontext.connect() are multi-processing safe, but it also doesn't seem to
hurt and prevents race conditions regardless of the database's own
safeguards (or lack thereof).
Make sure nightly_gzip.py calls initialize().
Diffstat (limited to 'Mailman/bin')
| -rw-r--r-- | Mailman/bin/genaliases.py | 7 | ||||
| -rw-r--r-- | Mailman/bin/import.py | 6 | ||||
| -rw-r--r-- | Mailman/bin/mailmanctl.py | 15 | ||||
| -rw-r--r-- | Mailman/bin/newlist.py | 36 | ||||
| -rw-r--r-- | Mailman/bin/nightly_gzip.py | 16 | ||||
| -rw-r--r-- | Mailman/bin/update.py | 10 |
6 files changed, 29 insertions, 61 deletions
diff --git a/Mailman/bin/genaliases.py b/Mailman/bin/genaliases.py index 2796804df..4ce8160fd 100644 --- a/Mailman/bin/genaliases.py +++ b/Mailman/bin/genaliases.py @@ -1,6 +1,6 @@ #! @PYTHON@ # -# Copyright (C) 2001-2006 by the Free Software Foundation, Inc. +# Copyright (C) 2001-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 @@ -17,7 +17,6 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, # USA. -import os import sys import optparse @@ -72,9 +71,6 @@ def main(): for listname in Utils.list_names(): mlist = MailList.MailList(listname, lock=False) mlists.setdefault(mlist.host_name, []).append(mlist) - # Make sure the files are created rw-rw-xxx; it should be okay to be world - # readable. - omask = os.umask(002) try: MTA.clear() if not mlists: @@ -86,7 +82,6 @@ def main(): # Be verbose for only the first printed list quiet = True finally: - os.umask(omask) lock.unlock(unconditionally=True) diff --git a/Mailman/bin/import.py b/Mailman/bin/import.py index 68876def1..b643de389 100644 --- a/Mailman/bin/import.py +++ b/Mailman/bin/import.py @@ -48,12 +48,12 @@ def nodetext(node): return u'' -def nodegen(node, *entities): +def nodegen(node, *elements): for child in node.childNodes: if child.nodeType <> minidom.Node.ELEMENT_NODE: continue - if entities and child.tagName not in entities: - print _('Ignoring unexpected entity: $node.tagName') + if elements and child.tagName not in elements: + print _('Ignoring unexpected element: $node.tagName') else: yield child diff --git a/Mailman/bin/mailmanctl.py b/Mailman/bin/mailmanctl.py index 5c85799bc..db74214c0 100644 --- a/Mailman/bin/mailmanctl.py +++ b/Mailman/bin/mailmanctl.py @@ -1,4 +1,4 @@ -# Copyright (C) 2001-2006 by the Free Software Foundation, Inc. +# Copyright (C) 2001-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 @@ -261,7 +261,7 @@ def start_runner(qrname, slice, count): args.extend(['-C', opts.config]) os.execl(*args) # Should never get here - raise RuntimeError, 'os.execl() failed' + raise RuntimeError('os.execl() failed') def start_all_runners(): @@ -371,23 +371,18 @@ def main(): return # child lock._take_possession() - # First, save our pid in a file for "mailmanctl stop" rendezvous. We - # want the perms on the .pid file to be rw-rw---- - omask = os.umask(6) + # Save our pid in a file for "mailmanctl stop" rendezvous. + fp = open(config.PIDFILE, 'w') try: - fp = open(config.PIDFILE, 'w') print >> fp, os.getpid() - fp.close() finally: - os.umask(omask) + fp.close() # Create a new session and become the session leader, but since we # won't be opening any terminal devices, don't do the ultra-paranoid # suggestion of doing a second fork after the setsid() call. os.setsid() # Instead of cd'ing to root, cd to the Mailman installation home os.chdir(config.PREFIX) - # Set our file mode creation umask - os.umask(007) # I don't think we have any unneeded file descriptors. # # Now start all the qrunners. This returns a dictionary where the diff --git a/Mailman/bin/newlist.py b/Mailman/bin/newlist.py index edd7ad7bd..a127b25e1 100644 --- a/Mailman/bin/newlist.py +++ b/Mailman/bin/newlist.py @@ -1,4 +1,4 @@ -# Copyright (C) 1998-2006 by the Free Software Foundation, Inc. +# 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 @@ -15,7 +15,6 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, # USA. -import os import sha import sys import getpass @@ -148,27 +147,20 @@ def main(): mlist.preferred_language = opts.language try: pw = sha.new(listpasswd).hexdigest() - # Guarantee that all newly created files have the proper permission. - # proper group ownership should be assured by the autoconf script - # enforcing that all directories have the group sticky bit set. - oldmask = os.umask(002) try: - try: - mlist.Create(fqdn_listname, owner_mail, pw) - except Errors.BadListNameError, s: - parser.print_help() - print >> sys.stderr, _('Illegal list name: $s') - sys.exit(1) - except Errors.EmailAddressError, s: - parser.print_help() - print >> sys.stderr, _('Bad owner email address: $s') - sys.exit(1) - except Errors.MMListAlreadyExistsError: - parser.print_help() - print >> sys.stderr, _('List already exists: $listname') - sys.exit(1) - finally: - os.umask(oldmask) + mlist.Create(fqdn_listname, owner_mail, pw) + except Errors.BadListNameError, s: + parser.print_help() + print >> sys.stderr, _('Illegal list name: $s') + sys.exit(1) + except Errors.EmailAddressError, s: + parser.print_help() + print >> sys.stderr, _('Bad owner email address: $s') + sys.exit(1) + except Errors.MMListAlreadyExistsError: + parser.print_help() + print >> sys.stderr, _('List already exists: $listname') + sys.exit(1) mlist.Save() finally: mlist.Unlock() diff --git a/Mailman/bin/nightly_gzip.py b/Mailman/bin/nightly_gzip.py index f55b21493..4bd9271bc 100644 --- a/Mailman/bin/nightly_gzip.py +++ b/Mailman/bin/nightly_gzip.py @@ -1,6 +1,4 @@ -#! @PYTHON@ -# -# Copyright (C) 1998-2006 by the Free Software Foundation, Inc. +# 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 @@ -31,6 +29,7 @@ from Mailman import Utils from Mailman import Version from Mailman.configuration import config from Mailman.i18n import _ +from Mailman.initialize import initialize __i18n_templates__ = True @@ -77,7 +76,7 @@ def compress(txtfile, opts): def main(): opts, args, parser = parseargs() - config.load(opts.config) + initialize(opts.config) if config.ARCHIVE_TO_MBOX not in (1, 2) or config.GZIP_ARCHIVE_TXT_FILES: # We're only going to run the nightly archiver if messages are @@ -119,12 +118,3 @@ def main(): files.append(txtfile) for f in files: compress(f, opts) - - - -if __name__ == '__main__': - omask = os.umask(002) - try: - main() - finally: - os.umask(omask) diff --git a/Mailman/bin/update.py b/Mailman/bin/update.py index b6953e007..281f40420 100644 --- a/Mailman/bin/update.py +++ b/Mailman/bin/update.py @@ -1,4 +1,4 @@ -# Copyright (C) 1998-2006 by the Free Software Foundation, Inc. +# 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 @@ -255,9 +255,7 @@ def dolist(listname): o_html_dir = makeabs('public_html/archives/%s' % (listname)) # Make the mbox directory if it's not there. if not os.path.exists(mbox_dir): - ou = os.umask(0) - os.mkdir(mbox_dir, 02775) - os.umask(ou) + Utils.makedirs(mbox_dir) else: # This shouldn't happen, but hey, just in case if not os.path.isdir(mbox_dir): @@ -265,9 +263,7 @@ def dolist(listname): For some reason, $mbox_dir exists as a file. This won't work with b6, so I'm renaming it to ${mbox_dir}.tmp and proceeding.""") os.rename(mbox_dir, "%s.tmp" % (mbox_dir)) - ou = os.umask(0) - os.mkdir(mbox_dir, 02775) - os.umask(ou) + Utils.makedirs(mbox_dir) # Move any existing mboxes around, but watch out for both a public and a # private one existing if os.path.isfile(o_pri_mbox_file) and os.path.isfile(o_pub_mbox_file): |
