I\'m having problems with changing a Linux user\'s password from python. I\'ve tried so many things, but I couldn\'t manage to solve the issue, here is the sample of things
I ran accross the same problem today and I wrote a simple wrapper around subprocess
to call the passwd
command and feed stdin
with the new password. This code is not fool proof and only works when running as root which does not prompt for the old password.
import subprocess
from time import sleep
PASSWD_CMD='/usr/bin/passwd'
def set_password(user, password):
cmd = [PASSWD_CMD, user]
p = subprocess.Popen(cmd, stdin=subprocess.PIPE)
p.stdin.write(u'%(p)s\n%(p)s\n' % { 'p': password })
p.stdin.flush()
# Give `passwd` cmd 1 second to finish and kill it otherwise.
for x in range(0, 10):
if p.poll() is not None:
break
sleep(0.1)
else:
p.terminate()
sleep(1)
p.kill()
raise RuntimeError('Setting password failed. '
'`passwd` process did not terminate.')
if p.returncode != 0:
raise RuntimeError('`passwd` failed: %d' % p.returncode)
If you need the output of passwd you can also pass stdout=subprocess.PIPE
to the Popen
call and read from it. In my case I was only interested if the operation succeeded or not so I simply skipped that part.
Security consideration: Do not use something like echo -n 'password\npassword\n | passwd username'
as this will make the password visible in the process list.
Since you seam to want to be using sudo passwd
I would recommend adding a new line to your /etc/sudoers
(use visudo
for that!)
some_user ALL = NOPASSWD: /usr/bin/passwd
Sudo will not ask for the password for some_user
and the script will run as expected.
Alternatively simply add an extra p.stdin.write(u'%s\n' % SUDO_PASSWORD)
line. That way sudo
will receive the user password first and then passwd
receives the new user password.