Cli*_*ore 3 password mac-osx-server opendirectory
我理解 Open Directory 是 OpenLDAP + SASL(密码服务器)+ Kerberos。OpenLDAP 似乎遵循 SASL 进行身份验证;我不知道 Kerberos。
我想通过脚本更改用户密码,最好是远程更改,并且我希望正确更改密码。(即,在任何情况下,我都不希望用户根据进入 Open Directory 的三个服务中的哪一个进行身份验证而拥有不同的密码。)
我可以dsimport在未绑定到目录的机器上通过网络执行一个很好的操作,但是,当您尝试导入密码时(尽管将 AuthType 设置为 dsAuthMethodStandard:dsAuthClearText),它仅在未输入密码时才有效之前设置。(我相信可以设置 Crypt 密码,但我担心这意味着只有 OD 的 LDAP 部分会知道当前密码。)
除了启动到服务器的 ssh 会话并更改那里的密码之外,我还能做些什么吗?如果我这样做,是否有任何命令可以让我在一行中指定多个用户及其新密码?
哪些命令可以更改所有打开的目录密码,有没有人更喜欢?
apropos password 给了我这些有趣的结果:
我会查看一些手册页,我认为这pwpolicy是最好的选择,但我很想知道使用这些页面是否有任何微妙之处(例如,不要更改 Kerberos 密码而不更改 LDAP 和 SASL 密码),并且如果其中任何一个在没有 ssh 会话的情况下远程工作。
我遇到的最方便的答案是将 passwd 命令与 dscl 结合使用。这是交互式会话的输出(密码替换为星号):
$ dscl -u diradmin -p ces
Password:
> cd /LDAPv3/127.0.0.1/
/LDAPv3/127.0.0.1 > auth diradmin *****
/LDAPv3/127.0.0.1 > passwd Users/Atwo807 *****
/LDAPv3/127.0.0.1 > passwd Users/Atwo249 *****
/LDAPv3/127.0.0.1 > passwd Users/doesnotexist foobar
passwd: Invalid Path
<dscl_cmd> DS Error: -14009 (eDSUnknownNodeName)
/LDAPv3/127.0.0.1 > exit
Goodbye
Run Code Online (Sandbox Code Playgroud)
这是一个进行更改的python脚本。您将需要 pexpect 模块(sudo easy_install pexpect应该为您获取它;我认为您不需要安装开发工具)。
#!/usr/bin/env python
import pexpect
def ChangePasswords(host, path, diradmin, diradmin_password, user_passwords, record_type='Users'):
"""Changes passwords in a Open Directory or similar directory service.
host = the dns name or IP of the computer hosting the directory
path = the pathname to the directory (ex. '/LDAPv3/127.0.0.1')
diradmin = the directory administrator's shortname (ex. 'diradmin')
diradmin_password = the directory administrator's password
user_passwords = a dictionary mapping record names (typically, user's short
names) onto their new password
record_type = the sort of records you are updating. Typically 'Users'
Returns a tuple. The first entry is a list of all records (users) who
failed to update. The second entry is a list of all records (users)
who successfully updated.
"""
failed_list = []
succeeded_list = []
prompt = " > "
child = pexpect.spawn("dscl -u %s -p %s" % (diradmin, host))
if not (ReplyOnGoodResult(child, "Password:", diradmin_password) and
ReplyOnGoodResult(child, prompt, "cd %s" % path) and
ReplyOnGoodResult(child, prompt,
"auth %s %s" % (diradmin, diradmin_password)) and
ReplyOnGoodResult(child, prompt, None)):
print "Failed to log in and authenticate"
failed_list = user_passwords.keys()
return (failed_list, succeeded_list)
# We are now logged in, and have a prompt waiting for us
expected_list = [ pexpect.EOF, pexpect.TIMEOUT,
'(?i)error', 'Invalid Path', prompt ]
desired_index = len(expected_list) - 1
for record_name in user_passwords:
#print "Updating password for %s" % record_name,
child.sendline("passwd %s/%s %s" % (record_type, record_name,
user_passwords[record_name]))
if child.expect(expected_list) == desired_index:
#print ": Succeeded"
succeeded_list.append(record_name)
else:
#print ": Failed"
failed_list.append(record_name)
child.expect(prompt)
child.sendline("exit")
child.expect(pexpect.EOF)
return (failed_list, succeeded_list)
def ReplyOnGoodResult(child, desired, reply):
"""Helps analyze the results as we try to set passwords.
child = a pexpect child process
desired = The value we hope to see
reply = text to send if we get the desired result (or None for no reply)
If we do get the desired result, we send the reply and return true.
If not, we return false."""
expectations = [ pexpect.EOF, pexpect.TIMEOUT, '(?i)error', desired ]
desired_index = len(expectations) - 1
index = child.expect(expectations)
if index == desired_index:
if reply:
child.sendline(reply)
return True
else:
return False
Run Code Online (Sandbox Code Playgroud)
您可以按如下方式使用它:
# This example assumes that you have named the script given above 'pwchange.py'
# and that it is in the current working directory
import pwchange
(failed, succeeded) = pwchange.ChangePasswords("ces", "/LDAPv3/127.0.0.1",
"diradmin", "******",
{ 'Atwo807' : '*****', 'Atwo249' : '*****',
'Nonexist' : 'foobar', 'Bad' : 'bad' })
print failed, succeeded
['Bad', 'Nonexist'] ['Atwo249', 'Atwo807']
Run Code Online (Sandbox Code Playgroud)