summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorAlexander Sulfrian <alexander@sulfrian.net>2015-01-16 03:53:00 +0100
committerAlexander Sulfrian <alexander@sulfrian.net>2015-02-25 18:35:00 +0100
commitf69d2c18d1351d49f4c1ffd2a6c282df0fa3d8e3 (patch)
treea8861e9ce11b6a5c320c2c1f9ba23cb152f6c20a /src
parent12b769d5864c9e04235184d38a5089f1ee655c8c (diff)
downloadbcfg2-f69d2c18d1351d49f4c1ffd2a6c282df0fa3d8e3.tar.gz
bcfg2-f69d2c18d1351d49f4c1ffd2a6c282df0fa3d8e3.tar.bz2
bcfg2-f69d2c18d1351d49f4c1ffd2a6c282df0fa3d8e3.zip
Server/Core: drop privileges even if not running as daemon
Diffstat (limited to 'src')
-rw-r--r--src/lib/Bcfg2/Options.py4
-rw-r--r--src/lib/Bcfg2/Server/CherryPyCore.py16
-rw-r--r--src/lib/Bcfg2/Server/Core.py17
-rw-r--r--src/lib/Bcfg2/Server/MultiprocessingCore.py3
-rwxr-xr-xsrc/sbin/bcfg2-info2
5 files changed, 34 insertions, 8 deletions
diff --git a/src/lib/Bcfg2/Options.py b/src/lib/Bcfg2/Options.py
index 652e216a5..fdc34eb95 100644
--- a/src/lib/Bcfg2/Options.py
+++ b/src/lib/Bcfg2/Options.py
@@ -1348,7 +1348,9 @@ TEST_COMMON_OPTIONS = dict(noseopts=TEST_NOSEOPTS,
validate=CFG_VALIDATION)
INFO_COMMON_OPTIONS = dict(ppath=PARANOID_PATH,
- max_copies=PARANOID_MAX_COPIES)
+ max_copies=PARANOID_MAX_COPIES,
+ daemon_uid=SERVER_DAEMON_USER,
+ daemon_gid=SERVER_DAEMON_GROUP)
INFO_COMMON_OPTIONS.update(CLI_COMMON_OPTIONS)
INFO_COMMON_OPTIONS.update(SERVER_COMMON_OPTIONS)
diff --git a/src/lib/Bcfg2/Server/CherryPyCore.py b/src/lib/Bcfg2/Server/CherryPyCore.py
index d097fd08f..c1581679c 100644
--- a/src/lib/Bcfg2/Server/CherryPyCore.py
+++ b/src/lib/Bcfg2/Server/CherryPyCore.py
@@ -103,17 +103,21 @@ class Core(BaseCore):
return cherrypy.serving.response.body
def _daemonize(self):
- """ Drop privileges with
- :class:`cherrypy.process.plugins.DropPrivileges`, daemonize
- with :class:`cherrypy.process.plugins.Daemonizer`, and write a
+ """ Drop privileges, daemonize
+ with :class:`cherrypy.process.plugins.Daemonizer` and write a
PID file with :class:`cherrypy.process.plugins.PIDFile`. """
+ self._drop_privileges()
+ Daemonizer(cherrypy.engine).subscribe()
+ PIDFile(cherrypy.engine, self.setup['daemon']).subscribe()
+ return True
+
+ def _drop_privileges(self):
+ """ Drop privileges with
+ :class:`cherrypy.process.plugins.DropPrivileges` """
DropPrivileges(cherrypy.engine,
uid=self.setup['daemon_uid'],
gid=self.setup['daemon_gid'],
umask=int(self.setup['umask'], 8)).subscribe()
- Daemonizer(cherrypy.engine).subscribe()
- PIDFile(cherrypy.engine, self.setup['daemon']).subscribe()
- return True
def _run(self):
""" Start the server listening. """
diff --git a/src/lib/Bcfg2/Server/Core.py b/src/lib/Bcfg2/Server/Core.py
index 6dfe4df1f..0369da8f2 100644
--- a/src/lib/Bcfg2/Server/Core.py
+++ b/src/lib/Bcfg2/Server/Core.py
@@ -11,6 +11,7 @@ import threading
import time
import inspect
import lxml.etree
+import daemon
import Bcfg2.settings
import Bcfg2.Server
import Bcfg2.Logger
@@ -112,6 +113,7 @@ class BaseCore(object):
:type setup: Bcfg2.Options.OptionParser
.. automethod:: _daemonize
+ .. automethod:: _drop_privileges
.. automethod:: _run
.. automethod:: _block
.. -----
@@ -803,7 +805,8 @@ class BaseCore(object):
self.logger.debug("Slept %s seconds while handling FAM events" % slept)
def run(self):
- """ Run the server core. This calls :func:`_daemonize`,
+ """ Run the server core. This calls :func:`_daemonize`
+ (or :func:`_drop_privileges` if not in daemon mode),
:func:`_run`, starts the :attr:`fam_thread`, and calls
:func:`_block`, but note that it is the responsibility of the
server core implementation to call :func:`shutdown` under
@@ -830,6 +833,8 @@ class BaseCore(object):
# dropped
os.environ['HOME'] = pwd.getpwuid(self.setup['daemon_uid'])[5]
else:
+ if os.getuid() == 0:
+ self._drop_privileges()
os.umask(int(self.setup['umask'], 8))
if not self._run():
@@ -861,6 +866,16 @@ class BaseCore(object):
overridden by a core implementation. """
raise NotImplementedError
+ def _drop_privileges(self):
+ """ This is called if not daemonized and running as root to
+ drop the privileges to the configured daemon_uid and daemon_gid.
+ """
+ daemon.daemon.change_process_owner(
+ self.setup['daemon_uid'],
+ self.setup['daemon_gid'])
+ self.logger.debug("Dropped privileges to %s:%s." %
+ (os.getuid(), os.getgid()))
+
def _run(self):
""" Start up the server; this method should return
immediately. This must be overridden by a core
diff --git a/src/lib/Bcfg2/Server/MultiprocessingCore.py b/src/lib/Bcfg2/Server/MultiprocessingCore.py
index 2cb3adae3..4986aac60 100644
--- a/src/lib/Bcfg2/Server/MultiprocessingCore.py
+++ b/src/lib/Bcfg2/Server/MultiprocessingCore.py
@@ -210,6 +210,9 @@ class ChildCore(BaseCore):
def _daemonize(self):
return True
+ def _drop_privileges(self):
+ pass
+
def _dispatch(self, address, data):
""" Method dispatcher used for commands received from
the RPC queue. """
diff --git a/src/sbin/bcfg2-info b/src/sbin/bcfg2-info
index a6c3149bc..2c97a9b91 100755
--- a/src/sbin/bcfg2-info
+++ b/src/sbin/bcfg2-info
@@ -726,6 +726,8 @@ Bcfg2 client itself.""")
def run(self, args): # pylint: disable=W0221
try:
+ if os.getuid() == 0:
+ self._drop_privileges()
self.load_plugins()
self.block_for_fam_events(handle_events=True)
if args: