【发布时间】:2015-06-03 17:54:10
【问题描述】:
在我的组织中,我们有许多运行 OS X Yosemite 的 Mac。每台机器都有一个默认帐户,我们的 IT 团队可以使用该帐户访问机器以提供 IT 帮助。我们希望定期更改此帐户的密码,并且随着组织中 mac 数量的增长,我们希望找到一种方法来自动执行此任务。
我已经使用pexpect 编写了一个 Python 脚本,它将 SSH 进入每台机器并执行 dscl 以更改登录密码,然后 SSH 进入每台机器以运行 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,并且笔记本电脑上的密码更改.
海森堡。
在pexpect 调用周围插入打印语句有时也会导致方法成功。
我已经尝试过pexepect 的delaybeforesend 属性,它在sendline 将其有效负载发送到子进程之前添加了延迟,认为调试器中的时间延迟可能是问题所在,但这并没有解决问题。
有人知道我接下来会去哪里吗?我的一些同事怀疑这可能是tty 问题。有谁知道pdb 可能如何影响环境并导致这些命令成功,或者 OS X 导致它们失败的原因是什么?
【问题讨论】:
-
您是否尝试过使用
ssh -t? -
我刚试过-ttt。没有骰子
标签: python ssh osx-yosemite pexpect dscl