I am opening some subproceses in python script and i need one of them to be with root privileges.
Is there a way to do this without running the whole script with root privileges?
p1 = "../p1"
p2 = "../p2"
p_root = "../p_root"
proc_P1 = subprocess.Popen(p1, stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE)
proc_P2 = subprocess.Popen(p2, stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE)
proc_ROOT = subprocess.Popen(p_root, stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE)
There are two (*) methods I can think of.
Add that one script, ../p_root
invocation to be a passwordless sudo configuration in the sudoers.d
directory. This configuration will allow only ../p_root
to be invoked with passwordless sudo. It is imperative you lock down the script write permissions. At least remove others' permission to write chmod o-w ../p_root
. Otherwise, someone can exploit this and run arbitrary code as root
by editing the file and adding their own content.
Each file in /etc/sudoers.d
contains rules for sudo
. You can add your own files in that directory, to sanely manage your system. The files within /etc/sudoers.d
are read in order (convention is to name them 10-something
, 20-else
, etc). They must be edited with visudo
.
visudo /etc/sudoers.d/20-special-proot
Example content (full path to executable used is mandatory)
youruser ALL=(ALL) NOPASSWD: /usr/bin/bash /full/path/to/p_root
The second is setting SetUID. This is a file permission that allows executing a script with its owner's permission. i.e., it means that you own the ../p_root
script to root
and whoever can execute it (group/others) will always run the script as root
.
chown root.yourgroup
chmod u+s ../p_root
chmod o-w ../p_root
Again, the same security implications apply here. Whoever can execute this file (group or others have execution permissions, especially) will run everything inside as root
. If a low privileged user (e.g. others) have write permissions then they can simply edit the file, add themselves to root
and change your PS1
to black on black.
As advised by lior.i, I'm adding this option, too.
You can prefix sudo
and bash
to your script's path as the executed command in order to achieve the same goal.
Popen(['sudo', 'bash', '/path/to/script'])
Popen is worth learning and the recommended way to execute subprocesses, especially in the long run. In other words, it can do anything the rest can. One of the reasoning for this, I found, is both flexibility and debugging. Flexibility to completely detach the subprocess from its parent or not. By default, if the parent is killed gracefully (SIGINT/Ctrl+C), the child will be signaled to die, too. Similarly, they're also attached at their stdin
, stdout
and stderr
file descriptor. Perhaps you want to make use of a new file descriptor for some crafty magic.
A consideration you should take if you use this is not using it in production. Leaving an applicative user with passwordless sudo is a security risk similar to just running everything as root.