Skip to content
Snippets Groups Projects
Commit 33472103 authored by Honza Mach's avatar Honza Mach
Browse files

Moved the permission changing feature from ZenDaemon to BaseApp.

Now it is possible to use this feature in ZenScripts and this also fixed the issue with permissions being dropped too late (the application was fully set up and possible files and/or directories were created with wrong permissions).
parent cd20757d
No related branches found
No related tags found
No related merge requests found
......@@ -24,6 +24,8 @@ usefull features including (but not limited to) following:
import os
import sys
import pwd
import grp
import re
import shutil
import glob
......@@ -148,6 +150,8 @@ class BaseApp:
CONFIG_ACTION = 'action'
CONFIG_INPUT = 'input'
CONFIG_LIMIT = 'limit'
CONFIG_USER = 'user'
CONFIG_GROUP = 'group'
CONFIG_CFG_FILE = 'config_file'
CONFIG_CFG_DIR = 'config_dir'
CONFIG_LOG_FILE = 'log_file'
......@@ -269,6 +273,12 @@ class BaseApp:
# Option for setting the result limit.
argparser.add_argument('--limit', help = 'apply given limit to the result', type = int)
# Option for overriding the process UID.
argparser.add_argument('--user', help = 'process UID or user name')
# Option for overriding the process GID.
argparser.add_argument('--group', help = 'process GID or group name')
# Option for overriding the name of the configuration file.
argparser.add_argument('--config-file', help = 'name of the config file')
......@@ -376,6 +386,8 @@ class BaseApp:
(self.CONFIG_ACTION, None),
(self.CONFIG_INPUT, None),
(self.CONFIG_LIMIT, None),
(self.CONFIG_USER, None),
(self.CONFIG_GROUP, None),
(self.CONFIG_CFG_FILE, os.path.join(self.paths.get(self.PATH_CFG), "{}.conf".format(self.name))),
(self.CONFIG_CFG_DIR, os.path.join(self.paths.get(self.PATH_CFG), "{}".format(self.name))),
(self.CONFIG_LOG_FILE, os.path.join(self.paths.get(self.PATH_LOG), "{}.log".format(self.name))),
......@@ -602,6 +614,42 @@ class BaseApp:
cc[self.CORE_RUNLOG_SAVE] = True
self.config[self.CORE][self.CORE_RUNLOG] = cc
if self.config[self.CONFIG_USER]:
u = self.config[self.CONFIG_USER]
res = None
if not res:
try:
res = pwd.getpwnam(u)
self.config[self.CONFIG_USER] = [res[0], res[2]]
except:
pass
if not res:
try:
res = pwd.getpwuid(int(u))
self.config[self.CONFIG_USER] = [res[0], res[2]]
except:
pass
if not res:
raise ZenAppSetupException("Unknown user account '{}'".format(u))
if self.config[self.CONFIG_GROUP]:
g = self.config[self.CONFIG_GROUP]
res = None
if not res:
try:
res = grp.getgrnam(g)
self.config[self.CONFIG_GROUP] = [res[0], res[2]]
except:
pass
if not res:
try:
res = grp.getgrgid(int(g))
self.config[self.CONFIG_GROUP] = [res[0], res[2]]
except:
pass
if not res:
raise ZenAppSetupException("Unknown group account '{}'".format(g))
def _configure_check(self):
"""
TODO: Implement config checking mechanism.
......@@ -636,6 +684,21 @@ class BaseApp:
# Check all loaded configurations.
self._configure_check()
def _stage_setup_privileges(self):
"""
Adjust the script privileges according to the configration.
"""
g = self.c(self.CONFIG_GROUP, None)
if g and g[1] != os.getgid():
cg = grp.getgrgid(os.getgid())
self.dbgout("[STATUS] Dropping group privileges from '{}':'{}' to '{}':'{}'".format(cg[0], cg[2], g[0], g[1]))
os.setgid(g[1])
u = self.c(self.CONFIG_USER, None)
if u and u[1] != os.getuid():
cu = pwd.getpwuid(os.getuid())
self.dbgout("[STATUS] Dropping user privileges from '{}':'{}' to '{}':'{}'".format(cu[0], cu[2], u[0], u[1]))
os.setuid(u[1])
def _stage_setup_logging(self):
"""
Setup terminal and file logging facilities.
......@@ -757,6 +820,9 @@ class BaseApp:
# Setup configurations.
self._stage_setup_configuration()
# Setup script privileges
self._stage_setup_privileges()
# Setup logging, if the appropriate feature is enabled.
if self.c(self.CONFIG_LOG_FILE):
self._stage_setup_logging()
......
......@@ -12,8 +12,6 @@ Base implementation of generic daemon.
import os
import re
import sys
import pwd
import grp
import json
import time
import copy
......@@ -252,8 +250,6 @@ class ZenDaemon(pyzenkit.baseapp.BaseApp):
CONFIG_PID_FILE = 'pid_file'
CONFIG_STATE_FILE = 'state_file'
CONFIG_UMASK = 'umask'
CONFIG_USER = 'user'
CONFIG_GROUP = 'group'
CONFIG_STATS_INTERVAL = 'stats_interval'
CONFIG_PARALEL = 'paralel'
......@@ -284,8 +280,6 @@ class ZenDaemon(pyzenkit.baseapp.BaseApp):
(self.CONFIG_PID_FILE, os.path.join(self.paths.get(self.PATH_RUN), "{}.pid".format(self.name))),
(self.CONFIG_STATE_FILE, os.path.join(self.paths.get(self.PATH_RUN), "{}.state".format(self.name))),
(self.CONFIG_UMASK, None),
(self.CONFIG_USER, None),
(self.CONFIG_GROUP, None),
(self.CONFIG_STATS_INTERVAL, 300),
(self.CONFIG_PARALEL, False),
)
......@@ -318,12 +312,6 @@ class ZenDaemon(pyzenkit.baseapp.BaseApp):
# Option for overriding the default umask.
argparser.add_argument('--umask', help = 'default file umask')
# Option for overriding the process UID.
argparser.add_argument('--user', help = 'process UID or user name')
# Option for overriding the process GID.
argparser.add_argument('--group', help = 'process GID or group name')
# Option for defining processing statistics display interval.
argparser.add_argument('--stats-interval', help = 'define processing statistics display interval')
......@@ -400,43 +388,6 @@ class ZenDaemon(pyzenkit.baseapp.BaseApp):
self.config[self.CORE][self.CORE_RUNLOG][self.CORE_RUNLOG_SAVE] = True
self.config[self.CORE][self.CORE_PSTATE][self.CORE_PSTATE_SAVE] = True
if self.config[self.CONFIG_USER]:
u = self.config[self.CONFIG_USER]
res = None
if not res:
try:
res = pwd.getpwnam(u)
self.config[self.CONFIG_USER] = res[2]
except:
pass
if not res:
try:
res = pwd.getpwuid(int(u))
self.config[self.CONFIG_USER] = res[2]
except:
pass
if not res:
raise ZenDaemonException("Unknown user '{}'".format(u))
if self.config[self.CONFIG_GROUP]:
g = self.config[self.CONFIG_GROUP]
res = None
if not res:
try:
res = grp.getgrnam(g)
self.config[self.CONFIG_GROUP] = res[2]
except:
pass
if not res:
try:
res = grp.getgruid(int(g))
self.config[self.CONFIG_GROUP] = res[2]
except:
pass
if not res:
raise ZenDaemonException("Unknown group '{}'".format(g))
def _stage_setup_custom(self):
"""
Perform custom daemon related setup.
......@@ -742,8 +693,6 @@ class ZenDaemon(pyzenkit.baseapp.BaseApp):
work_dir = self.c(self.CONFIG_WORK_DIR),
pidfile = self.get_fn_pidfile(),
umask = self.c(self.CONFIG_UMASK),
uid = self.c(self.CONFIG_USER),
gid = self.c(self.CONFIG_GROUP),
files_preserve = logs,
signals = {
signal.SIGHUP: self._hnd_signal_hup,
......@@ -765,8 +714,6 @@ class ZenDaemon(pyzenkit.baseapp.BaseApp):
work_dir = self.c(self.CONFIG_WORK_DIR),
pidfile = self.get_fn_pidfile(),
umask = self.c(self.CONFIG_UMASK),
uid = self.c(self.CONFIG_USER),
gid = self.c(self.CONFIG_GROUP),
signals = {
signal.SIGHUP: self._hnd_signal_hup,
signal.SIGUSR1: self._hnd_signal_usr1,
......
......@@ -23,7 +23,7 @@ with open(path.join(here, 'README.rst'), encoding='utf-8') as f:
setup(
name = 'pyzenkit',
version = '0.13',
version = '0.16',
description = 'Python 3 script and daemon toolkit',
long_description = long_description,
classifiers = [
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment