diff -Ncr Zope-2.4.4b1-src.orig/lib/Components/initgroups/initgroups.c Zope-2.4.4b1-src/lib/Components/initgroups/initgroups.c *** Zope-2.4.4b1-src.orig/lib/Components/initgroups/initgroups.c Wed Dec 31 19:00:00 1969 --- Zope-2.4.4b1-src/lib/Components/initgroups/initgroups.c Tue Jan 29 09:53:21 2002 *************** *** 0 **** --- 1,62 ---- + /* + * Copyright (c) 2002 Matt Behrens + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + */ + + #include "Python.h" + + #include + #include + #include + + static PyObject * + initgroups_initgroups(self, args) + PyObject *self; + PyObject *args; + { + char *username; + gid_t gid; + + if(!PyArg_ParseTuple(args, "sl", &username, &gid)) + return NULL; + + if(initgroups(username, gid) == -1) + return PyErr_SetFromErrno(PyExc_OSError); + + Py_INCREF(Py_None); + return Py_None; + } + + static PyMethodDef InitgroupsMethods[] = { + {"initgroups", initgroups_initgroups, METH_VARARGS}, + {NULL, NULL} + }; + + void + initinitgroups() + { + (void)Py_InitModule("initgroups", InitgroupsMethods); + } + diff -Ncr Zope-2.4.4b1-src.orig/lib/python/Setup20 Zope-2.4.4b1-src/lib/python/Setup20 *** Zope-2.4.4b1-src.orig/lib/python/Setup20 Fri Feb 16 14:54:25 2001 --- Zope-2.4.4b1-src/lib/python/Setup20 Tue Jan 29 09:53:21 2002 *************** *** 18,20 **** --- 18,22 ---- zlib ../Components/zlib/zlib.c -I../Components/zlib ../Components/zlib/adler32.c ../Components/zlib/compress.c ../Components/zlib/crc32.c ../Components/zlib/gzio.c ../Components/zlib/uncompr.c ../Components/zlib/deflate.c ../Components/zlib/trees.c ../Components/zlib/zutil.c ../Components/zlib/inflate.c ../Components/zlib/infblock.c ../Components/zlib/inftrees.c ../Components/zlib/infcodes.c ../Components/zlib/infutil.c ../Components/zlib/inffast.c + + initgroups ../Components/initgroups/initgroups.c diff -Ncr Zope-2.4.4b1-src.orig/z2.py Zope-2.4.4b1-src/z2.py *** Zope-2.4.4b1-src.orig/z2.py Mon Jun 18 09:49:01 2001 --- Zope-2.4.4b1-src/z2.py Tue Jan 29 09:53:21 2002 *************** *** 144,152 **** -u username or uid number ! The username to run ZServer as. You may want to run ZServer as 'nobody' ! or some other user with limited resouces. The only works under Unix, and ! if ZServer is started by root. The default is: %(UID)s -P [ipaddress:]number --- 144,152 ---- -u username or uid number ! The username to run ZServer as. You may want to run ZServer as ! a dedicated user. The only works under Unix, and if ZServer is ! started by root. The default is: %(UID)s -P [ipaddress:]number *************** *** 322,329 **** DNS_IP='' # User id to run ZServer as. Note that this only works under Unix, and if ! # ZServer is started by root. ! UID='nobody' # Log file location. If this is a relative path, then it is joined the # the 'var' directory. --- 322,330 ---- DNS_IP='' # User id to run ZServer as. Note that this only works under Unix, and if ! # ZServer is started by root. This no longer defaults to 'nobody' since ! # that can lead to a Zope file compromise. ! UID=None # Log file location. If this is a relative path, then it is joined the # the 'var' directory. *************** *** 545,550 **** --- 546,556 ---- zdaemon.run(sys.argv, os.path.join(CLIENT_HOME, Zpid)) + def _warn_nobody(): + zLOG.LOG("z2", zLOG.WARNING, 'Running Zope as the UNIX nobody user ' + + 'can compromise your Zope setup. It is recommended that ' + + 'you use a dedicated user for this purpose.') + try: # Import logging support import zLOG *************** *** 719,758 **** hostname=address, port=port) - # Try to set uid to "-u" -provided uid. - # Try to set gid to "-u" user's primary group. - # This will only work if this script is run by root. - try: - import pwd - try: - try: UID = string.atoi(UID) - except: pass - gid = None - if type(UID) == type(""): - uid = pwd.getpwnam(UID)[2] - gid = pwd.getpwnam(UID)[3] - elif type(UID) == type(1): - uid = pwd.getpwuid(UID)[2] - gid = pwd.getpwuid(UID)[3] - else: - raise KeyError - try: - if gid is not None: - try: - os.setgid(gid) - except OSError: - pass - os.setuid(uid) - except OSError: - pass - except KeyError: - zLOG.LOG("z2", zLOG.ERROR, ("can't find UID %s" % UID)) - except: - pass - - - - # if it hasn't failed at this point, create a .pid file. if not READ_ONLY: pf = open(PID_FILE, 'w') pid=str(os.getpid()) --- 725,730 ---- *************** *** 760,765 **** --- 732,814 ---- except: pass pf.write(pid) pf.close() + + # Warn if we were started as nobody. + try: + import pwd + if os.getuid(): + if pwd.getpwuid(os.getuid())[0] == 'nobody': + _warn_nobody() + except: + pass + + # Drop root privileges if we have them, and do some sanity checking + # to make sure we're not starting with an obviously insecure setup. + try: + if os.getuid() == 0: + try: + import initgroups + except: + raise SystemExit, 'Cannot safely setuid without initgroups' + if UID == None: + raise SystemExit, 'You must specify a user with the -u ' + \ + 'flag if you wish to start Zope as ' + \ + 'root. It is not recommended that ' + \ + 'you start Zope as root unless you ' + \ + 'need ZServer to listen on low ports ' + \ + 'such at 80.' + import stat + if not (os.stat(os.path.join(CLIENT_HOME))[stat.ST_MODE]&01000): + raise SystemExit, CLIENT_HOME + ' does not have the ' + \ + '"sticky bit" set. For security ' + \ + 'reasons, you must set this if you ' + \ + 'are starting Zope as root.' + try: + try: UID = string.atoi(UID) + except: pass + gid = None + if type(UID) == type(""): + uid = pwd.getpwnam(UID)[2] + gid = pwd.getpwnam(UID)[3] + elif type(UID) == type(1): + uid = pwd.getpwuid(UID)[2] + gid = pwd.getpwuid(UID)[3] + UID = pwd.getpwuid(UID)[0] + else: + raise KeyError + zLOG.LOG("z2", zLOG.INFO, "switching user ID to %s" % UID) + if UID == 'nobody': + _warn_nobody() + try: + initgroups.initgroups(UID, gid) + if gid is not None: + try: + os.setgid(gid) + except OSError: + pass + os.setuid(uid) + except OSError: + pass + except KeyError: + zLOG.LOG("z2", zLOG.ERROR, ("can't find UID %s" % UID)) + except SystemExit: + raise + except: + pass + + # umask() is a silly call (blame POSIX). We have to set something in + # order to get its value. + try: + current_umask = os.umask(0) + os.umask(current_umask) + if current_umask != 077: + current_umask = '%03o' % current_umask + zLOG.LOG("z2", zLOG.WARNING, 'Your current umask setting of ' + + current_umask + ' may be too permissive. For the ' + + 'security of your Zope data, it is recommended you ' + + 'use a umask of 077.') + except: + pass except: # Log startup exception and tell zdaemon not to restart us.