pythonlinuxubuntupython-daemon

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?


Solution

  • 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.