Running python script as root
Asked Answered
R

5

8

I have the following script:

#!/usr/bin/env python                                                           

import sys                                                                      
import pyttsx                                                                   

def main():                                                                     
        print 'running speech-text.py...'                                       
        engine = pyttsx.init()                                                  
        str = "Hi..."                                    
        if len(sys.argv) > 1:                                                   
                str = sys.argv[1]                                               
        engine.say(str)                                                         
        engine.runAndWait()                                                     

if __name__ == '__main__':                                                      
        main() 

and I have placed it in /usr/bin/speech-test.py

I have also given it executable permissions and ownership to root:

sudo chown root:root /usr/bin/speech-test.py
sudo chmod 4755 /usr/bin/speech-test.py

However, this script will only run correctly if I run as sudo speec-test.py. If I try to run it as just speech-test.py it complains about not finding a bunch of ALSA lib files.

Am I missing something to have my script run with root privileges?

Recuperate answered 22/3, 2014 at 6:20 Comment(7)
The problem might be with env in hashbang, but I need to test it. You call it like ./speech-test.py, not by python speech-test.py? Because later would run python still with user rights.Trichromatism
just speech-test.py no ./Recuperate
You can't SUID scripts on linux. If you need it, write a binary launcher or use nopasswd sudo. Anything executable that starts with a hashbang is a script.Sharpeyed
TIL: #18699476 + faqs.org/faqs/unix-faq/faq/part4/section-7.html Thanks @SharpeyedTrichromatism
unrelated: have you tried espeak?Corcyra
If you don't want to use nopasswd sudo then you could create a binary executable from a Python script using something like cx_Freeze.Corcyra
I will look into espeak. Also, will look into cx_Freeze although I just made my own binary wrapper and that fixed the issue.Recuperate
B
15

So you want the script to run as root, even without sudo? For that you would need to set the setuid bit on the script with sudo chmod u+s program. However, most Unix distributions allow this only for binaries, and not for scripts, for security reasons. In general it's really not a good idea to do that.

If you want to run this script as root, you will have to run as sudo. Or, you have to create a binary that runs your script, so that you can set the setuid bit on this binary wrapper. This related question explains more.

It's also a good idea to check the effective uid, and if it's not root then stop running. For that, add this near the top (thanks @efirvida for the tip!)

if not os.geteuid() == 0:
    sys.exit("\nOnly root can run this script\n")

ORIGINAL ANSWER

Maybe your user and root use a different version of python, with different python path, and different set of libraries.

Try this:

command -v python
sudo command -v python

If the two commands don't give the same result then you either need to change the setup of the users to use the same version of python (the one that has the ALSA libs), or hardcode the python version the first line of the script.

Also try adding a print sys.path line in the script, and run with your user and with sudo and compare. Probably you'll get different results. You may need to tweak the PYTHONPATH variable of your user.

It shouldn't be necessary to make the owner of the script root, and to run it with sudo. You just need to configure python and PYTHONPATH correctly.

Berserker answered 22/3, 2014 at 6:32 Comment(2)
which was changed to command -v. There are several reasons to use command -v over which. Please revert if you don't want the change. Also see How to check if command exists in a shell script? and How to check if a program exists from a Bash script?Shabbir
Unless packages are installed globally (accessible to sudo) this won't work, and there is a trend to keep packages local.Histoplasmosis
S
1

Idk but replacing #!/usr/bin/env python by #!/bin/python worked for me.

Syne answered 29/1, 2022 at 11:7 Comment(3)
Your answer could be improved with additional supporting information. Please edit to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers in the help center.Haemagglutinate
(Ubuntu 22.04) This didn't work for me. I get the same "Permission Denied" error.Finally
Do you have multiple python interpreters? If yes, then u may need to specify the version like python3Syne
B
0

I'm not really sure if this is a great method. I tried it and it works fine on arch linux. Let me what you think. If you write a script to execute the .py as different system group, that group can own a python interpreter and have specified root capabilities.

mkdir roottest && cd roottest
sudo cp /usr/bin/python<ver> ./
sudo groupadd -r rootpython
sudo usermod -a -G rootpython <user>
newgrp rootpython
sudo chown root:rootpython python<ver>
sudo chmod 750 $bin                       #that way a normal user can't rwx the python interpreter and the rootpython group cant write.
sudo setcap <caps> ./python<ver>              #now the group has specify caps allowing it to act like root
sudo getcap ./python<ver>
sudo sh
touch rootfile && echo "original text" > rootfile

open a new prompt as regular user

newgroup rootpython
cd roottest && ./python<ver>
>> open('rootfile', 'w').write("different text")
sudo cat rootfile

This method is way more secure than sudo if used properly because python can only do what you let it and does not have complete control of the system. The downside is having to either make a copy of the interpreter or to not allow the regular user's group to use it. DO NOT run all your python code like this, its a big vulnerability if not needed. The cap_net_admin+ep will allow you to change the kernal var ip_forward and for the example above you need cap_dac_override+ep. You can also create a newuser that belongs to the rootpython group, that way you can't just newgrp rootpython without entering the newuser's password.

Blanketyblank answered 10/5, 2018 at 1:44 Comment(0)
D
0

you should run as root sudo -i or su

Dyslogia answered 9/10, 2023 at 20:31 Comment(1)
Welcome to stackoverflow! The question here asks why the program in question doesn't work when not executed as root. Saying "just execute it as root" does therefore not address the problem.Adventuress
R
-4

Its running privilege is the same as the one who ran it. So if you ran it as yourself, it won't have su privilege. You have to do it sudo.

Riggins answered 22/3, 2014 at 6:24 Comment(2)
That's not true if you have sticky bit set, as OP tries.Trichromatism
Oh yeah I forgot about that... SorryRiggins

© 2022 - 2024 — McMap. All rights reserved.