![Samba4 用户密码无法通过 LDAP 消息正确更新,只能通过 smbpasswd 更新](https://linux22.com/image/793288/Samba4%20%E7%94%A8%E6%88%B7%E5%AF%86%E7%A0%81%E6%97%A0%E6%B3%95%E9%80%9A%E8%BF%87%20LDAP%20%E6%B6%88%E6%81%AF%E6%AD%A3%E7%A1%AE%E6%9B%B4%E6%96%B0%EF%BC%8C%E5%8F%AA%E8%83%BD%E9%80%9A%E8%BF%87%20smbpasswd%20%E6%9B%B4%E6%96%B0.png)
我已经设置了 Samba4 AD DC,并且可以Administrator
通过 .net 代码成功地对我的用户进行身份验证:
var directoryIdentifier = new LdapDirectoryIdentifier("127.0.0.1", 636);
var credentials = new NetworkCredential($"CN=Administrator,CN=Users,DC=ldap,DC=test,DC=dev", "admin1234!");
using(var connection = new LdapConnection(directoryIdentifier, credentials))
{
try
{
connection.SessionOptions.ProtocolVersion = 3;
connection.SessionOptions.SecureSocketLayer = true;
connection.SessionOptions.ReferralChasing = ReferralChasingOptions.None;
connection.AuthType = AuthType.Basic;
connection.Bind(credentials);
}
}
然后通过此连接创建一个新用户:
var addRequest = new AddRequest(
"CN=testuser,CN=Users,DC=ldap,DC=test,DC=dev",
new DirectoryAttribute("objectClass", new object[] { "user" }),
new DirectoryAttribute("cn", "testuser"),
new DirectoryAttribute("uid", "testuser"),
new DirectoryAttribute("sAMAccountName", "testuser"),
new DirectoryAttribute("unicodePwd", Encoding.Unicode.GetBytes($@"""pw1234!"""))
);
var addResponse = connection.SendRequest(addRequest);
Console.WriteLine($"[ADD] response: {addResponse.ErrorMessage}");
或者从终端执行相同操作:
ldapadd -H LDAPS://127.0.0.1:636 -D "CN=Administrator,CN=Users,DC=ldap,DC=test,DC=dev" -w admin1234!
dn: CN=testuser,CN=Users,DC=ldap,DC=test,DC=dev
objectClass: user
cn: testuser
uid: testuser
unicodePwd:: IgBwAHcAMQAyADMANAAhACIA
sAMAccountName: testUser
我从哪里获得了unicodePwd echo -n "\"pw1234\!\"" | iconv -f UTF-8 -t UTF-16LE | base64
。
但是,当尝试向该用户进行身份验证时:
var testUser_directoryIdentifier = new LdapDirectoryIdentifier("127.0.0.1", 636);
var testUser_credentials = new NetworkCredential($"CN=testuser,CN=Users,DC=ldap,DC=test,DC=dev", "pw1234!");
using(var connection = new LdapConnection(testUser_directoryIdentifier, testUser_credentials))
{
try
{
connection.SessionOptions.ProtocolVersion = 3;
connection.SessionOptions.SecureSocketLayer = true;
connection.SessionOptions.ReferralChasing = ReferralChasingOptions.None;
connection.AuthType = AuthType.Basic;
connection.Bind(testUser_credentials);
}
}
我收到错误:
提供的凭证无效。[错误代码 49]
同样,对于终端命令
ldapwhoami -vvv -H ldaps://127.0.0.1:636 -D "CN=testuser,CN=Users,DC=ldap,DC=test,DC=dev" -x -w pw1234\!
我明白了
ldap_bind:无效凭据(49)附加信息:80090308:LdapErr:DSID-0C0903A9,评论:AcceptSecurityContext 错误,数据 533,v1db1
ldbsearch -H /var/lib/samba/private/sam.ldb '(cn=testuser)' unicodePwd
在 samba AD DC 上执行时,我得到了以下信息:
# record 1
dn: CN=testuser,CN=Users,DC=ldap,DC=test,DC=dev
unicodePwd:: 0pQq91kmGPJQOuQ3oiHPgg==
[...]
(附带问题,0pQq91kmGPJQOuQ3oiHPgg==
与我传入的不相等,IgBwAHcAMQAyADMANAAhACIA
不知道为什么。但似乎不相关。)
但是,当我使用该smbpasswd
工具并设置相同的密码时,它似乎有效:
smbpasswd testuser
我可以通过再次执行ldbsearch -H /var/lib/samba/private/sam.ldb '(cn=testuser)' unicodePwd
并接收相同的记录来确认这一点。
这次,相同的 bash 脚本起作用了:
ldapwhoami -vvv -H ldaps://127.0.0.1:636 -D "CN=testuser,CN=Users,DC=ldap,DC=test,DC=dev" -x -w pw1234\!
ldap_initialize( ldaps://127.0.0.1:636/??base )
u:DEV-AD\testUser
Result: Success (0)
为什么简单的 LDAP 消息不起作用(完全符合Active Directory 的规范)? smbpasswd 是否也更新了通过或 .netunicodePwd
进行身份验证时使用的其他内容?ldapsearch -D -w
LdapConnection
答案1
您需要通过 指定帐户选项userAccountControl
。这是一个位掩码(记录在 MS),其中 NORMAL_ACCOUNT 标志至少应为 512。如果您未指定,则默认546
为ACCOUNT_DISABLED | PASSWD_NOTREQD | NORMAL_ACCOUNT
。
(附带问题,
0pQq91kmGPJQOuQ3oiHPgg==
与我传入的不相等,IgBwAHcAMQAyADMANAAhACIA
不知道为什么。但似乎不相关。)
AD 从不存储纯文本密码;unicodePwd 是一个神奇的属性,它具有服务器端处理功能,可将密码转换为 NT 哈希(加上存储在另一个属性中的 Kerberos AES 密钥)。