[Zope-Checkins] SVN: zdaemon/branches/2/ Fixed:

jim cvs-admin at zope.org
Fri Jun 8 17:19:48 UTC 2012


Log message for revision 126696:
  Fixed:
  
  The change in 2.0.6 to set a user's supplemental groups broke common
  configurations in which the effective user was set via ``su`` or
  ``sudo -u`` prior to invoking zdaemon.
  
  Now, zdaemon doesn't set groups or the effective user if the
  effective user is already set to the configured user.
  

Changed:
  U   zdaemon/branches/2/CHANGES.txt
  U   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-08 17:19:06 UTC (rev 126695)
+++ zdaemon/branches/2/CHANGES.txt	2012-06-08 17:19:44 UTC (rev 126696)
@@ -2,6 +2,18 @@
  Changelog
 ===========
 
+2.0.7 (2012-06-08)
+==================
+
+- Fixed:
+
+  The change in 2.0.6 to set a user's supplemental groups broke common
+  configurations in which the effective user was set via ``su`` or
+  ``sudo -u`` prior to invoking zdaemon.
+
+  Now, zdaemon doesn't set groups or the effective user if the
+  effective user is already set to the configured user.
+
 2.0.6 (2012-06-07)
 ==================
 

Modified: zdaemon/branches/2/src/zdaemon/tests/testuser.py
===================================================================
--- zdaemon/branches/2/src/zdaemon/tests/testuser.py	2012-06-08 17:19:06 UTC (rev 126695)
+++ zdaemon/branches/2/src/zdaemon/tests/testuser.py	2012-06-08 17:19:44 UTC (rev 126696)
@@ -96,10 +96,36 @@
 
     """
 
+def test_do_nothing_if_effective_user_is_configured_user():
+    """
+
+    >>> write('conf',
+    ... '''
+    ... <runner>
+    ...   program sleep 9
+    ...   user zope
+    ... </runner>
+    ... ''')
+
+    >>> with mock.patch('os.geteuid') as geteuid:
+    ...     geteuid.return_value = 99
+    ...     zdaemon.zdctl.main(['-C', 'conf', 'status'])
+    ...     os.geteuid.assert_called_with()
+    daemon manager not running
+
+    >>> import pwd, os, grp
+    >>> pwd.getpwnam.assert_called_with('zope')
+    >>> _ = grp.getgrall.assert_not_called()
+    >>> _ = os.setuid.assert_not_called()
+    >>> _ = os.setgid.assert_not_called()
+    >>> _ = os.setgroups.assert_not_called()
+
+    """
+
 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)
+    getpwname.return_value = O(pw_gid=5, pw_uid=99, pw_name='zope')
     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'))

Modified: zdaemon/branches/2/src/zdaemon/zdctl.py
===================================================================
--- zdaemon/branches/2/src/zdaemon/zdctl.py	2012-06-08 17:19:06 UTC (rev 126695)
+++ zdaemon/branches/2/src/zdaemon/zdctl.py	2012-06-08 17:19:44 UTC (rev 126696)
@@ -173,15 +173,43 @@
             os.chown(directory, self.options.uid, self.options.gid)
 
     def set_uid(self):
-        if self.options.uid is None:
+        user = self.options.user
+        if user is None:
             return
-        uid = os.geteuid()
-        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)
 
+        import pwd
+        try:
+            uid = int(user)
+        except ValueError:
+            try:
+                pwrec = pwd.getpwnam(user)
+            except KeyError:
+                self.options.usage("username %r not found" % user)
+            uid = pwrec.pw_uid
+        else:
+            try:
+                pwrec = pwd.getpwuid(uid)
+            except KeyError:
+                self.options.usage("uid %r not found" % user)
+
+        # See if we're already that user:
+        euid = os.geteuid()
+        if euid != 0:
+            if euid != uid:
+                self.options.usage("only root can use -u USER to change users")
+            return
+
+        # OK, we have to set user and groups:
+        os.setgid(pwrec.pw_gid)
+
+        import grp
+        user = pwrec.pw_name
+        os.setgroups(
+            sorted(g.gr_gid for g in grp.getgrall() # sort for tests
+                   if user in g.gr_mem)
+            )
+        os.setuid(uid)
+
     def emptyline(self):
         # We don't want a blank line to repeat the last command.
         # Showing status is a nice alternative.

Modified: zdaemon/branches/2/src/zdaemon/zdoptions.py
===================================================================
--- zdaemon/branches/2/src/zdaemon/zdoptions.py	2012-06-08 17:19:06 UTC (rev 126695)
+++ zdaemon/branches/2/src/zdaemon/zdoptions.py	2012-06-08 17:19:44 UTC (rev 126696)
@@ -400,31 +400,7 @@
                  existing_parent_directory)
         self.add("hang_around", "runner.hang_around", default=0)
 
-    def realize(self, *args, **kwds):
-        ZDOptions.realize(self, *args, **kwds)
 
-        # Additional checking of user option; set uid and gid
-        if self.user is not None:
-            import pwd, grp
-            try:
-                uid = int(self.user)
-            except ValueError:
-                try:
-                    pwrec = pwd.getpwnam(self.user)
-                except KeyError:
-                    self.usage("username %r not found" % self.user)
-                uid = pwrec.pw_uid
-            else:
-                try:
-                    pwrec = pwd.getpwuid(uid)
-                except KeyError:
-                    self.usage("uid %r not found" % self.user)
-            self.uid = uid
-            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
 
 def list_of_ints(arg):



More information about the Zope-Checkins mailing list