Browse Source

Merge branch 'trac213-incremental-noroot' into trac213-incremental

Conflicts:
	src/bin/bind10/bind10_src.py.in
	src/bin/bind10/tests/bind10_test.py.in
Michal 'vorner' Vaner 13 years ago
parent
commit
b513f0ab65

+ 3 - 0
src/bin/bind10/bind10_messages.mes

@@ -149,6 +149,9 @@ The boss module is sending a SIGKILL signal to the given process.
 % BIND10_SEND_SIGTERM sending SIGTERM to %1 (PID %2)
 The boss module is sending a SIGTERM signal to the given process.
 
+% BIND10_SETUID setting UID to %1
+The boss switches the user it runs as to the given UID.
+
 % BIND10_SHUTDOWN stopping the server
 The boss process received a command or signal telling it to shut down.
 It will send a shutdown command to each process. The processes that do

+ 6 - 1
src/bin/bind10/bob.spec

@@ -8,9 +8,14 @@
         "item_type": "named_set",
         "item_optional": false,
         "item_default": {
+          "b10-auth": { "special": "auth", "kind": "needed", "priority": 10 },
+          "setuid": {
+            "special": "setuid",
+            "priority": 5,
+            "kind": "dispensable"
+          },
           "b10-xfrin": { "address": "Xfrin", "kind": "dispensable" },
           "b10-xfrout": { "address": "Xfrout", "kind": "dispensable" },
-          "b10-auth": { "special": "auth", "kind": "needed" },
           "b10-zonemgr": { "address": "Zonemgr", "kind": "dispensable" },
           "b10-stats": { "address": "Stats", "kind": "dispensable" },
           "b10-stats-httpd": {

+ 0 - 3
src/bin/bind10/tests/bind10_test.py.in

@@ -241,9 +241,6 @@ class MockBob(BoB):
         procinfo.pid = 1
         return procinfo
 
-    def stop_creator(self, kill=False):
-        self.creator = False
-
     def _read_bind10_config(self):
         # Configuration options are set directly
         pass

+ 33 - 1
src/lib/python/isc/bind10/special_component.py

@@ -17,6 +17,11 @@ from isc.bind10.component import Component, BaseComponent
 import isc.bind10.sockcreator
 from bind10_config import LIBEXECDIR
 import os
+import posix
+import isc.log
+from isc.log_messages.bind10_messages import *
+
+logger = isc.log.Logger("boss")
 
 class SockCreator(BaseComponent):
     """
@@ -108,6 +113,31 @@ class XfrIn(Component):
         Component.__init__(self, process, boss, kind, 'Xfrin', None,
                            boss.start_xfrin)
 
+class SetUID(BaseComponent):
+    """
+    This is a pseudo-component which drops root privileges when started
+    and sets the uid stored in boss.
+
+    This component does nothing when stopped.
+    """
+    def __init__(self, process, boss, kind, address=None, params=None):
+        BaseComponent.__init__(self, boss, kind)
+        self.uid = boss.uid
+
+    def _start_internal(self):
+        if self.uid is not None:
+            logger.info(BIND10_SETUID, self.uid)
+            posix.setuid(self.uid)
+
+    def _stop_internal(self): pass
+    def kill(self, forcefull=False): pass
+
+    def name(self):
+        return "Set UID"
+
+    def pid(self):
+        return None
+
 def get_specials():
     """
     List of specially started components. Each one should be the class than can
@@ -123,5 +153,7 @@ def get_specials():
         'resolver': Resolver,
         'cmdctl': CmdCtl,
         # FIXME: Temporary workaround before #1292 is done
-        'xfrin': XfrIn
+        'xfrin': XfrIn,
+        # TODO: Remove when not needed, workaround before sockcreator works
+        'setuid': SetUID
     }

+ 31 - 2
src/lib/python/isc/bind10/tests/component_test.py

@@ -106,6 +106,9 @@ class ComponentTests(BossUtils, unittest.TestCase):
         self.__registered_processes = {}
         self.__stop_process_params = None
         self.__start_simple_params = None
+        # Pretending to be boss
+        self.uid = None
+        self.__uid_set = None
 
     def __start(self):
         """
@@ -418,7 +421,7 @@ class ComponentTests(BossUtils, unittest.TestCase):
     def test_pid_not_running(self):
         """
         Test that a componet that is not yet started doesn't have a PID.
-        But it won't failed if asked for and returns None.
+        But it won't fail if asked for and return None.
         """
         for component_type in [Component,
                                isc.bind10.special_component.SockCreator,
@@ -427,7 +430,8 @@ class ComponentTests(BossUtils, unittest.TestCase):
                                isc.bind10.special_component.Auth,
                                isc.bind10.special_component.Resolver,
                                isc.bind10.special_component.CmdCtl,
-                               isc.bind10.special_component.XfrIn]:
+                               isc.bind10.special_component.XfrIn,
+                               isc.bind10.special_component.SetUID]:
             component = component_type('none', self, 'needed')
             self.assertIsNone(component.pid())
 
@@ -527,6 +531,31 @@ class ComponentTests(BossUtils, unittest.TestCase):
         self.assertTrue(process.killed)
         self.assertFalse(process.terminated)
 
+    def setuid(self, uid):
+        self.__uid_set = uid
+
+    def test_setuid(self):
+        """
+        Some tests around the SetUID pseudo-component.
+        """
+        component = isc.bind10.special_component.SetUID(None, self, 'needed',
+                                                        None)
+        orig_setuid = isc.bind10.special_component.posix.setuid
+        isc.bind10.special_component.posix.setuid = self.setuid
+        component.start()
+        # No uid set in boss, nothing called.
+        self.assertIsNone(self.__uid_set)
+        # Doesn't do anything, but doesn't crash
+        component.stop()
+        component.kill()
+        component.kill(True)
+        self.uid = 42
+        component = isc.bind10.special_component.SetUID(None, self, 'needed',
+                                                        None)
+        component.start()
+        # This time, it get's called
+        self.assertEqual(42, self.__uid_set)
+
 class TestComponent(BaseComponent):
     """
     A test component. It does not start any processes or so, it just logs