mirror of
https://gitlab.isc.org/isc-projects/kea
synced 2025-09-01 14:35:29 +00:00
[master] Merge branch 'trac711'
This commit is contained in:
@@ -308,13 +308,6 @@ During the startup process, a number of messages are exchanged between the
|
|||||||
Boss process and the processes it starts. This error is output when a
|
Boss process and the processes it starts. This error is output when a
|
||||||
message received by the Boss process is not recognised.
|
message received by the Boss process is not recognised.
|
||||||
|
|
||||||
% BIND10_START_AS_NON_ROOT_RESOLVER starting b10-resolver as a user, not root. This might fail.
|
|
||||||
The resolver is being started or restarted without root privileges.
|
|
||||||
If the module needs these privileges, it may have problems starting.
|
|
||||||
Note that this issue should be resolved by the pending 'socket-creator'
|
|
||||||
process; once that has been implemented, modules should not need root
|
|
||||||
privileges anymore. See tickets #800 and #801 for more information.
|
|
||||||
|
|
||||||
% BIND10_STOP_PROCESS asking %1 to shut down
|
% BIND10_STOP_PROCESS asking %1 to shut down
|
||||||
The boss module is sending a shutdown command to the given module over
|
The boss module is sending a shutdown command to the given module over
|
||||||
the message channel.
|
the message channel.
|
||||||
|
@@ -103,8 +103,31 @@ VERSION = "bind10 20110223 (BIND 10 @PACKAGE_VERSION@)"
|
|||||||
# This is for boot_time of Boss
|
# This is for boot_time of Boss
|
||||||
_BASETIME = time.gmtime()
|
_BASETIME = time.gmtime()
|
||||||
|
|
||||||
|
# Detailed error message commonly used on startup failure, possibly due to
|
||||||
|
# permission issue regarding log lock file. We dump verbose message because
|
||||||
|
# it may not be clear exactly what to do if it simply says
|
||||||
|
# "failed to open <filename>: permission denied"
|
||||||
|
NOTE_ON_LOCK_FILE = """\
|
||||||
|
TIP: if this is about permission error for a lock file, check if the directory
|
||||||
|
of the file is writable for the user of the bind10 process; often you need
|
||||||
|
to start bind10 as a super user. Also, if you specify the -u option to
|
||||||
|
change the user and group, the directory must be writable for the group,
|
||||||
|
and the created lock file must be writable for that user. Finally, make sure
|
||||||
|
the lock file is not left in the directly before restarting.
|
||||||
|
"""
|
||||||
|
|
||||||
class ProcessInfoError(Exception): pass
|
class ProcessInfoError(Exception): pass
|
||||||
|
|
||||||
|
class ChangeUserError(Exception):
|
||||||
|
'''Exception raised when setuid/setgid fails.
|
||||||
|
|
||||||
|
When raised, it's expected to be propagated via underlying component
|
||||||
|
management modules to the top level so that it will help provide useful
|
||||||
|
fatal error message.
|
||||||
|
|
||||||
|
'''
|
||||||
|
pass
|
||||||
|
|
||||||
class ProcessInfo:
|
class ProcessInfo:
|
||||||
"""Information about a process"""
|
"""Information about a process"""
|
||||||
|
|
||||||
@@ -206,8 +229,8 @@ class BoB:
|
|||||||
# restart. Components manage their own restart schedule now
|
# restart. Components manage their own restart schedule now
|
||||||
self.components_to_restart = []
|
self.components_to_restart = []
|
||||||
self.runnable = False
|
self.runnable = False
|
||||||
self.uid = setuid
|
self.__uid = setuid
|
||||||
self.gid = setgid
|
self.__gid = setgid
|
||||||
self.username = username
|
self.username = username
|
||||||
self.verbose = verbose
|
self.verbose = verbose
|
||||||
self.nokill = nokill
|
self.nokill = nokill
|
||||||
@@ -269,6 +292,31 @@ class BoB:
|
|||||||
# Update the configuration
|
# Update the configuration
|
||||||
self._component_configurator.reconfigure(comps)
|
self._component_configurator.reconfigure(comps)
|
||||||
|
|
||||||
|
def change_user(self):
|
||||||
|
'''Change the user and group to those specified on construction.
|
||||||
|
|
||||||
|
This method is expected to be called by a component on initial
|
||||||
|
startup when the system is ready to switch the user and group
|
||||||
|
(i.e., once all components that need the privilege of the original
|
||||||
|
user have started).
|
||||||
|
'''
|
||||||
|
try:
|
||||||
|
if self.__gid is not None:
|
||||||
|
logger.info(BIND10_SETGID, self.__gid)
|
||||||
|
posix.setgid(self.__gid)
|
||||||
|
except Exception as ex:
|
||||||
|
raise ChangeUserError('failed to change group: ' + str(ex))
|
||||||
|
|
||||||
|
try:
|
||||||
|
if self.__uid is not None:
|
||||||
|
posix.setuid(self.__uid)
|
||||||
|
# We use one-shot logger after setuid here. This will
|
||||||
|
# detect any permission issue regarding logging due to the
|
||||||
|
# result of setuid at the earliest opportunity.
|
||||||
|
isc.log.Logger("boss").info(BIND10_SETUID, self.__uid)
|
||||||
|
except Exception as ex:
|
||||||
|
raise ChangeUserError('failed to change user: ' + str(ex))
|
||||||
|
|
||||||
def config_handler(self, new_config):
|
def config_handler(self, new_config):
|
||||||
# If this is initial update, don't do anything now, leave it to startup
|
# If this is initial update, don't do anything now, leave it to startup
|
||||||
if not self.runnable:
|
if not self.runnable:
|
||||||
@@ -578,8 +626,6 @@ class BoB:
|
|||||||
are pure speculation. As with the auth daemon, they should be
|
are pure speculation. As with the auth daemon, they should be
|
||||||
read from the configuration database.
|
read from the configuration database.
|
||||||
"""
|
"""
|
||||||
if self.uid is not None and self.__started:
|
|
||||||
logger.warn(BIND10_START_AS_NON_ROOT_RESOLVER)
|
|
||||||
self.curproc = "b10-resolver"
|
self.curproc = "b10-resolver"
|
||||||
# XXX: this must be read from the configuration manager in the future
|
# XXX: this must be read from the configuration manager in the future
|
||||||
resargs = ['b10-resolver']
|
resargs = ['b10-resolver']
|
||||||
@@ -646,6 +692,9 @@ class BoB:
|
|||||||
try:
|
try:
|
||||||
self.c_channel_env = c_channel_env
|
self.c_channel_env = c_channel_env
|
||||||
self.start_all_components()
|
self.start_all_components()
|
||||||
|
except ChangeUserError as e:
|
||||||
|
self.kill_started_components()
|
||||||
|
return str(e) + '; ' + NOTE_ON_LOCK_FILE.replace('\n', ' ')
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
self.kill_started_components()
|
self.kill_started_components()
|
||||||
return "Unable to start " + self.curproc + ": " + str(e)
|
return "Unable to start " + self.curproc + ": " + str(e)
|
||||||
@@ -1155,7 +1204,19 @@ def remove_lock_files():
|
|||||||
for f in lockfiles:
|
for f in lockfiles:
|
||||||
fname = lpath + '/' + f
|
fname = lpath + '/' + f
|
||||||
if os.path.isfile(fname):
|
if os.path.isfile(fname):
|
||||||
os.unlink(fname)
|
try:
|
||||||
|
os.unlink(fname)
|
||||||
|
except OSError as e:
|
||||||
|
# We catch and ignore permission related error on unlink.
|
||||||
|
# This can happen if bind10 started with -u, created a lock
|
||||||
|
# file as a privileged user, but the directory is not writable
|
||||||
|
# for the changed user. This setup will cause immediate
|
||||||
|
# start failure, and we leave verbose error message including
|
||||||
|
# the leftover lock file, so it should be acceptable to ignore
|
||||||
|
# it (note that it doesn't make sense to log this event at
|
||||||
|
# this poitn)
|
||||||
|
if e.errno != errno.EPERM and e.errno != errno.EACCES:
|
||||||
|
raise
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
@@ -1173,13 +1234,7 @@ def main():
|
|||||||
except RuntimeError as e:
|
except RuntimeError as e:
|
||||||
sys.stderr.write('ERROR: failed to write the initial log: %s\n' %
|
sys.stderr.write('ERROR: failed to write the initial log: %s\n' %
|
||||||
str(e))
|
str(e))
|
||||||
sys.stderr.write("""\
|
sys.stderr.write(NOTE_ON_LOCK_FILE)
|
||||||
TIP: if this is about permission error for a lock file, check if the directory
|
|
||||||
of the file is writable for the user of the bind10 process; often you need
|
|
||||||
to start bind10 as a super user. Also, if you specify the -u option to
|
|
||||||
change the user and group, the directory must be writable for the group,
|
|
||||||
and the created lock file must be writable for that user.
|
|
||||||
""")
|
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
# Check user ID.
|
# Check user ID.
|
||||||
|
@@ -341,6 +341,18 @@ class TestCacheCommands(unittest.TestCase):
|
|||||||
|
|
||||||
|
|
||||||
class TestBoB(unittest.TestCase):
|
class TestBoB(unittest.TestCase):
|
||||||
|
def setUp(self):
|
||||||
|
# Save original values that may be tweaked in some tests
|
||||||
|
self.__orig_setgid = bind10_src.posix.setgid
|
||||||
|
self.__orig_setuid = bind10_src.posix.setuid
|
||||||
|
self.__orig_logger_class = isc.log.Logger
|
||||||
|
|
||||||
|
def tearDown(self):
|
||||||
|
# Restore original values saved in setUp()
|
||||||
|
bind10_src.posix.setgid = self.__orig_setgid
|
||||||
|
bind10_src.posix.setuid = self.__orig_setuid
|
||||||
|
isc.log.Logger = self.__orig_logger_class
|
||||||
|
|
||||||
def test_init(self):
|
def test_init(self):
|
||||||
bob = BoB()
|
bob = BoB()
|
||||||
self.assertEqual(bob.verbose, False)
|
self.assertEqual(bob.verbose, False)
|
||||||
@@ -349,10 +361,56 @@ class TestBoB(unittest.TestCase):
|
|||||||
self.assertEqual(bob.ccs, None)
|
self.assertEqual(bob.ccs, None)
|
||||||
self.assertEqual(bob.components, {})
|
self.assertEqual(bob.components, {})
|
||||||
self.assertEqual(bob.runnable, False)
|
self.assertEqual(bob.runnable, False)
|
||||||
self.assertEqual(bob.uid, None)
|
|
||||||
self.assertEqual(bob.username, None)
|
self.assertEqual(bob.username, None)
|
||||||
self.assertIsNone(bob._socket_cache)
|
self.assertIsNone(bob._socket_cache)
|
||||||
|
|
||||||
|
def __setgid(self, gid):
|
||||||
|
self.__gid_set = gid
|
||||||
|
|
||||||
|
def __setuid(self, uid):
|
||||||
|
self.__uid_set = uid
|
||||||
|
|
||||||
|
def test_change_user(self):
|
||||||
|
bind10_src.posix.setgid = self.__setgid
|
||||||
|
bind10_src.posix.setuid = self.__setuid
|
||||||
|
|
||||||
|
self.__gid_set = None
|
||||||
|
self.__uid_set = None
|
||||||
|
bob = BoB()
|
||||||
|
bob.change_user()
|
||||||
|
# No gid/uid set in boss, nothing called.
|
||||||
|
self.assertIsNone(self.__gid_set)
|
||||||
|
self.assertIsNone(self.__uid_set)
|
||||||
|
|
||||||
|
BoB(setuid=42, setgid=4200).change_user()
|
||||||
|
# This time, it get's called
|
||||||
|
self.assertEqual(4200, self.__gid_set)
|
||||||
|
self.assertEqual(42, self.__uid_set)
|
||||||
|
|
||||||
|
def raising_set_xid(gid_or_uid):
|
||||||
|
ex = OSError()
|
||||||
|
ex.errno, ex.strerror = errno.EPERM, 'Operation not permitted'
|
||||||
|
raise ex
|
||||||
|
|
||||||
|
# Let setgid raise an exception
|
||||||
|
bind10_src.posix.setgid = raising_set_xid
|
||||||
|
bind10_src.posix.setuid = self.__setuid
|
||||||
|
self.assertRaises(bind10_src.ChangeUserError,
|
||||||
|
BoB(setuid=42, setgid=4200).change_user)
|
||||||
|
|
||||||
|
# Let setuid raise an exception
|
||||||
|
bind10_src.posix.setgid = self.__setgid
|
||||||
|
bind10_src.posix.setuid = raising_set_xid
|
||||||
|
self.assertRaises(bind10_src.ChangeUserError,
|
||||||
|
BoB(setuid=42, setgid=4200).change_user)
|
||||||
|
|
||||||
|
# Let initial log output after setuid raise an exception
|
||||||
|
bind10_src.posix.setgid = self.__setgid
|
||||||
|
bind10_src.posix.setuid = self.__setuid
|
||||||
|
isc.log.Logger = raising_set_xid
|
||||||
|
self.assertRaises(bind10_src.ChangeUserError,
|
||||||
|
BoB(setuid=42, setgid=4200).change_user)
|
||||||
|
|
||||||
def test_set_creator(self):
|
def test_set_creator(self):
|
||||||
"""
|
"""
|
||||||
Test the call to set_creator. First time, the cache is created
|
Test the call to set_creator. First time, the cache is created
|
||||||
@@ -423,7 +481,6 @@ class TestBoB(unittest.TestCase):
|
|||||||
self.assertEqual(bob.ccs, None)
|
self.assertEqual(bob.ccs, None)
|
||||||
self.assertEqual(bob.components, {})
|
self.assertEqual(bob.components, {})
|
||||||
self.assertEqual(bob.runnable, False)
|
self.assertEqual(bob.runnable, False)
|
||||||
self.assertEqual(bob.uid, None)
|
|
||||||
self.assertEqual(bob.username, None)
|
self.assertEqual(bob.username, None)
|
||||||
|
|
||||||
def test_command_handler(self):
|
def test_command_handler(self):
|
||||||
@@ -2021,8 +2078,10 @@ class TestBossComponents(unittest.TestCase):
|
|||||||
|
|
||||||
def start_all_components(self):
|
def start_all_components(self):
|
||||||
self.started = True
|
self.started = True
|
||||||
if self.throw:
|
if self.throw is True:
|
||||||
raise Exception('Assume starting components has failed.')
|
raise Exception('Assume starting components has failed.')
|
||||||
|
elif self.throw:
|
||||||
|
raise self.throw
|
||||||
|
|
||||||
def kill_started_components(self):
|
def kill_started_components(self):
|
||||||
self.killed = True
|
self.killed = True
|
||||||
@@ -2067,6 +2126,12 @@ class TestBossComponents(unittest.TestCase):
|
|||||||
r = bob.startup()
|
r = bob.startup()
|
||||||
self.assertEqual({'BIND10_MSGQ_SOCKET_FILE': 'foo'}, bob.c_channel_env)
|
self.assertEqual({'BIND10_MSGQ_SOCKET_FILE': 'foo'}, bob.c_channel_env)
|
||||||
|
|
||||||
|
# Check failure of changing user results in a different message
|
||||||
|
bob = MockBobStartup(bind10_src.ChangeUserError('failed to chusr'))
|
||||||
|
r = bob.startup()
|
||||||
|
self.assertIn('failed to chusr', r)
|
||||||
|
self.assertTrue(bob.killed)
|
||||||
|
|
||||||
# Check the case when socket file already exists
|
# Check the case when socket file already exists
|
||||||
isc.cc.Session = DummySessionSocketExists
|
isc.cc.Session = DummySessionSocketExists
|
||||||
bob = MockBobStartup(False)
|
bob = MockBobStartup(False)
|
||||||
@@ -2277,11 +2342,15 @@ class TestFunctions(unittest.TestCase):
|
|||||||
self.assertFalse(os.path.exists(self.lockfile_testpath))
|
self.assertFalse(os.path.exists(self.lockfile_testpath))
|
||||||
os.mkdir(self.lockfile_testpath)
|
os.mkdir(self.lockfile_testpath)
|
||||||
self.assertTrue(os.path.isdir(self.lockfile_testpath))
|
self.assertTrue(os.path.isdir(self.lockfile_testpath))
|
||||||
|
self.__isfile_orig = bind10_src.os.path.isfile
|
||||||
|
self.__unlink_orig = bind10_src.os.unlink
|
||||||
|
|
||||||
def tearDown(self):
|
def tearDown(self):
|
||||||
os.rmdir(self.lockfile_testpath)
|
os.rmdir(self.lockfile_testpath)
|
||||||
self.assertFalse(os.path.isdir(self.lockfile_testpath))
|
self.assertFalse(os.path.isdir(self.lockfile_testpath))
|
||||||
os.environ["B10_LOCKFILE_DIR_FROM_BUILD"] = "@abs_top_builddir@"
|
os.environ["B10_LOCKFILE_DIR_FROM_BUILD"] = "@abs_top_builddir@"
|
||||||
|
bind10_src.os.path.isfile = self.__isfile_orig
|
||||||
|
bind10_src.os.unlink = self.__unlink_orig
|
||||||
|
|
||||||
def test_remove_lock_files(self):
|
def test_remove_lock_files(self):
|
||||||
os.environ["B10_LOCKFILE_DIR_FROM_BUILD"] = self.lockfile_testpath
|
os.environ["B10_LOCKFILE_DIR_FROM_BUILD"] = self.lockfile_testpath
|
||||||
@@ -2305,6 +2374,28 @@ class TestFunctions(unittest.TestCase):
|
|||||||
# second call should not assert anyway
|
# second call should not assert anyway
|
||||||
bind10_src.remove_lock_files()
|
bind10_src.remove_lock_files()
|
||||||
|
|
||||||
|
def test_remove_lock_files_fail(self):
|
||||||
|
# Permission error on unlink is ignored; other exceptions are really
|
||||||
|
# unexpected and propagated.
|
||||||
|
def __raising_unlink(unused, ex):
|
||||||
|
raise ex
|
||||||
|
|
||||||
|
bind10_src.os.path.isfile = lambda _: True
|
||||||
|
os_error = OSError()
|
||||||
|
bind10_src.os.unlink = lambda f: __raising_unlink(f, os_error)
|
||||||
|
|
||||||
|
os_error.errno = errno.EPERM
|
||||||
|
bind10_src.remove_lock_files() # no disruption
|
||||||
|
|
||||||
|
os_error.errno = errno.EACCES
|
||||||
|
bind10_src.remove_lock_files() # no disruption
|
||||||
|
|
||||||
|
os_error.errno = errno.ENOENT
|
||||||
|
self.assertRaises(OSError, bind10_src.remove_lock_files)
|
||||||
|
|
||||||
|
bind10_src.os.unlink = lambda f: __raising_unlink(f, Exception('bad'))
|
||||||
|
self.assertRaises(Exception, bind10_src.remove_lock_files)
|
||||||
|
|
||||||
def test_get_signame(self):
|
def test_get_signame(self):
|
||||||
# just test with some samples
|
# just test with some samples
|
||||||
signame = bind10_src.get_signame(signal.SIGTERM)
|
signame = bind10_src.get_signame(signal.SIGTERM)
|
||||||
|
@@ -177,8 +177,14 @@ class BaseComponent:
|
|||||||
self._start_internal()
|
self._start_internal()
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(BIND10_COMPONENT_START_EXCEPTION, self.name(), e)
|
logger.error(BIND10_COMPONENT_START_EXCEPTION, self.name(), e)
|
||||||
self.failed(None)
|
try:
|
||||||
raise
|
self.failed(None)
|
||||||
|
finally:
|
||||||
|
# Even failed() can fail if this happens during initial startup
|
||||||
|
# time. In that case we'd rather propagate the original reason
|
||||||
|
# for the failure than the fact that failed() failed. So we
|
||||||
|
# always re-raise the original exception.
|
||||||
|
raise e
|
||||||
|
|
||||||
def stop(self):
|
def stop(self):
|
||||||
"""
|
"""
|
||||||
|
@@ -17,11 +17,7 @@ from isc.bind10.component import Component, BaseComponent
|
|||||||
import isc.bind10.sockcreator
|
import isc.bind10.sockcreator
|
||||||
from bind10_config import LIBEXECPATH
|
from bind10_config import LIBEXECPATH
|
||||||
import os
|
import os
|
||||||
import posix
|
|
||||||
import isc.log
|
import isc.log
|
||||||
from isc.log_messages.bind10_messages import *
|
|
||||||
|
|
||||||
logger = isc.log.Logger("boss")
|
|
||||||
|
|
||||||
class SockCreator(BaseComponent):
|
class SockCreator(BaseComponent):
|
||||||
"""
|
"""
|
||||||
@@ -36,8 +32,6 @@ class SockCreator(BaseComponent):
|
|||||||
def __init__(self, process, boss, kind, address=None, params=None):
|
def __init__(self, process, boss, kind, address=None, params=None):
|
||||||
BaseComponent.__init__(self, boss, kind)
|
BaseComponent.__init__(self, boss, kind)
|
||||||
self.__creator = None
|
self.__creator = None
|
||||||
self.__uid = boss.uid
|
|
||||||
self.__gid = boss.gid
|
|
||||||
|
|
||||||
def _start_internal(self):
|
def _start_internal(self):
|
||||||
self._boss.curproc = 'b10-sockcreator'
|
self._boss.curproc = 'b10-sockcreator'
|
||||||
@@ -46,12 +40,9 @@ class SockCreator(BaseComponent):
|
|||||||
self._boss.register_process(self.pid(), self)
|
self._boss.register_process(self.pid(), self)
|
||||||
self._boss.set_creator(self.__creator)
|
self._boss.set_creator(self.__creator)
|
||||||
self._boss.log_started(self.pid())
|
self._boss.log_started(self.pid())
|
||||||
if self.__gid is not None:
|
|
||||||
logger.info(BIND10_SETGID, self.__gid)
|
# We are now ready for switching user.
|
||||||
posix.setgid(self.__gid)
|
self._boss.change_user()
|
||||||
if self.__uid is not None:
|
|
||||||
logger.info(BIND10_SETUID, self.__uid)
|
|
||||||
posix.setuid(self.__uid)
|
|
||||||
|
|
||||||
def _stop_internal(self):
|
def _stop_internal(self):
|
||||||
self.__creator.terminate()
|
self.__creator.terminate()
|
||||||
|
@@ -104,10 +104,10 @@ class ComponentTests(BossUtils, unittest.TestCase):
|
|||||||
self.__stop_process_params = None
|
self.__stop_process_params = None
|
||||||
self.__start_simple_params = None
|
self.__start_simple_params = None
|
||||||
# Pretending to be boss
|
# Pretending to be boss
|
||||||
self.gid = None
|
self.__change_user_called = False
|
||||||
self.__gid_set = None
|
|
||||||
self.uid = None
|
def change_user(self):
|
||||||
self.__uid_set = None
|
self.__change_user_called = True # just record the fact it's called
|
||||||
|
|
||||||
def __start(self):
|
def __start(self):
|
||||||
"""
|
"""
|
||||||
@@ -624,12 +624,6 @@ class ComponentTests(BossUtils, unittest.TestCase):
|
|||||||
self.assertTrue(process.killed)
|
self.assertTrue(process.killed)
|
||||||
self.assertFalse(process.terminated)
|
self.assertFalse(process.terminated)
|
||||||
|
|
||||||
def setgid(self, gid):
|
|
||||||
self.__gid_set = gid
|
|
||||||
|
|
||||||
def setuid(self, uid):
|
|
||||||
self.__uid_set = uid
|
|
||||||
|
|
||||||
class FakeCreator:
|
class FakeCreator:
|
||||||
def pid(self):
|
def pid(self):
|
||||||
return 42
|
return 42
|
||||||
@@ -655,35 +649,19 @@ class ComponentTests(BossUtils, unittest.TestCase):
|
|||||||
"""
|
"""
|
||||||
component = isc.bind10.special_component.SockCreator(None, self,
|
component = isc.bind10.special_component.SockCreator(None, self,
|
||||||
'needed', None)
|
'needed', None)
|
||||||
orig_setgid = isc.bind10.special_component.posix.setgid
|
|
||||||
orig_setuid = isc.bind10.special_component.posix.setuid
|
|
||||||
isc.bind10.special_component.posix.setgid = self.setgid
|
|
||||||
isc.bind10.special_component.posix.setuid = self.setuid
|
|
||||||
orig_creator = \
|
orig_creator = \
|
||||||
isc.bind10.special_component.isc.bind10.sockcreator.Creator
|
isc.bind10.special_component.isc.bind10.sockcreator.Creator
|
||||||
# Just ignore the creator call
|
# Just ignore the creator call
|
||||||
isc.bind10.special_component.isc.bind10.sockcreator.Creator = \
|
isc.bind10.special_component.isc.bind10.sockcreator.Creator = \
|
||||||
lambda path: self.FakeCreator()
|
lambda path: self.FakeCreator()
|
||||||
component.start()
|
component.start()
|
||||||
# No gid/uid set in boss, nothing called.
|
self.assertTrue(self.__change_user_called)
|
||||||
self.assertIsNone(self.__gid_set)
|
|
||||||
self.assertIsNone(self.__uid_set)
|
|
||||||
# Doesn't do anything, but doesn't crash
|
# Doesn't do anything, but doesn't crash
|
||||||
component.stop()
|
component.stop()
|
||||||
component.kill()
|
component.kill()
|
||||||
component.kill(True)
|
component.kill(True)
|
||||||
self.gid = 4200
|
|
||||||
self.uid = 42
|
|
||||||
component = isc.bind10.special_component.SockCreator(None, self,
|
component = isc.bind10.special_component.SockCreator(None, self,
|
||||||
'needed', None)
|
'needed', None)
|
||||||
component.start()
|
|
||||||
# This time, it get's called
|
|
||||||
self.assertEqual(4200, self.__gid_set)
|
|
||||||
self.assertEqual(42, self.__uid_set)
|
|
||||||
isc.bind10.special_component.posix.setgid = orig_setgid
|
|
||||||
isc.bind10.special_component.posix.setuid = orig_setuid
|
|
||||||
isc.bind10.special_component.isc.bind10.sockcreator.Creator = \
|
|
||||||
orig_creator
|
|
||||||
|
|
||||||
class TestComponent(BaseComponent):
|
class TestComponent(BaseComponent):
|
||||||
"""
|
"""
|
||||||
|
Reference in New Issue
Block a user