2

I have to execute few commands in linux but I need to be a super user before I execute the command. This has to be done via python script The scenario is i should execute the following command in the order

>> su

This prompts for password

After entering the password I will have to execute the bluez commands

>> hciconfig hci0 up
>> hcitool lescan
>> hcitool lecc <address>

i need to do this in python but could you please tell me how to be a super user and give password via python then later execute the above commands in order? Meaning,I want to automate the whole process that is execute all the commands without manual intervention.

sans0909
  • 395
  • 7
  • 20
  • sudo python script.py – Rolf of Saxony Jan 27 '16 at 08:42
  • See the [`subprocess`](https://docs.python.org/2/library/subprocess.html) module for running commands. Instead of using `su`, I recommend running each command with `sudo`. The user should only be prompted for a password the first time. – augurar Jan 27 '16 at 08:50
  • 2
    @sanyesh: read `man sudoers`, assuming your Python script can resides in a standard location and a given group of users needs to use it, you can "whitelist" the commands that require super user privileges inside the `sudoers` file and use `NOPASSWD`, so such a script could even be run unattended. – 0xC0000022L Jan 27 '16 at 08:58
  • @0xC0000022L thank you – sans0909 Jan 27 '16 at 09:14
  • @augurar thank you , how to automate this process without manual intervention – sans0909 Jan 27 '16 at 09:15
  • add a entry in `sudoers.tmp`, don't add your root pasword in to python script. – dsgdfg Jan 27 '16 at 11:44

4 Answers4

2

Good security practice says you should minimize the time you are at elevated privilege. One way to do this is to put the commands to be run as root in a different file and then cause that file to be run as root. You have several options:

  1. Your script could run the other script with sudo:
    subprocess.check_call(['sudo', '/we/run/as/root']);
  2. You could make the script be 'setuid-root' and run it, no sudo needed:
    subprocess.check_call(['/we/run/as/root']);
    (however, on many systems this will not work because setuid-root is disabled on scripts)
  3. Like #2 but use a small C-program which is setuid-root and it runs your script:
    subprocess.check_call(['/the/c/program']); Basically the C-program is:
    int main(void) { return system("/we/run/as/root"); }
John Hascall
  • 9,176
  • 6
  • 48
  • 72
  • 1
    You should avoid `os.system()` like it says in its documentation, and avoid invoking a shell if you can. Try `subprocess.check_call(['sudo', '/we/run/as/root'])` instead. – tripleee Jan 27 '16 at 09:43
0

Another recommendation to start the python script initially with sudo is that when you run a very long script that requires sudo permissions at the end, it will still require you to re-enter your password.

An example of calling sudo after running the script without admin permissions:

import subprocess
subprocess.call(["sudo", "hcitool", "hci0", "up"]);

You should seperate each parameter like shown above. The result that is being executed will be: 'sudo hcitool hci0 up'.

S. Kerdel
  • 90
  • 1
  • 9
  • 1
    ... unless you have "whitelisted" the particular executed command inside the `sudoers` file for the particular sudoer and used `NOPASSWD`. Yes, you can have very fine-grained `sudoers`. The man page really helps in this case. – 0xC0000022L Jan 27 '16 at 08:56
  • @ProjectHardcore .. thanks for the reply, sorry for not making my question clear, I want to automate the whole process that is execute all the commands without manual intervention. – sans0909 Jan 27 '16 at 09:10
  • 1
    In that case I think the following page will do what @0xC0000022L mentioned and is what you need: [link](http://askubuntu.com/questions/39281/how-to-run-an-application-using-sudo-without-a-password) You should add the python script to your 'sudo visudo' file. – S. Kerdel Jan 27 '16 at 09:14
  • @sanyesh have you tried the link I've mentioned above? It should solve your problem as it automates the process where you was asking for in the comments on your question. – S. Kerdel Jan 27 '16 at 09:47
  • @ProjectHardcore I did try to add the line username ALL=(ALL) NOPASSWD: /home/username/some_file below %sudo ALL=(ALL:ALL) ALL..... where username is my username and some_file is a .sh file which contains all the above commands. Now I go to python and execute os.system('sudo /home/username/some_file') it still asks for sudo password, what should i do now? – sans0909 Jan 27 '16 at 10:14
  • Since you added the script to that path I think you don't need sudo in the os.system call anymore, but you should use subprocess (look at @tripleee's response). Try removing the sudo from the command, and I guess it will work as it should. – S. Kerdel Jan 27 '16 at 10:20
0

You can use pexpect to solve your problem. With this python module you can spawn a root shell, send the root password to the process and then execute multiple commands afterwards.

pexpect is a nice trick to automate any kind of interactive shell program ... It works fine in this example - but storing a root PW in a script like this has serious security implications (adding a user to sudoers without a password has serious security implications as well) ...

import pexpect, sys

# spawn a root shell with sudo or su depending on your linux
proc = pexpect.spawn("su")
proc.logfile = sys.stdout

# wait until the programm finds the string Password or password
# in the shell output
proc.expect("[Pp]assword")
# then: send the password to the waiting shell
proc.sendline("yourRootPW123")

# wait until the command completed ("#" is part of the next prompt)
proc.expect("#")
# run the whoami command
proc.sendline("whoami")

# wait for next prompt
proc.expect("#")
proc.sendline("ls -al")
proc.expect("#")
# ...

This will output:

myuser@lnx-work:~$ python script
[sudo] password for myuser: **************

root@lnx-work:~# whoami
whoami
root
root@lnx-work:~# ls -al
ls -al
total 60
drwx------  5 root root  4096 Dez 18 14:38 .
drwxr-xr-x 23 root root  4096 Jan 21 14:18 ..
-rw-------  1 root root 13149 Jan 27 10:19 .bash_history
-rw-r--r--  1 root root  3106 Feb 20  2014 .bashrc
...

You can read more on this here: automate with python pexpect

  • This will "work" but having the password in your script like this is a really bad idea. – augurar Jan 27 '16 at 22:19
  • @augurar - you are right - somehow. Hardcoding passwords is mostly a bad idea. Adding users to "sudoers" without password can be bad as well. The problem in automation is: you can hide, encrypt, outsource your password 100s of times - at one point you have to know/store a valid plaintext secret - so you can automate the whole thing. I recommend using https://www.vaultproject.io/ for "secrets management" in enterprise environments. Here the user wanted to know " ... how to give password via python then later execute the above commands ..." This is the answer. Didn't say it's secure ... –  Jan 28 '16 at 11:14
-1

According to this you should use external commands like this:

from subprocess import call
call(["ls", "-l"])

or

os.system("ls -l")

if your command is ls -l.

(For the super user privilege, i recommend you start python as a super user.)

EDIT: You can run from subprocess import call call(["sudo", "hciconfig", "hci0", "up"]) if you want to run a sub process (hciconfig hci0 up) as a superuser.

You have to also use NOPASSWD:

sudo visudo

And change a with your username ALL=(ALL) NOPASSWD: ALL

I however recommend you run a whole script as a super user, and just use a "normal" subprocess call in the script. You probably don't want to have no pass super user access. If your script doesn't do anything really nasty, it's safer to run script as superuser.

Community
  • 1
  • 1
ursusd8
  • 227
  • 2
  • 7
  • Doesn't answer question, which is how to run commands as the superuser within the script. – augurar Jan 27 '16 at 08:46
  • ok, i'm editing the answer to make it more understandable You can call any type of subprocess, even as superuser. I just recomend to run a whole script as a superuser so you don't have to use NOPASSWD, which can be less save as running a single script as sudo. – ursusd8 Jan 27 '16 at 10:26