0

I want to run a python program using sudo (e.g. sudo python test.py) but within the python program when I use os.system(<some command>) to invoke other processes, I want to run them as a non-root user.

Is this doable?

Thanks!

PLNewbie
  • 69
  • 7
  • Fork a subprocess. In the subprocess, call `os.setuid()` to the user, then do what you want. In the parent, wait for the subprocess to complete (`os.waitpid()`). – alani Jul 26 '20 at 22:50
  • 2
    @alaniwi Thanks! This works! Another way I just found seems to be that I can add a prefix "sudo -u username" in front of the command I want to run to execute as that specific user. – PLNewbie Jul 26 '20 at 22:55
  • Could you please add the solution you found as the right answer to the question. This might help others. – dbaltor Jul 27 '20 at 07:41

2 Answers2

1

Example:

import os
import pwd

username = "nobody"

pwent = pwd.getpwnam(username)
uid = pwent.pw_uid
gid = pwent.pw_gid

pid = os.fork()
if pid == 0:
    # child

    # relinquish any privileged groups before we call setuid
    # (not bothering to load the target user's supplementary groups here)
    os.setgid(gid)
    os.setgroups([])

    # now relinquish root privs
    os.setuid(uid)

    # os.setuid should probably raise an exception if it fails,
    # but I'm paranoid so...
    if os.getuid() != uid:
        print("setuid failed - bailing")
        os._exit(1)

    return_value = os.system("id") // 256  # or whatever
    os._exit(return_value)

# parent
os.waitpid(pid, 0)

print("parent continues (still root here)")

os.system("id")

Gives:

uid=65534(nobody) gid=65534(nogroup) groups=65534(nogroup)
parent continues (still root here)
uid=0(root) gid=0(root) groups=0(root)
alani
  • 12,573
  • 2
  • 13
  • 23
0

Another way to do this is to add a prefix sudo -u username in front of the command one wants to run to execute as that specific user. For example, one can use os.system('sudo -u user_a python test.py') to run test.py inside a python script as user_a.

PLNewbie
  • 69
  • 7