How do you temporary run your code as 'root

2019-08-06 14:44发布

问题:

RELATED: Python multiprocessing: Permission denied

I want to use Python's multiprocessing.Pool

import multiprocessing as mp
pool =  mp.Pool(3)
for i in range(num_to_run):
    pool.apply_async(popen_wrapper, args=(i,), callback=log_result)

I get OSError

  File "/usr/local/lib/python2.6/multiprocessing/__init__.py", line 178, in RLock
    return RLock()
  File "/usr/local/lib/python2.6/multiprocessing/synchronize.py", line 142, in __init__
    SemLock.__init__(self, RECURSIVE_MUTEX, 1, 1)
  File "/usr/local/lib/python2.6/multiprocessing/synchronize.py", line 49, in __init__
    sl = self._semlock = _multiprocessing.SemLock(kind, value, maxvalue)
OSError: [Errno 13] Permission denied

I read in the related question that it's due to not having r/w to /dev/shm

Besides changing the permission in /dev/shm, is there a way to run as root in the code?

I initially thought you could do something like os.umask() but it didnt work

EDIT (rephrasing the question):

  • let's say a username A has r/w access to directory A
  • You are user B and your program needs access to directory A. how do you run a program as user A?

回答1:

In order from the least dangerous to the most dangerous.

  1. You can try dropping permissions as John Zwinck suggested. Basically you would start the program with root level permissions, immediately do what you need to do, and then switch to a non-root user.

    From this StackOverflow.

    import os, pwd, grp
    
    def drop_privileges(uid_name='nobody', gid_name='nogroup'):
    if os.getuid() != 0:
    # We're not root so, like, whatever dude
    return
    
    # Get the uid/gid from the name
    running_uid = pwd.getpwnam(uid_name).pw_uid
    running_gid = grp.getgrnam(gid_name).gr_gid
    
    # Remove group privileges
    os.setgroups([])
    
    # Try setting the new uid/gid
    os.setgid(running_gid)
    os.setuid(running_uid)
    
    # Ensure a very conservative umask
    old_umask = os.umask(077)
    
  2. You could also require the credentials for the root user to be inputed into the script, and then only use them when they are required.

    subprocess.call("sudo python RunStuffWithElevatedPrivelages.py")
    #From here, the main script will continue to run without root permissions
    

    Or if you don't want the script to prompt the user for the password you can do

    subprocess.call("echo getRootCredentials() | sudo -S python RunStuffWithElevatedPrivelages.py")
    
  3. Or you could just run the entire program as a root user -- sudo python myScript.py.

As far as temporarily giving users root permission to /dev/shm only when they run your script, the only thing I could think of was having some script that runs in the background under the root user that can temporarily grant anyone who uses your script root privileges to /dev/shm. This could be done through using setuid to grant such permissions and then after a certain amount of time or if the script ends the privilege is taken away. My only concern would be if there is a way a user who has temporarily been given such permissions might be able to secure more permanent privileges.