summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJulien Cristau <julien.cristau@logilab.fr>2011-09-06 11:20:27 +0200
committerJulien Cristau <julien.cristau@logilab.fr>2011-09-06 11:20:27 +0200
commitd18aef0ff0eb5a3577c232eed317bd2b0001e601 (patch)
tree4f9922914cdb074bc45bdd0113830c1a7f85714b
parent23a3aa51b7464990be210167261f29653bb80491 (diff)
downloadlogilab-common-d18aef0ff0eb5a3577c232eed317bd2b0001e601.tar.gz
daemon: call initgroups/setgid before setuid (closes #74173)
Otherwise we keep the initial (most likely root) GID.
-rw-r--r--ChangeLog3
-rw-r--r--daemon.py28
2 files changed, 25 insertions, 6 deletions
diff --git a/ChangeLog b/ChangeLog
index f3140f2..c4f87cb 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -4,6 +4,9 @@ ChangeLog for logilab.common
--
* modutils: allow overriding of _getobj by suppressing mangling
+--
+ * daemon: call initgroups/setgid before setuid
+
2011-08-05 -- 0.56.1
* clcommands: #72450 --rc-file option doesn't work
diff --git a/daemon.py b/daemon.py
index 7890637..2eedca5 100644
--- a/daemon.py
+++ b/daemon.py
@@ -26,6 +26,27 @@ import sys
import time
import warnings
+def setugid(user):
+ """Change process user and group ID
+
+ Argument is a numeric user id or a user name"""
+ try:
+ from pwd import getpwuid
+ passwd = getpwuid(int(user))
+ except ValueError:
+ from pwd import getpwnam
+ passwd = getpwnam(user)
+
+ if hasattr(os, 'initgroups'): # python >= 2.7
+ os.initgroups(passwd.pw_name, passwd.pw_gid)
+ else:
+ import ctypes
+ if ctypes.CDLL(None).initgroups(passwd.pw_name, passwd.pw_gid) < 0:
+ err = ctypes.c_int.in_dll(ctypes.pythonapi,"errno").value
+ raise OSError(err, os.strerror(err), 'initgroups')
+ os.setgid(passwd.pw_gid)
+ os.setuid(passwd.pw_uid)
+
def daemonize(pidfile=None, uid=None, umask=077):
"""daemonize a Unix process. Set paranoid umask by default.
@@ -73,12 +94,7 @@ def daemonize(pidfile=None, uid=None, umask=077):
f.close()
# change process uid
if uid:
- try:
- uid = int(uid)
- except ValueError:
- from pwd import getpwnam
- uid = getpwnam(uid).pw_uid
- os.setuid(uid)
+ setugid(uid)
return None