0

私の組織では、OS X Yosemite を実行している多くの Mac があります。これらの各マシンには、IT チームがマシンにアクセスして IT 支援を提供するために使用できるデフォルト アカウントがあります。このアカウントのパスワードを定期的に変更したいと考えており、組織内の Mac の数が増えるにつれて、このタスクを自動化する方法を見つけたいと考えています。

pexpect各マシンにdsclSSH でログイン パスワードを変更し、次に各マシンに SSHでログイン キーチェーン パスワードを変更する Python スクリプトを作成しましたsecurity

これらのメソッドは、古いパスワードと新しいパスワードがold_passwordおよびnew_password属性に格納されているクラスの一部です。

def _change_login_password(self, host):
    """Change the login password of a machine.

    Returns True on success, False on failure.
    """

    try:
        child = pexpect.spawn(
            "ssh default@{} dscl . passwd /Users/default".format(host))
        child.expect("Password:")
        child.sendline(self.old_password)
        child.expect("New Password: ")
        child.sendline(self.new_password)
        child.expect(
            "Permission denied. Please enter user's old password:")
        child.sendline(self.old_password)
        child.close()

        return not child.exitstatus

    except pexpect.TIMEOUT:
        return False

def _change_keychain_password(self, host, login_password):
    """Change the keychain password of a machine.

    Changes the keychain password to match the login password.

    Returns True on success, False on failure.
    """

    try:
        child = pexpect.spawn(
            "ssh default@{} security set-keychain-password"
            " login.keychain".format(host))
        child.expect("Password:")
        child.sendline(login_password)
        child.expect("Old Password: ")
        child.sendline(self.old_password)
        child.expect("New Password: ")
        child.sendline(login_password)
        child.expect("Retype New Password: ")
        child.sendline(login_password)
        child.close()

        return not child.exitstatus

    except pexpect.TIMEOUT:
        return False

これらの方法はどちらも、私の OS X Yosemite 仕事用ラップトップに対するテストで失敗します。ssh 経由で実行される各コマンドはゼロ以外の終了ステータスを返し、ラップトップのパスワードは変更されません。

...しかし、pdbいずれかのメソッドの先頭にブレークポイントを挿入し、変更を加えずにデバッガーでメソッドをステップ実行すると、終了ステータスが 0 になり、ラップトップのパスワードが変更されます。

ハイゼンバグ。

呼び出しの周りに print ステートメントを挿入するpexpectと、メソッドが成功する場合もあります。

ペイロードを子プロセスに送信する前に遅延を追加するpexepectの属性を既に試しました。delaybeforesendsendline

私が次にどこを見るか知っている人はいますか?私の同僚の何人かは、それが問題ではないかと疑っていttyます。環境にどのpdbように影響し、これらのコマンドが成功するか、OS X が失敗する原因を知っている人はいますか?

4

1 に答える 1

0

ああ、ここに何かがあります。詳しく調べてみると、両方のプロセスがステータス コード 130 で終了していました。これは Ctrl+C に対応しています。expect(pexpect.EOF)の前に両方のメソッドにを追加する必要があっcloseたため、シャットダウンされる前に終了する機会がありました。

def _change_login_password(self, host):
    """Change the login password of a machine.

    Returns True on success, False on failure.
    """

    try:
        child = pexpect.spawn(
            "ssh -ttt default@{} dscl . passwd /Users/default".format(host))
        child.expect("Password:")
        child.sendline(self.old_password)
        child.expect("New Password: ")
        child.sendline(self.new_password)
        child.expect(
            "Permission denied. Please enter user's old password:")
        child.sendline(self.old_password)
        child.expect(pexpect.EOF)  # Wait for EOF.
        child.close()

        return not child.exitstatus

    except pexpect.TIMEOUT:
        return False

    def _change_keychain_password(self, host, login_password):
    """Change the keychain password of a machine.

    Changes the keychain password to match the login password.

    Returns True on success, False on failure.
    """

    try:
        child = pexpect.spawn(
            "ssh -ttt default@{} security set-keychain-password"
            " login.keychain".format(host))
        child.expect("Password:")
        child.sendline(login_password)
        child.expect("Old Password: ")
        child.sendline(self.old_password)
        child.expect("New Password: ")
        child.sendline(login_password)
        child.expect("Retype New Password: ")
        child.sendline(login_password)
        child.expect(pexpect.EOF)  # Wait for EOF.
        child.close()

        return not child.exitstatus

    except pexpect.TIMEOUT:
        return False

また、robertklep が提案したように、使用しましたssh -t(実際にssh -tttは、その tty を取得するのに苦労しました)。これらの両方を組み合わせることで問題が解決し、現在は ssh 経由でパスワードを喜んで変更しています。

于 2015-06-03T19:11:28.517 に答える