1

When I execute the following code as root

import os
try:
  if os.getuid() == 0:
    import pwd, grp
    os.setgroups([])
    os.setgid(grp.getgrnam('my_user').gr_gid)
    os.setuid(pwd.getpwnam('my_group').pw_uid)
    os.umask(077)
    print 'dropped privileges successfully'
  else:
    print 'no need to drop privileges'
except:
  print 'unable to drop privileges'

print os.system('ls -lsa ~/')

then the last statement prints ls: cannot open directory /root/: Permission denied.

The cause is clear, but the question is: What do I need to do so that ~ will expand to /home/my_user?

Daniel F
  • 11,845
  • 6
  • 75
  • 100
  • http://stackoverflow.com/questions/4028904/how-to-get-the-home-directory-in-python – dm03514 Apr 28 '14 at 18:57
  • @dm03514 I'm not sure if this is points me in the right direction. My problem is that when using matplotlib I get a `RuntimeError: Failed to create /root/.matplotlib; consider setting MPLCONFIGDIR to a writable directory for matplotlib configuration data`. I dislike the idea of setting MPLCONFIGDIR, and would prefer to "convert" my environment to the one which would fully suit / represent my_user. – Daniel F Apr 28 '14 at 19:01
  • os.path.expanduser('~') – Vor Apr 28 '14 at 19:07
  • Is there a reason you are running your script as `root`? Can't think of a situation where you'd have to do that when using `matplotlib`. – msvalkon Apr 28 '14 at 19:10
  • Yes, it's a (non-public) server using a privileged port. Upon start it binds to the port, then drops its privileges. When it receives a voicemail, it stores it and uses `subprocess.Popen(['python process_voicemail.py "' + tempfile + '"'], shell=True)` to process the message. It is `process_voicemail.py` which uses matplotlib. – Daniel F Apr 28 '14 at 19:15
  • While looking at a os.environ dump I found `environ: {'USERNAME': 'root', 'LANG': 'en_US.UTF-8', 'SUDO_GID': '1000'...` so maybe the problem is that `USERNAME` has not been changed to my_user, while `SUDO_GID` and `SUDO_UID` changed their id's. So this tells me that I'm not dropping the privileges properly. Will check that out now. – Daniel F Apr 28 '14 at 19:29
  • `os.putenv('HOME', '/home/my_user')` solves the issue, but this feels more like a workaround than a proper solution. – Daniel F Apr 28 '14 at 19:46

1 Answers1

0

In this case, where I needed root privileges in order to bind to privileged ports, it turned out to be the wrong approach to start the server as root.

Using authbind turned out to be the proper solution, so that sudo python server.py ended up being authbind python server.py.

I've read that authbind seems to have some problems with ipv6, more helpful information may be found at Is there a way for non-root processes to bind to “privileged” ports (<1024) on Linux?

Community
  • 1
  • 1
Daniel F
  • 11,845
  • 6
  • 75
  • 100