[Zope-Checkins] SVN: zdaemon/branches/2/ Fixed: When the ``user`` option was used to run as a particular

jim cvs-admin at zope.org
Thu Jun 7 19:56:08 UTC 2012


Log message for revision 126672:
  Fixed: When the ``user`` option was used to run as a particular
  user, supplemental groups weren't set to the user's supplemental
  groups.
  

Changed:
  U   zdaemon/branches/2/CHANGES.txt
  U   zdaemon/branches/2/README.txt
  U   zdaemon/branches/2/setup.py
  A   zdaemon/branches/2/src/zdaemon/tests/testuser.py
  U   zdaemon/branches/2/src/zdaemon/zdctl.py
  U   zdaemon/branches/2/src/zdaemon/zdoptions.py

-=-
Modified: zdaemon/branches/2/CHANGES.txt
===================================================================
--- zdaemon/branches/2/CHANGES.txt	2012-06-07 16:49:37 UTC (rev 126671)
+++ zdaemon/branches/2/CHANGES.txt	2012-06-07 19:56:03 UTC (rev 126672)
@@ -2,7 +2,13 @@
  Changelog
 ===========
 
+2.0.5 (2012-06-07)
+==================
 
+- Fixed: When the ``user`` option was used to run as a particular
+  user, supplemental groups weren't set to the user's supplemental
+  groups.
+
 2.0.4 (2009-04-20)
 ==================
 

Modified: zdaemon/branches/2/README.txt
===================================================================
--- zdaemon/branches/2/README.txt	2012-06-07 16:49:37 UTC (rev 126671)
+++ zdaemon/branches/2/README.txt	2012-06-07 19:56:03 UTC (rev 126672)
@@ -2,10 +2,7 @@
 ``zdaemon`` process controller for Unix-based systems
 *****************************************************
 
-`zdaemon` is a Python package which provides APIs for managing applications
-run as daemons.  Its principal use to date has been to manage the application
-server and storage server daemons for Zope / ZEO, although it is not limited
-to running Python-based applications (for instance, it has been used to
-manage the 'spread' daemon).
+``zdaemon`` is a Unix (Unix, Linux, Mac OS X) Python program that wraps
+commands to make them behave as proper daemons.
 
 .. contents::

Modified: zdaemon/branches/2/setup.py
===================================================================
--- zdaemon/branches/2/setup.py	2012-06-07 16:49:37 UTC (rev 126671)
+++ zdaemon/branches/2/setup.py	2012-06-07 19:56:03 UTC (rev 126672)
@@ -29,7 +29,7 @@
         entry_points=entry_points,
         include_package_data = True,
         install_requires=["ZConfig"],
-        extras_require=dict(test=['zope.testing']),
+        extras_require=dict(test=['zope.testing', 'mock']),
         )
 except ImportError:
     from distutils.core import setup
@@ -48,10 +48,10 @@
     long_description=(
         read('README.txt')
         + '\n' +
+        read('src/zdaemon/README.txt')
+        + '\n' +
         read('CHANGES.txt')
         + '\n' +
-        read('src/zdaemon/README.txt')
-        + '\n' +
         '========\n' +
         'Download\n' +
         '========\n'

Added: zdaemon/branches/2/src/zdaemon/tests/testuser.py
===================================================================
--- zdaemon/branches/2/src/zdaemon/tests/testuser.py	                        (rev 0)
+++ zdaemon/branches/2/src/zdaemon/tests/testuser.py	2012-06-07 19:56:03 UTC (rev 126672)
@@ -0,0 +1,111 @@
+##############################################################################
+#
+# Copyright (c) 2010 Zope Foundation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+
+# Test user and groups options
+
+from zope.testing import setupstack
+import doctest
+import mock
+import os
+import sys
+import unittest
+import zdaemon.zdctl
+
+def write(name, text):
+    with open(name, 'w') as f:
+        f.write(text)
+
+class O:
+    def __init__(self, **kw):
+        self.__dict__.update(kw)
+
+def test_user_fails_when_not_root():
+    """
+
+    >>> write('conf',
+    ... '''
+    ... <runner>
+    ...   program sleep 9
+    ...   user zope
+    ... </runner>
+    ... ''')
+
+    >>> with mock.patch('os.geteuid') as geteuid:
+    ...   with mock.patch('sys.stderr'):
+    ...     sys.stderr = sys.stdout
+    ...     geteuid.return_value = 42
+    ...     try:
+    ...         zdaemon.zdctl.main(['-C', 'conf', 'status'])
+    ...     except SystemExit:
+    ...         pass
+    ...     else:
+    ...         print 'oops'
+    ... # doctest: +ELLIPSIS
+    Error: only root can use -u USER to change users
+    For help, use ... -h
+
+    >>> import pwd
+    >>> pwd.getpwnam.assert_called_with('zope')
+
+    """
+
+def test_user_sets_supplemtary_groups():
+    """
+
+    >>> write('conf',
+    ... '''
+    ... <runner>
+    ...   program sleep 9
+    ...   user zope
+    ... </runner>
+    ... ''')
+
+    >>> import grp
+    >>> grp.getgrall.return_value = [
+    ...   O(gr_gid=8, gr_mem =['g', 'zope', ]),
+    ...   O(gr_gid=1, gr_mem =['a', 'x', ]),
+    ...   O(gr_gid=2, gr_mem =['b', 'x', 'zope']),
+    ...   O(gr_gid=5, gr_mem =['c', 'x', ]),
+    ...   O(gr_gid=4, gr_mem =['d', 'x', ]),
+    ...   O(gr_gid=3, gr_mem =['e', 'x', 'zope', ]),
+    ...   O(gr_gid=6, gr_mem =['f', ]),
+    ...   O(gr_gid=7, gr_mem =['h', ]),
+    ... ]
+
+    >>> zdaemon.zdctl.main(['-C', 'conf', 'status'])
+    daemon manager not running
+
+    >>> import pwd, os
+    >>> os.geteuid.assert_called_with()
+    >>> pwd.getpwnam.assert_called_with('zope')
+    >>> grp.getgrall.assert_called_with()
+    >>> os.setuid.assert_called_with(99)
+    >>> os.setgid.assert_called_with(5)
+    >>> os.setgroups.assert_called_with([2, 3, 8])
+
+    """
+
+def setUp(test):
+    setupstack.setUpDirectory(test)
+    getpwname = setupstack.context_manager(test, mock.patch('pwd.getpwnam'))
+    getpwname.return_value = O(pw_gid=5, pw_uid=99)
+    setupstack.context_manager(test, mock.patch('os.geteuid')).return_value = 0
+    setupstack.context_manager(test, mock.patch('grp.getgrall'))
+    setupstack.context_manager(test, mock.patch('os.setgroups'))
+    setupstack.context_manager(test, mock.patch('os.setuid'))
+    setupstack.context_manager(test, mock.patch('os.setgid'))
+
+def test_suite():
+    return doctest.DocTestSuite(setUp=setUp, tearDown=setupstack.tearDown)
+


Property changes on: zdaemon/branches/2/src/zdaemon/tests/testuser.py
___________________________________________________________________
Added: svn:keywords
   + Id
Added: svn:eol-style
   + native

Modified: zdaemon/branches/2/src/zdaemon/zdctl.py
===================================================================
--- zdaemon/branches/2/src/zdaemon/zdctl.py	2012-06-07 16:49:37 UTC (rev 126671)
+++ zdaemon/branches/2/src/zdaemon/zdctl.py	2012-06-07 19:56:03 UTC (rev 126672)
@@ -179,6 +179,7 @@
         if uid != 0 and uid != self.options.uid:
             self.options.usage("only root can use -u USER to change users")
         os.setgid(self.options.gid)
+        os.setgroups(self.options.groups)
         os.setuid(self.options.uid)
 
     def emptyline(self):

Modified: zdaemon/branches/2/src/zdaemon/zdoptions.py
===================================================================
--- zdaemon/branches/2/src/zdaemon/zdoptions.py	2012-06-07 16:49:37 UTC (rev 126671)
+++ zdaemon/branches/2/src/zdaemon/zdoptions.py	2012-06-07 19:56:03 UTC (rev 126672)
@@ -405,7 +405,7 @@
 
         # Additional checking of user option; set uid and gid
         if self.user is not None:
-            import pwd
+            import pwd, grp
             try:
                 uid = int(self.user)
             except ValueError:
@@ -413,15 +413,16 @@
                     pwrec = pwd.getpwnam(self.user)
                 except KeyError:
                     self.usage("username %r not found" % self.user)
-                uid = pwrec[2]
+                uid = pwrec.pw_uid
             else:
                 try:
                     pwrec = pwd.getpwuid(uid)
                 except KeyError:
                     self.usage("uid %r not found" % self.user)
-            gid = pwrec[3]
             self.uid = uid
-            self.gid = gid
+            self.gid = pwrec.pw_gid
+            self.groups = sorted(g.gr_gid for g in grp.getgrall()
+                                 if self.user in g.gr_mem)
 
 
 # ZConfig datatype



More information about the Zope-Checkins mailing list