Question:
I am trying to execute a cmd which reads from a PostgreSQL db. I am able to manually switch to root, then switch to the postgre user and access the information I desire.
The problem I have is that when I run this, it just hangs and nothing happens.
I have the root password and will need this when switching from the current user But I am not being prompted to enter it.
How can I get this not to hang and the password be prompted?
The code below only executes 'ls' for simplicity.
Code:
def popen_cmd_shell(command):
print command
process = subprocess.Popen(command,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
shell=True)
proc_stdout = process.communicate()[0].strip()
return proc_stdout
if __name__ == '__main__':
querylist = popen_cmd_shell('su - root; ls;')
print querylist
Update One:
I am unable to use any library that dose not come with python 2.7 on Linux SUSE. I just need to execute a command and exit.
Update Two:
I am unable to run the script as root as I need to perform other tasks which require me not to be root.
Update Three:
As per LeBarton suggestions I have got the script to log into root, although the the ls command never gets executed as root, it gets executed as the user I originally was. When I run the command I get prompted to enter the root password and get transfered from "@host" to "host" who cannot execute any command other than exit. When I exit all the commands executed output appears.
I do not wish to store the user password in the code as LeBarton has it. How can I execute a command as root and return back and continue the rest of the script, without getting locked into the new users and needing to type 'exit'.
The "stderr=subprocess.STDOUT" seems to have been what was causing it to hang.
Code:
if __name__ == '__main__':
def subprocess_cmd(command):
process = subprocess.Popen(command,stdout=subprocess.PIPE, shell=True)
proc_stdout = process.communicate()[0].strip()
print proc_stdout
subprocess_cmd('echo a; su - root; ls; cd;ls;')
...continue with rest of script where I execute commands as original user
Answer:
Thanks to tripleee for his excellent answer.
I Have achieved what I set out to do with the follwoing code:
if __name__ == '__main__':
def subprocess_cmd(command):
process = subprocess.Popen(command,stdout=subprocess.PIPE, shell=False)
proc_stdout = process.communicate()[0].strip()
print proc_stdout
subprocess_cmd(['su','-','root','-c','su -s /bin/sh postgres -c \'psql -U msa ..........])
I just needed to the place the command I was executing as root after -c. So it now switches to the postgres user and finds the data it needs from root returning to the normal user after.
You are misunderstanding what su does. su creates a privileged subprocess; it does not change the privileges of your current process. The commands after su will be executed after su finishes, with your normal privileges.
Instead, you want to pass a -c option to specify the commands you want to run with elevated privileges. (See also the su man page.)
popen_cmd_shell('su -c ls - root')
sudo was specifically designed to simplify this sort of thing, so you should probably be using that instead.
Scripted access to privileged commands is a sticky topic. One common approach is to have your command perform the privileged operation, then drop its privileges. Both from a security and a design point of view, this approach tends to simplify the overall logic. You need to make sure your privileged code is as simple and short as possible--no parsing in the privileged section, for example.
Once the privileged code is properly tested, audited, and frozen, bestowing the script with the required privileges should be a simple matter (although many organizations are paranoid, and basically unable to establish a workable policy for this sort of thing).
Regardless of which approach you take, you should definitely avoid anything with shell=True in any security-sensitive context, and instead pass any external commands as a list, not as a single string.
popen_cmd_shell(['su', '-c', 'ls', '-', 'root'])
(Maybe also rename the function, since you specifically do not want a shell. Obviously, also change the function to specify shell=False.)
Again, these security concerns hold whether you go with dropping privileges, or requesting privilege escalation via su or sudo.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With