summaryrefslogtreecommitdiff
path: root/bin
diff options
context:
space:
mode:
authorbwarsaw2006-09-24 16:49:18 +0000
committerbwarsaw2006-09-24 16:49:18 +0000
commit3da41d89a8c827383b2256b965fa1be8b179b9cd (patch)
tree04f49d3dab6e586be4769eab29d10618bf8378ea /bin
parentad16650e9806bcf864325626da59b93e64ce47ea (diff)
downloadmailman-3da41d89a8c827383b2256b965fa1be8b179b9cd.tar.gz
mailman-3da41d89a8c827383b2256b965fa1be8b179b9cd.tar.zst
mailman-3da41d89a8c827383b2256b965fa1be8b179b9cd.zip
Convert check_perms to mmshell symlink, configuration object, and optparse
usage.
Diffstat (limited to 'bin')
-rw-r--r--bin/Makefile.in10
-rwxr-xr-xbin/check_perms393
2 files changed, 5 insertions, 398 deletions
diff --git a/bin/Makefile.in b/bin/Makefile.in
index 37084d1f7..1251cd831 100644
--- a/bin/Makefile.in
+++ b/bin/Makefile.in
@@ -46,17 +46,17 @@ SHELL= /bin/sh
SCRIPTS= mmshell \
remove_members clone_member \
- sync_members check_db withlist check_perms \
+ sync_members check_db withlist \
config_list dumpdb cleanarch \
list_admins genaliases \
fix_url.py convert.py transcheck \
msgfmt.py discard \
reset_pw.py templ2pot.py po2templ.py
-LN_SCRIPTS= add_members arch change_pw find_member inject list_lists \
- list_members list_owners mailmanctl mmsitepass newlist \
- qrunner rmlist show_qfiles show_mm_cfg testall unshunt \
- update version
+LN_SCRIPTS= add_members arch change_pw check_perms find_member inject \
+ list_lists list_members list_owners mailmanctl mmsitepass \
+ newlist qrunner rmlist show_qfiles show_mm_cfg testall \
+ unshunt update version
BUILDDIR= ../build/bin
diff --git a/bin/check_perms b/bin/check_perms
deleted file mode 100755
index 7c807745d..000000000
--- a/bin/check_perms
+++ /dev/null
@@ -1,393 +0,0 @@
-#! @PYTHON@
-#
-# Copyright (C) 1998-2005 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 permissions for the Mailman installation.
-
-Usage: %(PROGRAM)s [-f] [-v] [-h]
-
-With no arguments, just check and report all the files that have bogus
-permissions or group ownership. With -f (and run as root), fix all the
-permission problems found. With -v be verbose.
-"""
-
-import os
-import sys
-import pwd
-import grp
-import errno
-import getopt
-from stat import *
-
-try:
- import paths
-except ImportError:
- print '''Could not import paths!
-
-This probably means that you are trying to run check_perms from the source
-directory. You must run this from the installation directory instead.
-'''
- raise
-from Mailman import mm_cfg
-from Mailman.mm_cfg import MAILMAN_USER, MAILMAN_GROUP
-from Mailman.i18n import _
-
-# Let KeyErrors percolate
-MAILMAN_GID = grp.getgrnam(MAILMAN_GROUP)[2]
-MAILMAN_UID = pwd.getpwnam(MAILMAN_USER)[2]
-
-PROGRAM = sys.argv[0]
-
-# Gotta check the archives/private/*/database/* files
-
-try:
- True, False
-except NameError:
- True = 1
- False = 0
-
-
-
-class State:
- FIX = False
- VERBOSE = False
- ERRORS = 0
-
-STATE = State()
-
-DIRPERMS = S_ISGID | S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH
-QFILEPERMS = S_ISGID | S_IRWXU | S_IRWXG
-PYFILEPERMS = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH
-ARTICLEFILEPERMS = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP
-
-
-
-def statmode(path):
- return os.stat(path)[ST_MODE]
-
-def statgidmode(path):
- stat = os.stat(path)
- return stat[ST_MODE], stat[ST_GID]
-
-seen = {}
-
-# libc's getgrgid re-opens /etc/group each time :(
-_gidcache = {}
-
-def getgrgid(gid):
- data = _gidcache.get(gid)
- if data is None:
- data = grp.getgrgid(gid)
- _gidcache[gid] = data
- return data
-
-
-
-def checkwalk(arg, dirname, names):
- # Short-circuit duplicates
- if seen.has_key(dirname):
- return
- seen[dirname] = True
- for name in names:
- path = os.path.join(dirname, name)
- if arg.VERBOSE:
- print _(' checking gid and mode for %(path)s')
- try:
- mode, gid = statgidmode(path)
- except OSError, e:
- if e.errno <> errno.ENOENT: raise
- continue
- if gid <> MAILMAN_GID:
- try:
- groupname = getgrgid(gid)[0]
- except KeyError:
- groupname = '<anon gid %d>' % gid
- arg.ERRORS += 1
- print _('%(path)s bad group (has: %(groupname)s, '
- 'expected %(MAILMAN_GROUP)s)'),
- if STATE.FIX:
- print _('(fixing)')
- os.chown(path, -1, MAILMAN_GID)
- else:
- print
- # all directories must be at least rwxrwsr-x. Don't check the private
- # archive directory or database directory themselves since these are
- # checked in checkarchives() and checkarchivedbs() below.
- private = mm_cfg.PRIVATE_ARCHIVE_FILE_DIR
- if path == private or (os.path.commonprefix((path, private)) == private
- and os.path.split(path)[1] == 'database'):
- continue
- # The directories under qfiles should have a more limited permission
- if os.path.commonprefix((path, mm_cfg.QUEUE_DIR)) == mm_cfg.QUEUE_DIR:
- targetperms = QFILEPERMS
- octperms = oct(targetperms)
- else:
- targetperms = DIRPERMS
- octperms = oct(targetperms)
- if S_ISDIR(mode) and (mode & targetperms) <> targetperms:
- arg.ERRORS += 1
- print _('directory permissions must be %(octperms)s: %(path)s'),
- if STATE.FIX:
- print _('(fixing)')
- os.chmod(path, mode | targetperms)
- else:
- print
- elif os.path.splitext(path)[1] in ('.py', '.pyc', '.pyo'):
- octperms = oct(PYFILEPERMS)
- if mode & PYFILEPERMS <> PYFILEPERMS:
- print _('source perms must be %(octperms)s: %(path)s'),
- arg.ERRORS += 1
- if STATE.FIX:
- print _('(fixing)')
- os.chmod(path, mode | PYFILEPERMS)
- else:
- print
- elif path.endswith('-article'):
- # Article files must be group writeable
- octperms = oct(ARTICLEFILEPERMS)
- if mode & ARTICLEFILEPERMS <> ARTICLEFILEPERMS:
- print _('article db files must be %(octperms)s: %(path)s'),
- arg.ERRORS += 1
- if STATE.FIX:
- print _('(fixing)')
- os.chmod(path, mode | ARTICLEFILEPERMS)
- else:
- print
-
-def checkall():
- # first check PREFIX
- if STATE.VERBOSE:
- prefix = mm_cfg.PREFIX
- print _('checking mode for %(prefix)s')
- dirs = {}
- for d in (mm_cfg.PREFIX, mm_cfg.EXEC_PREFIX, mm_cfg.VAR_PREFIX,
- mm_cfg.LOG_DIR):
- dirs[d] = True
- for d in dirs.keys():
- try:
- mode = statmode(d)
- except OSError, e:
- if e.errno <> errno.ENOENT: raise
- print _('WARNING: directory does not exist: %(d)s')
- continue
- if (mode & DIRPERMS) <> DIRPERMS:
- STATE.ERRORS += 1
- print _('directory must be at least 02775: %(d)s'),
- if STATE.FIX:
- print _('(fixing)')
- os.chmod(d, mode | DIRPERMS)
- else:
- print
- # check all subdirs
- os.path.walk(d, checkwalk, STATE)
-
-def checkarchives():
- private = mm_cfg.PRIVATE_ARCHIVE_FILE_DIR
- if STATE.VERBOSE:
- print _('checking perms on %(private)s')
- # private archives must not be other readable
- mode = statmode(private)
- if mode & S_IROTH:
- STATE.ERRORS += 1
- print _('%(private)s must not be other-readable'),
- if STATE.FIX:
- print _('(fixing)')
- os.chmod(private, mode & ~S_IROTH)
- else:
- print
- # In addition, on a multiuser system you may want to hide the private
- # archives so other users can't read them.
- if mode & S_IXOTH:
- print _("""\
-Warning: Private archive directory is other-executable (o+x).
- This could allow other users on your system to read private archives.
- If you're on a shared multiuser system, you should consult the
- installation manual on how to fix this.""")
-
-MBOXPERMS = S_IRGRP | S_IWGRP | S_IRUSR | S_IWUSR
-
-def checkmboxfile(mboxdir):
- absdir = os.path.join(mm_cfg.PRIVATE_ARCHIVE_FILE_DIR, mboxdir)
- for f in os.listdir(absdir):
- if not f.endswith('.mbox'):
- continue
- mboxfile = os.path.join(absdir, f)
- mode = statmode(mboxfile)
- if (mode & MBOXPERMS) <> MBOXPERMS:
- STATE.ERRORS = STATE.ERRORS + 1
- print _('mbox file must be at least 0660:'), mboxfile
- if STATE.FIX:
- print _('(fixing)')
- os.chmod(mboxfile, mode | MBOXPERMS)
- else:
- print
-
-def checkarchivedbs():
- # The archives/private/listname/database file must not be other readable
- # or executable otherwise those files will be accessible when the archives
- # are public. That may not be a horrible breach, but let's close this off
- # anyway.
- for dir in os.listdir(mm_cfg.PRIVATE_ARCHIVE_FILE_DIR):
- if dir.endswith('.mbox'):
- checkmboxfile(dir)
- dbdir = os.path.join(mm_cfg.PRIVATE_ARCHIVE_FILE_DIR, dir, 'database')
- try:
- mode = statmode(dbdir)
- except OSError, e:
- if e.errno not in (errno.ENOENT, errno.ENOTDIR): raise
- continue
- if mode & S_IRWXO:
- STATE.ERRORS += 1
- print _('%(dbdir)s "other" perms must be 000'),
- if STATE.FIX:
- print _('(fixing)')
- os.chmod(dbdir, mode & ~S_IRWXO)
- else:
- print
-
-def checkcgi():
- cgidir = os.path.join(mm_cfg.EXEC_PREFIX, 'cgi-bin')
- if STATE.VERBOSE:
- print _('checking cgi-bin permissions')
- exes = os.listdir(cgidir)
- for f in exes:
- path = os.path.join(cgidir, f)
- if STATE.VERBOSE:
- print _(' checking set-gid for %(path)s')
- mode = statmode(path)
- if mode & S_IXGRP and not mode & S_ISGID:
- STATE.ERRORS += 1
- print _('%(path)s must be set-gid'),
- if STATE.FIX:
- print _('(fixing)')
- os.chmod(path, mode | S_ISGID)
- else:
- print
-
-def checkmail():
- wrapper = os.path.join(mm_cfg.WRAPPER_DIR, 'mailman')
- if STATE.VERBOSE:
- print _('checking set-gid for %(wrapper)s')
- mode = statmode(wrapper)
- if not mode & S_ISGID:
- STATE.ERRORS += 1
- print _('%(wrapper)s must be set-gid'),
- if STATE.FIX:
- print _('(fixing)')
- os.chmod(wrapper, mode | S_ISGID)
-
-def checkadminpw():
- for pwfile in (os.path.join(mm_cfg.DATA_DIR, 'adm.pw'),
- os.path.join(mm_cfg.DATA_DIR, 'creator.pw')):
- targetmode = S_IFREG | S_IRUSR | S_IWUSR | S_IRGRP
- if STATE.VERBOSE:
- print _('checking permissions on %(pwfile)s')
- try:
- mode = statmode(pwfile)
- except OSError, e:
- if e.errno <> errno.ENOENT: raise
- return
- if mode <> targetmode:
- STATE.ERRORS += 1
- octmode = oct(mode)
- print _('%(pwfile)s permissions must be exactly 0640 '
- '(got %(octmode)s)'),
- if STATE.FIX:
- print _('(fixing)')
- os.chmod(pwfile, targetmode)
- else:
- print
-
-def checkmta():
- if mm_cfg.MTA:
- modname = 'Mailman.MTA.' + mm_cfg.MTA
- __import__(modname)
- try:
- sys.modules[modname].checkperms(STATE)
- except AttributeError:
- pass
-
-def checkdata():
- targetmode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP
- checkfiles = ('config.pck', 'config.pck.last',
- 'config.db', 'config.db.last',
- 'next-digest', 'next-digest-topics',
- 'request.db', 'request.db.tmp')
- if STATE.VERBOSE:
- print _('checking permissions on list data')
- # BAW: This needs to be converted to the Site module abstraction
- for dir in os.listdir(mm_cfg.LIST_DATA_DIR):
- for file in checkfiles:
- path = os.path.join(mm_cfg.LIST_DATA_DIR, dir, file)
- if STATE.VERBOSE:
- print _(' checking permissions on: %(path)s')
- try:
- mode = statmode(path)
- except OSError, e:
- if e.errno <> errno.ENOENT: raise
- continue
- if (mode & targetmode) <> targetmode:
- STATE.ERRORS += 1
- print _('file permissions must be at least 660: %(path)s'),
- if STATE.FIX:
- print _('(fixing)')
- os.chmod(path, mode | targetmode)
- else:
- print
-
-
-
-def usage(code, msg=''):
- if code:
- fd = sys.stderr
- else:
- fd = sys.stdout
- print >> fd, _(__doc__)
- if msg:
- print >> fd, msg
- sys.exit(code)
-
-
-if __name__ == '__main__':
- try:
- opts, args = getopt.getopt(sys.argv[1:], 'fvh',
- ['fix', 'verbose', 'help'])
- except getopt.error, msg:
- usage(1, msg)
-
- for opt, arg in opts:
- if opt in ('-h', '--help'):
- usage(0)
- elif opt in ('-f', '--fix'):
- STATE.FIX = True
- elif opt in ('-v', '--verbose'):
- STATE.VERBOSE = True
-
- checkall()
- checkarchives()
- checkarchivedbs()
- checkcgi()
- checkmail()
- checkdata()
- checkadminpw()
- checkmta()
-
- if not STATE.ERRORS:
- print _('No problems found')
- else:
- print _('Problems found:'), STATE.ERRORS
- print _('Re-run as %(MAILMAN_USER)s (or root) with -f flag to fix')