[Zope-Checkins] CVS: Zope - z2.py:1.61.4.1
Casey Duncan
casey@zope.com
Wed, 27 Mar 2002 15:52:01 -0500
Update of /cvs-repository/Zope
In directory cvs.zope.org:/tmp/cvs-serv22094
Modified Files:
Tag: casey-death_to_index_html-branch
z2.py
Log Message:
Updating branch to head for testing
=== Zope/z2.py 1.61 => 1.61.4.1 ===
-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
+ The username to run ZServer as. You may want to run ZServer as
+ a dedicated user. This only works under Unix, and if ZServer
+ is started as root, and is required in that case.
-P [ipaddress:]number
@@ -154,6 +154,18 @@
Multiple -m options can be provided to run multiple servers.
+ --icp port
+
+ The ICP port. ICP can be used to distribute load between back-end
+ zope servers, if you are using an ICP-aware front-end proxy such
+ as Squid.
+
+ The port can be preeceeded by an ip address follwed by a colon
+ to specify an address to listen on. This allows different servers
+ to listen on different addresses.
+
+ Multiple --icp options can be provided to run multiple servers.
+
-l path
Path to the ZServer log file. If this is a relative path then the
@@ -221,7 +233,7 @@
sys.path.insert(5, '%s' % swhome)
-import os, sys, getopt, codecs
+import os, sys, getopt, codecs, string
# workaround to allow unicode encoding conversions in DTML
dummy = codecs.lookup('iso-8859-1')
@@ -254,8 +266,9 @@
DNS_IP=''
# User id to run ZServer as. Note that this only works under Unix, and if
-# ZServer is started by root.
-UID='nobody'
+# 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.
@@ -288,6 +301,9 @@
## Monitor configuration
MONITOR_PORT=0
+## ICP configuration
+ICP_PORT=0
+
# Module to be published, which must be Main or Zope
MODULE='Zope'
@@ -341,7 +357,9 @@
raise 'Invalid python version', sys.version.split()[0]
opts, args = getopt.getopt(sys.argv[1:],
- 'hz:Z:t:i:a:d:u:w:W:f:p:m:Sl:2DP:rF:L:XM:')
+ 'hz:Z:t:i:a:d:u:w:W:f:p:m:Sl:2DP:rF:L:XM:',
+ ['icp=',
+ ])
DEBUG=0
READ_ONLY=0
@@ -384,7 +402,7 @@
DEBUG=1
elif o=='-S': sys.ZMANAGED=1
elif o=='-X':
- MONITOR_PORT=HTTP_PORT=FTP_PORT=FCGI_PORT=0
+ MONITOR_PORT=HTTP_PORT=FTP_PORT=FCGI_PORT=ICP_PORT=0
PCGI_FILE=''
elif o=='-m':
MONITOR_PORT=server_info(MONITOR_PORT, v)
@@ -397,6 +415,8 @@
elif o=='-P':
HTTP_PORT=server_info(HTTP_PORT, v, 80)
FTP_PORT=server_info(FTP_PORT, v, 21)
+ elif o=='--icp':
+ ICP_PORT=server_info(ICP_PORT, v)
elif o=='-p':
if v=='-': v=''
@@ -479,6 +499,11 @@
os.chdir(CLIENT_HOME)
+def _warn_nobody():
+ zLOG.LOG("z2", zLOG.INFO, "Running Zope as 'nobody' can compromise " + \
+ "your Zope files; consider using a " + \
+ "dedicated user account for Zope")
+
try:
# Import logging support
import zLOG
@@ -666,47 +691,94 @@
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 = int(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 ICP_PORT:
+ if type(ICP_PORT) is type(0): ICP_PORT=((IP_ADDRESS, ICP_PORT),)
+ from ZServer.ICPServer import ICPServer
+ for address, port in ICP_PORT:
+ ICPServer(address,port)
-
- # if it hasn't failed at this point, create a .pid file.
if not READ_ONLY:
+ if os.path.exists(PID_FILE): os.unlink(PID_FILE)
pf = open(PID_FILE, 'w')
pid=str(os.getpid())
try: pid=str(os.getppid())+' '+pid
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, 'initgroups is required to safely setuid'
+ if UID == None:
+ raise SystemExit, 'A user was not specified to setuid ' + \
+ 'to; fix this to start as root'
+ import stat
+ client_home_stat = os.stat(CLIENT_HOME)
+ client_home_faults = []
+ if not (client_home_stat[stat.ST_MODE]&01000):
+ client_home_faults.append('does not have the sticky bit set')
+ if client_home_stat[stat.ST_UID] != 0:
+ client_home_faults.append('is not owned by root')
+ if len(client_home_faults) > 0:
+ raise SystemExit, CLIENT_HOME + ' ' + \
+ string.join(client_home_faults, ', ') + \
+ '; fix this to start 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
+ 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 AttributeError:
+ pass
+ except:
+ raise
+
+ # Check umask sanity.
+ if os.name == 'posix':
+ # umask is silly, blame POSIX. We have to set it to get its value.
+ current_umask = os.umask(0)
+ os.umask(current_umask)
+ if current_umask != 077:
+ current_umask = '%03o' % current_umask
+ zLOG.LOG("z2", zLOG.INFO, 'Your umask of ' + current_umask + \
+ ' may be too permissive; for the security of your ' + \
+ 'Zope data, it is recommended you use 077')
except:
# Log startup exception and tell zdaemon not to restart us.