Python-Change another user's password - python

So, using Python and os.system, how would I change another user's password?
I know using the command passwd doesn't work.
I was able (I think) to create a user with a password, using -p, but I do not know how to change a user's password through script.
Any help would be great.

Your best bet is likely to use subprocesses. Anything you can you on the shell you can put into a subprocess call. This isn't ideal for all admin tasks, but considering the task is not portable I don't know a suitable module.
This will run the "passwd test" command just like from the shell and feed in the password string for the two password prompts. The output is split into standard output and standard error by communicate().
from subprocess import Popen, PIPE
username = 'test'
password = 'qZt53h9b'
proc=Popen(['passwd', username],stdin=PIPE,stdout=PIPE,stderr=PIPE)
proc.stdin.write(password + '\n')
proc.stdin.write(password)
proc.stdin.flush()
stdout,stderr = proc.communicate()
print(stdout)
print(stderr)
Don't forget you will get a permissions error trying to change another user's password when not root or as a sudoer.

Related

How do I Interactively Retrieve Child Subprocess Output and Send Input using Popen?

Sorry in advance, I've tried searching through similar questions, but I've come to a dead-end. I've figured out a way around this issue, but I still want to figure out how to use the subprocess module effectively.
I'm writing a Python function that interacts with VMWare's OVFtool.exe (Windows environment) via the subprocess module using Popen to export an OVA file from VSphere. I've made it to the point where I can see and interact with the username and password prompts from the OVFTool.
When I run the below code, it shows me the prompt from the ovftool.exe for the username, and I write the username to stdint and flush, and then I see the prompt for the password. I input the password write it to stdin and it then flushes stdin but then it just stalls on the last proc.stdout.readline(4) with no errors or output. I'm just using a test username/password for now, and it should give me the username and password prompts again, but it seems to just hang on that readline function. My thought is maybe the ovftool process is spawning another process or maybe I'm misunderstanding how to buffer and submit input via stdin (likely)?
I've changed around the buffer amount, I've tried subprocess with and without the universal_new_lines, bufsize=1, and shell=True arguments. What I ended up doing as a workaround is I pass the username and password via the command-line argument for ovftool.exe. Still, I'd like to know what I am doing wrong because I'd like to be able to capture the output in real-time using Popen and interact with it as needed.
Thank you in advance for your help.
def export_extract_ova_file():
vm_name = input("What is the name of the vm you are exporting?")
print(f"Exporting {vm_name} from VSphere.")
with subprocess.Popen(f"\"{ovf_tool_path}\" vi://example_ip/{vm_name}"
f"./{vm_name}.ova", text=True,
stdin=subprocess.PIPE, stdout=subprocess.PIPE,
stderr=subprocess.STDOUT, shell=True) as proc:
proc_read = proc.stdout.readline()
print(proc_read)
proc_read = proc.stdout.readline(10)
print(proc_read)
input("Please enter your username")
proc.stdin.write(username + "\n")
proc.stdin.flush()
proc_read = proc.stdout.readline(10)
print(proc_read)
password = input("Please enter your password")
proc.stdin.write(password + "\n")
proc.stdin.flush()
proc.stdout.flush()
sleep(1.0)
proc_read = proc.stdout.readline(4)
print(proc_read)

When using a subprocess.Popen(command), would a password be exposed in a terminal log in any way?

I need to execute a command multiple times which, when executed, asks for a password. However, the password could also be specified as a variable through "--cpass ".
I would like to use the module getpass to first get the password securely and then execute the command (multiple times) similar to:
import getpass
import subprocess
password = getpass.getpass(prompt="Password: ", stream=None)
# later in a for-loop context:
....
subprocess.Popen([command, "--cpass", password],
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
....
Will this approach "leak" or store the password in plain text in some terminal log somewhere? and if so, what could be a better approach?
(not providing the password through "--cpass " would result in a password-prompt for every command execution which would be very cumbersome for the user...)
According to docs:
Security Considerations
Unlike some other popen functions, this implementation will never implicitly call a system shell. This means that all characters, including shell metacharacters, can safely be passed to child processes.
This part clearly claims that everything can be "passed safely", so that would include plaintext passwords.
If someone is still not convinced, password can be probably passed through normal communication with the process.

python ssh password prompt

I am trying to get automatic password passing upon prompt while using ssh.
normally, rsa keys are used to prevent password prompt but I can't guarantee every user is set up properly so i want the script to automatically set the password if given by the user
Here is the
ssh = subprocess.Popen(["ssh", "localhost", "python -c 'print \"I am running\"' "], shell=False,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
>>> Password:
My tried solution was
import sys, subprocess
class GetPass():
def __init__(self, password):
self.password=str(password)
def readline(self):
return self.password
sys.stdin = GetPass('mypassword')
# test raw_input 3 time to verify
raw_input()
>> 'mypassword'
raw_input()
>> 'mypassword'
raw_input()
>> 'mypassword'
# Now try sshing again
ssh = subprocess.Popen(["ssh", "localhost", "python -c 'print \"I am running\"' "], shell=False,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
>>> Password:
This is not working as requesting password is still prompted.
The idea is that GetPass replacing sys.stdin will always return the desired password automatically without the user typing it himself.
any idea or solution ?
SSH reads the password from the terminal, not from stdin, so there's no way you can provide a synthetic (not prompted) password using subprocess.Popen.
I understand not wanting to lade your application with dependencies, but I also would recommend paramiko for this. Without that, you're looking at using a workflow manager like pyexpect for fabric anyway, unless you implement the whole workflow yourself using a pseudoterminal. You can do that without introducing dependencies, but frankly it's not worth the extra surface area for bugs or behavior divergence.
Still, if you want to try it, here's a gist that outlines an approach. You could simplify this quite a lot but it gets the essentials across.

Using python to open cmd and automatically enter a password

I've managed to get the cmd being opened by python. However, using runas administrator comes with a password check before cmd.exe is executed.
I'm using this to open cmd...
import subprocess
subprocess.call(["runas", "/user:Administrator", "cmd.exe"])
I'm looking for a way to automatically enter the password into the runas.exe prompt which opens when i run the code. Say if i were to create var = "test" and add it after import subprocess how would i make it so that this variable is passed to and seen as an input to the runas.exe?
The solution would require only python modules which are in version 3.4 or higher.
Update
I have found some code which appears to input straight into runas.exe. However, the apparent input is \x00\r\n when in the code the input is supposed to be test I am fairly certain that if i can get the input to be test then the code will be successful.
The code is as follows :
import subprocess
args = ['runas', '/user:Administrator', 'cmd.exe']
proc = subprocess.Popen(args,
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
proc.stdin.write(b'test\n')
proc.stdin.flush()
stdout, stderr = proc.communicate()
print (stdout)
print (stderr)
Although not an answer to your question, this can be a solution to your problem. Use psexec instead of runas. You can run it like this:
psexec -u user -p password cmd
(or run it from Python using subprocess.Popen or something else)
This piece of code actually works (tested on a Windows 2008 server). I've used it to call runas for a different user and pass his password. A new command prompt opened with new user context, without needing to enter password.
Note that you have to install pywin32 to have access to the win32 API.
The idea is:
to Popen the runas command, without any input redirection, redirecting output
read char by char until we encounter ":" (last char of the password prompt).
send key events to the console using win32 packages, with the final \r to end the password input.
(adapted from this code):
import win32console, win32con, time
import subprocess
username = "me"
domain = "my_domain"
password ="xxx"
free_console=True
try:
win32console.AllocConsole()
except win32console.error as exc:
if exc.winerror!=5:
raise
## only free console if one was created successfully
free_console=False
stdin=win32console.GetStdHandle(win32console.STD_INPUT_HANDLE)
p = subprocess.Popen(["runas",r"/user:{}\{}".format(domain,username),"cmd.exe"],stdout=subprocess.PIPE)
while True:
if p.stdout.read(1)==b":":
for c in "{}\r".format(password): # end by CR to send "RETURN"
## write some records to the input queue
x=win32console.PyINPUT_RECORDType(win32console.KEY_EVENT)
x.Char=unicode(c) # remove unicode for python 3
x.KeyDown=True
x.RepeatCount=1
x.VirtualKeyCode=0x0
x.ControlKeyState=win32con.SHIFT_PRESSED
stdin.WriteConsoleInput([x])
p.wait()
break

Make python enter password when running a csh script

I'm writing a python script that executes a csh script in Solaris 10. The csh script prompts the user for the root password (which I know) but I'm not sure how to make the python script answer the prompt with the password. Is this possible? Here is what I'm using to execute the csh script:
import commands
commands.getoutput('server stop')
Have a look at the pexpect module. It is designed to deal with interactive programs, which seems to be your case.
Oh, and remember that hard-encoding root's password in a shell or python script is potentially a security hole :D
Use subprocess. Call Popen() to create your process and use communicate() to send it text. Sorry, forgot to include the PIPE..
from subprocess import Popen, PIPE
proc = Popen(['server', 'stop'], stdin=PIPE)
proc.communicate('password')
You would do better do avoid the password and try a scheme like sudo and sudoers. Pexpect, mentioned elsewhere, is not part of the standard library.
import pexpect
child = pexpect.spawn('server stop')
child.expect_exact('Password:')
child.sendline('password')
print "Stopping the servers..."
index = child.expect_exact(['Server processes successfully stopped.', 'Server is not running...'], 60)
child.expect(pexpect.EOF)
Did the trick! Pexpect rules!
Add input= in proc.communicate() make it run, for guys who like to use standard lib.
from subprocess import Popen, PIPE
proc = Popen(['server', 'stop'], stdin=PIPE)
proc.communicate(input='password')
Should be able to pass it as a parameter. something like:
commands.getoutput('server stop -p password')
This seems to work better:
import popen2
(stdout, stdin) = popen2.popen2('server stop')
stdin.write("password")
But it's not 100% yet. Even though "password" is the correct password I'm still getting su: Sorry back from the csh script when it's trying to su to root.
To avoid having to answer the Password question in the python script I'm just going to run the script as root. This question is still unanswered but I guess I'll just do it this way for now.

Categories