4

Linux ユーザーのパスワードを Python から変更する際に問題が発生しています。私は非常に多くのことを試しましたが、問題を解決することができませんでした.これは私がすでに試したことのサンプルです:

sudo_password は sudo のパスワード、sudo_command はシステムに実行させるコマンド、user はリストから取得し、パスワードを変更するユーザー、newpass は「ユーザー」に割り当てたいパスです。

    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」をハッシュし、「newpassencryp」を置き換えると、0 が返されます。これは理論的には正しく行われたことを意味しますが、これまでのところパスワードは変更されていません。

この問題または類似の問題をインターネットとスタックオーバーフローで検索し、公開されたソリューションを試しましたが、成功しませんでした。

もちろん、さらに情報が必要な場合は、喜んで提供します。

前もって感謝します。

4

6 に答える 6

4

passwdこれを実行しているユーザーには、パスワードなしでコマンドを実行するための sudo 権限が必要です。

>>> from subprocess import Popen
>>> proc = Popen(['/usr/bin/sudo', '/usr/bin/passwd', 'test', '--stdin'])
>>> proc.communicate('newpassword')
于 2012-11-01T20:28:23.170 に答える
3

パイプの passwd コマンドに「--stdin」オプションを使用してみてください。マニュアルページから引用するには:

    --標準入力
      このオプションは、passwd が新しいパスワードを読み取る必要があることを示すために使用されます。
      標準入力からのパスワード。これはパイプにすることができます。

別のオプションとして、Linux に usermod コマンドがある場合、root として (または sudo 経由で)、「-p」オプションを使用して (暗号化された) パスワードを明示的に設定できます。

于 2012-11-01T16:52:08.663 に答える
2

私は今日同じ問題に遭遇し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.PIPEPopen呼び出しに渡して読み取ることもできます。私の場合、操作が成功したかどうかにのみ関心があったので、その部分はスキップしました。

セキュリティ上の考慮事項:このようなものは使用しないでくださいecho -n 'password\npassword\n | passwd username'。パスワードがプロセス リストに表示されるためです。

須藤

あなたは使いたいと思っているので、あなた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受け取り、次に新しいユーザー パスワードを受け取ります。

于 2013-07-21T14:28:55.850 に答える
1

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
于 2012-11-02T10:59:35.373 に答える