views:

387

answers:

1

I've got a long running, daemonized Python process that uses subprocess to spawn new child processes when certain events occur. The long running process is started by a user with super user privileges. I need the child processes it spawns to run as a different user (e.g., "nobody") while retaining the super user privileges for the parent process.

I'm currently using

su -m nobody -c <program to execute as a child>

but this seems heavyweight and doesn't die very cleanly.

Is there a way to accomplish this programmatically instead of using su? I'm looking at the os.set*uid methods, but the doc in the Python std lib is quite sparse in that area.

+4  A: 

There is an os.setuid() method. You can use it to change the current user for this script.

One solution is, somewhere where the child starts, to call os.setuid() and os.setgid() to change the user and group id and after that call one of the os.exec* methods to spawn a new child. The newly spawned child will run with the less powerful user without the ability to become a more powerful one again.

Another is to do it when the daemon (the master process) starts and then all newly spawned processes will have run under the same user.

For information look at the manpage for setuid.

Emil Ivanov
You may also need `os.setgroups()` if you're switching to a user with additional gids. Other than that, yeah, it's pretty straightforward.
bobince
Followup: The processes intended to run as nobody are untrusted, third-party apps. I can't rely on them switching to another uid/gid. I also can't switch the daemon process to another uid/gid permanently when it starts because it still needs super user privileges for some ops other than launching these child processes.Is the following possible?1. Start the daemon as a super user.2. When the daemon is about to launch a child, drop to the nobody user. Ensure that the child can't become a super user again.3. After launching the child, switch the daemon back to super user privileges.
Peter Parente
No. Once you become a less powerful user there is no way back. I've edited the post above that should work for you - look at the first option.
Emil Ivanov
The subprocess.Popen function has a preexec_func parameter which can be used to accomplish the double child spawn suggested by Emil. The preexec_func can call os.setgid and os.setuid in the context of the first launched child which will then launch the second as that user.
Peter Parente