如何从python更改Linux用户密码

我遇到了从python更改Linux用户密码的问题。 我已经尝试了很多东西,但是我无法解决这个问题,下面是我已经尝试过的一些例子:

sudo_password是sudo的密码,sudo_command是我希望系统运行的命令,user是从List中获取的,并且是我想要更改密码的用户,newpass是我想要分配给“user”

user = list.get(ANCHOR) sudo_command = 'passwd' f = open("passwordusu.tmp", "w") f.write("%s\n%s" % (newpass, newpass)) f.close() A=os.system('echo -e %s|sudo -S %s < %s %s' % (sudo_password, sudo_command,'passwordusu.tmp', user)) print A windowpass.destroy() 

'A'是执行os.system的返回值,在这里是256.我也试过

  A=os.system('echo %s|sudo -S %s < %s %s' % (sudo_password, sudo_command,'passwordusu.tmp', user)) 

但它返回相同的错误代码。 我用“passwd”命令尝试了其他几种方法,但没有成功。 用'chpasswd'命令我试过这个:

  user = list.get(ANCHOR) sudo_command = 'chpasswd' f = open("passwordusu.tmp", "w") f.write("%s:%s" % (user, newpass)) f.close() A=os.system('echo %s|sudo -S %s < %s %s' % (sudo_password, sudo_command,'passwordusu.tmp', user)) print A windowpass.destroy() 

还有:

  A=os.system('echo %s|sudo -S %s:%s|%s' % (sudo_password, user, newpass, sudo_command)) @;which returns 32512 A=os.system("echo %s | sudo -S %s < \"%s\"" % (sudo_password, sudo_command, "passwordusu.tmp")) @;which returns 256 

我也尝试了'mkpasswd'和'usermod':

  user = list.get(ANCHOR) sudo_command = 'mkpasswd -m sha-512' os.system("echo %s | sudo -S %s %s > passwd.tmp" % (sudo_password,sudo_command, newpass)) sudo_command="usermod -p" f = open('passwd.tmp', 'r') for line in f.readlines(): newpassencryp=line f.close() A=os.system("echo %s | sudo -S %s %s %s" % (sudo_password, sudo_command, newpassencryp, user)) @;which returns 32512 

但是,如果你去https://www.mkpasswd.net ,散列'newpass'并replace'newpassencryp',它返回0,理论上这意味着它已经正确,但到目前为止,它不会改变密码。

我已经search了互联网和这个问题或类似的计算器,并尝试了什么解决scheme暴露,但又一次,没有成功。

我真的会赞赏任何帮助,当然,如果你需要更多的信息,我会很乐意提供!

提前致谢。

Solutions Collecting From Web of "如何从python更改Linux用户密码"

尝试在管道中使用“–stdin”选项来执行passwd命令。 引用从手册页:

     --stdin
      这个选项用来表示passwd应该读新的
      来自标准输入的密码,可以是管道。

另一种选择是,如果你的Linux有usermod命令,作为root用户(或通过sudo),你可以使用'-p'选项明确地设置(加密的)密码。

基于usermod的版本:

 #!/usr/bin/env python from crypt import crypt from getpass import getpass from subprocess import Popen, PIPE sudo_password_callback = lambda: sudo_password # getpass("[sudo] password: ") username, username_newpassword = 'testaccount', '$2&J|5ty)*X?9+KqODA)7' # passwd has no `--stdin` on my system, so `usermod` is used instead # hash password for `usermod` try: hashed = crypt(username_newpassword) # use the strongest available method except TypeError: # Python < 3.3 p = Popen(["mkpasswd", "-m", "sha-512", "-s"], stdin=PIPE, stdout=PIPE, universal_newlines=True) hashed = p.communicate(username_newpassword)[0][:-1] # chop '\n' assert p.wait() == 0 assert hashed == crypt(username_newpassword, hashed) # change password p = Popen(['sudo', '-S', # read sudo password from the pipe # XXX: hashed is visible to other users 'usermod', '-p', hashed, username], stdin=PIPE, universal_newlines=True) p.communicate(sudo_password_callback() + '\n') assert p.wait() == 0 

我今天跑了相同的问题,我写了一个简单的包装subprocess调用passwd命令,并提供新的密码stdin 。 这个代码不是简单的,只有以root身份运行时才会起作用。

 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) 

如果您需要passwd的输出,您还可以将stdout=subprocess.PIPE传递给Popen调用并从中读取。 在我的情况下,我只是在操作成功或没有兴趣,所以我只是略过了这部分。

安全考虑:不要使用类似echo -n 'password\npassword\n | passwd username' echo -n 'password\npassword\n | passwd username'因为这将使密码在进程列表中可见。

SUDO

因为你想要使用sudo passwd <username>来接缝,所以我建议在你的/etc/sudoers添加一个新行(使用visudo !)

 some_user ALL = NOPASSWD: /usr/bin/passwd 

Sudo不会要求输入some_user的密码,脚本将按预期运行。

或者只需添加一个额外的p.stdin.write(u'%s\n' % SUDO_PASSWORD)行。 这样sudo会先收到用户密码,然后passwd收到新的用户密码。

您正在运行的用户必须具有sudo权限才能运行passwd命令而不使用密码。

 >>> from subprocess import Popen >>> proc = Popen(['/usr/bin/sudo', '/usr/bin/passwd', 'test', '--stdin']) >>> proc.communicate('newpassword')