私の組織では、OS X Yosemite を実行している多くの Mac があります。これらの各マシンには、IT チームがマシンにアクセスして IT 支援を提供するために使用できるデフォルト アカウントがあります。このアカウントのパスワードを定期的に変更したいと考えており、組織内の Mac の数が増えるにつれて、このタスクを自動化する方法を見つけたいと考えています。
pexpect
各マシンにdscl
SSH でログイン パスワードを変更し、次に各マシンに 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
の属性を既に試しました。delaybeforesend
sendline
私が次にどこを見るか知っている人はいますか?私の同僚の何人かは、それが問題ではないかと疑っていtty
ます。環境にどのpdb
ように影響し、これらのコマンドが成功するか、OS X が失敗する原因を知っている人はいますか?