Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

running python-daemon as non-priviliged user and keeping group-memberships

I'm writing a daemon in python, using the python-daemon package. the daemon is started at boot-time (init.d) and needs to access various devices. the daemon is to run on an embedded system (beaglebone) running ubuntu.

now my problem is that I want to run the daemon as an unprivileged user rather (e.g. mydaemon) than root.

in order to allow the daemon to access the devices I added that user to the required groups. in the python code I use daemon.DaemonContext(uid=uidofmydamon).

the process started by root daemonizes nicely and is owned by the correct user, but I get permission denied errors when trying to access the devices. I wrote a small test application, and it seems that the process does not inherit the group-memberships of the user.

#!/usr/bin/python
import logging, daemon, os

if __name__ == '__main__':
  lh=logging.StreamHandler()
  logger = logging.getLogger()
  logger.setLevel(logging.INFO)
  logger.addHandler(lh)

  uid=1001 ## UID of the daemon user
  with daemon.DaemonContext(uid=uid,
                            files_preserve=[lh.stream],
                            stderr=lh.stream):
    logger.warn("UID : %s" % str(os.getuid()))
    logger.warn("groups: %s" % str(os.getgroups()))

when i run the above code as the user with uid=1001 i get something like

$ ./testdaemon.py
UID: 1001
groups: [29,107,1001]

whereas when I run the above code as root (or su), I get:

$ sudo ./testdaemon.py
UID: 1001
groups: [0]

How can I create a daemon-process started by root but with a different effective uid and intact group memberships?

like image 477
umläute Avatar asked Jul 01 '13 12:07

umläute


1 Answers

my current solution involves dropping root priviliges before starting the actual daemon, using the chuid argument for start-stop-daemon:

 start-stop-daemon \
      --start \
      --chuid daemonuser \
      --name testdaemon \
      --pidfile /var/run/testdaemon/test.pid \
      --startas /tmp/testdaemon.py \
     -- \
      --pidfile /var/run/testdaemon/test.pid \
      --logfile=/var/log/testdaemon/testdaemon.log

the drawback of this solution is, that i need to create all directories, where the daemon ought to write to (noteably /var/run/testdaemon and /var/log/testdaemon), before starting the actual daemon (with the proper file permissions).

i would have preferred to write that logic in python rather than bash.

for now that works, but me thinketh that this should be solveable in a more elegant fashion.

like image 200
umläute Avatar answered Sep 30 '22 14:09

umläute