[svn] commit: r2277 - in /branches/trac180: ChangeLog src/bin/bind10/bind10.py.in src/bin/bind10/tests/args_test.py src/bin/bind10/tests/bind10_test.in
BIND 10 source code commits
bind10-changes at lists.isc.org
Fri Jun 25 02:23:26 UTC 2010
Author: shane
Date: Fri Jun 25 02:23:26 2010
New Revision: 2277
Log:
Initial support for setuid. Will be replaced later when the
PriviligedSocketCreator arrives.
See Trac ticket #180 for more details:
https://bind10.isc.org/ticket/180
Added:
branches/trac180/src/bin/bind10/tests/args_test.py
Modified:
branches/trac180/ChangeLog
branches/trac180/src/bin/bind10/bind10.py.in
branches/trac180/src/bin/bind10/tests/bind10_test.in
Modified: branches/trac180/ChangeLog
==============================================================================
--- branches/trac180/ChangeLog (original)
+++ branches/trac180/ChangeLog Fri Jun 25 02:23:26 2010
@@ -1,3 +1,8 @@
+ XX. [func] shane
+ Added initial support for setuid(). This will be replaced in the
+ future, but for now provides a reasonable starting point.
+ (Trac #180, svn rYYYY)
+
58. [bug] jinmei
Worked around an interaction issue between ASIO and standard C++
library headers. Without this ASIO didn't work: sometimes the
Modified: branches/trac180/src/bin/bind10/bind10.py.in
==============================================================================
--- branches/trac180/src/bin/bind10/bind10.py.in (original)
+++ branches/trac180/src/bin/bind10/bind10.py.in Fri Jun 25 02:23:26 2010
@@ -57,6 +57,9 @@
import select
import random
from optparse import OptionParser, OptionValueError
+import io
+import pwd
+import posix
import isc.cc
@@ -114,15 +117,21 @@
dev_null = open(os.devnull, "w")
def __init__(self, name, args, env={}, dev_null_stdout=False,
- dev_null_stderr=False):
+ dev_null_stderr=False, uid=None):
self.name = name
self.args = args
self.env = env
self.dev_null_stdout = dev_null_stdout
self.dev_null_stderr = dev_null_stderr
self.restart_schedule = RestartSchedule()
+ self.uid = uid
self._spawn()
+ def _setuid(self):
+ if not self.uid is None:
+ sys.stderr.write("setting uid\n")
+ posix.setuid(self.uid)
+ sys.stderr.write("set it\n")
def _spawn(self):
if self.dev_null_stdout:
@@ -145,7 +154,8 @@
stdout=spawn_stdout,
stderr=spawn_stderr,
close_fds=True,
- env=spawn_env,)
+ env=spawn_env,
+ preexec_fn=self._setuid)
self.pid = self.process.pid
self.restart_schedule.set_run_start_time()
@@ -155,7 +165,8 @@
class BoB:
"""Boss of BIND class."""
- def __init__(self, msgq_socket_file=None, auth_port=5300, verbose=False):
+ def __init__(self, msgq_socket_file=None, auth_port=5300, verbose=False,
+ setuid=None):
"""Initialize the Boss of BIND. This is a singleton (only one
can run).
@@ -171,6 +182,7 @@
self.processes = {}
self.dead_processes = {}
self.runnable = False
+ self.uid = setuid
def config_handler(self, new_config):
if self.verbose:
@@ -225,12 +237,13 @@
sys.stdout.write("[bind10] Starting b10-msgq\n")
try:
c_channel = ProcessInfo("b10-msgq", ["b10-msgq"], c_channel_env,
- True, not self.verbose)
+ True, not self.verbose, uid=self.uid)
except Exception as e:
return "Unable to start b10-msgq; " + str(e)
self.processes[c_channel.pid] = c_channel
if self.verbose:
- sys.stdout.write("[bind10] Started b10-msgq (PID %d)\n" % c_channel.pid)
+ sys.stdout.write("[bind10] Started b10-msgq (PID %d)\n" %
+ c_channel.pid)
# now connect to the c-channel
cc_connect_start = time.time()
@@ -250,7 +263,7 @@
sys.stdout.write("[bind10] Starting b10-cfgmgr\n")
try:
bind_cfgd = ProcessInfo("b10-cfgmgr", ["b10-cfgmgr"],
- c_channel_env)
+ c_channel_env, uid=self.uid)
except Exception as e:
c_channel.process.kill()
return "Unable to start b10-cfgmgr; " + str(e)
@@ -271,23 +284,6 @@
self.ccs.start()
if self.verbose:
sys.stdout.write("[bind10] ccsession started\n")
-
- # start the xfrout before auth-server, to make sure every xfr-query can
- # be processed properly.
- xfrout_args = ['b10-xfrout']
- if self.verbose:
- sys.stdout.write("[bind10] Starting b10-xfrout\n")
- xfrout_args += ['-v']
- try:
- xfrout = ProcessInfo("b10-xfrout", xfrout_args,
- c_channel_env )
- except Exception as e:
- c_channel.process.kill()
- bind_cfgd.process.kill()
- return "Unable to start b10-xfrout; " + str(e)
- self.processes[xfrout.pid] = xfrout
- if self.verbose:
- sys.stdout.write("[bind10] Started b10-xfrout (PID %d)\n" % xfrout.pid)
# start b10-auth
# XXX: this must be read from the configuration manager in the future
@@ -307,6 +303,28 @@
self.processes[auth.pid] = auth
if self.verbose:
sys.stdout.write("[bind10] Started b10-auth (PID %d)\n" % auth.pid)
+
+ # everything after the authoritative server can run as non-root
+ if not self.uid is None:
+ posix.setuid(self.uid)
+
+ # start the xfrout before auth-server, to make sure every xfr-query can
+ # be processed properly.
+ xfrout_args = ['b10-xfrout']
+ if self.verbose:
+ sys.stdout.write("[bind10] Starting b10-xfrout\n")
+ xfrout_args += ['-v']
+ try:
+ xfrout = ProcessInfo("b10-xfrout", xfrout_args,
+ c_channel_env )
+ except Exception as e:
+ c_channel.process.kill()
+ bind_cfgd.process.kill()
+ return "Unable to start b10-xfrout; " + str(e)
+ self.processes[xfrout.pid] = xfrout
+ if self.verbose:
+ sys.stdout.write("[bind10] Started b10-xfrout (PID %d)\n" %
+ xfrout.pid)
# start b10-xfrin
xfrin_args = ['b10-xfrin']
@@ -324,7 +342,8 @@
return "Unable to start b10-xfrin; " + str(e)
self.processes[xfrind.pid] = xfrind
if self.verbose:
- sys.stdout.write("[bind10] Started b10-xfrin (PID %d)\n" % xfrind.pid)
+ sys.stdout.write("[bind10] Started b10-xfrin (PID %d)\n" %
+ xfrind.pid)
# start the b10-cmdctl
# XXX: we hardcode port 8080
@@ -344,7 +363,8 @@
return "Unable to start b10-cmdctl; " + str(e)
self.processes[cmd_ctrld.pid] = cmd_ctrld
if self.verbose:
- sys.stdout.write("[bind10] Started b10-cmdctl (PID %d)\n" % cmd_ctrld.pid)
+ sys.stdout.write("[bind10] Started b10-cmdctl (PID %d)\n" %
+ cmd_ctrld.pid)
self.runnable = True
@@ -439,7 +459,8 @@
next_restart = None
# if we're shutting down, then don't restart
if not self.runnable:
- return next_restart
+# return next_restart
+ return 0
# otherwise look through each dead process and try to restart
still_dead = {}
now = time.time()
@@ -510,6 +531,10 @@
def main():
global options
global boss_of_bind
+ # Enforce line buffering on stdout, even when not a TTY
+ sys.stdout = io.TextIOWrapper(sys.stdout.detach(), line_buffering=True)
+
+
# Parse any command-line options.
parser = OptionParser(version=__version__)
parser.add_option("-v", "--verbose", dest="verbose", action="store_true",
@@ -520,7 +545,34 @@
parser.add_option("-m", "--msgq-socket-file", dest="msgq_socket_file",
type="string", default=None,
help="UNIX domain socket file the b10-msgq daemon will use")
+ parser.add_option("-u", "--user", dest="user",
+ type="string", default=None,
+ help="Change user after startup (must run as root)")
(options, args) = parser.parse_args()
+ if args:
+ parser.print_help()
+ sys.exit(1)
+
+ # Check user ID.
+ setuid = None
+ if options.user:
+ try:
+ pw_ent = pwd.getpwuid(int(options.user))
+ setuid = pw_ent.pw_uid
+ except ValueError:
+ pass
+ except KeyError:
+ pass
+
+ try:
+ pw_ent = pwd.getpwnam(options.user)
+ setuid = pw_ent.pw_uid
+ except KeyError:
+ pass
+
+ if setuid is None:
+ sys.stderr.write("bind10: invalid user: '%s'\n" % options.user)
+ sys.exit(1)
# Announce startup.
if options.verbose:
@@ -543,11 +595,12 @@
# Go bob!
boss_of_bind = BoB(options.msgq_socket_file, int(options.auth_port),
- options.verbose)
+ options.verbose, setuid)
startup_result = boss_of_bind.startup()
if startup_result:
sys.stderr.write("[bind10] Error on startup: %s\n" % startup_result)
sys.exit(1)
+ sys.stdout.write("[bind10] BIND 10 started\n")
# In our main loop, we check for dead processes or messages
# on the c-channel.
@@ -584,6 +637,7 @@
# shutdown
signal.signal(signal.SIGCHLD, signal.SIG_DFL)
boss_of_bind.shutdown()
+ sys.exit(0)
if __name__ == "__main__":
main()
Modified: branches/trac180/src/bin/bind10/tests/bind10_test.in
==============================================================================
--- branches/trac180/src/bin/bind10/tests/bind10_test.in (original)
+++ branches/trac180/src/bin/bind10/tests/bind10_test.in Fri Jun 25 02:23:26 2010
@@ -28,4 +28,5 @@
cd ${BIND10_PATH}/tests
exec ${PYTHON_EXEC} -O bind10_test.py $*
+exec ${PYTHON_EXEC} -O args_test.py $*
More information about the bind10-changes
mailing list