我已经设置了 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
在 samba AD DC 上执行时ldbsearch -H /var/lib/samba/private/sam.ldb '(cn=testuser)' unicodePwd
,我得到以下结果:
# 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 消息不起作用(完全符合unicodePwd
Active Directory 的规范)?ldapsearch -D -w
smbpasswd 是否也会更新通过或 .net进行身份验证时使用的其他内容LdapConnection
?
您需要通过 指定帐户选项
userAccountControl
。它是一个位掩码(在 MS 中有记录),NORMAL_ACCOUNT 标志至少应具有 512。如果不指定,则默认为546
whichmeansACCOUNT_DISABLED | PASSWD_NOTREQD | NORMAL_ACCOUNT
。AD从不存储明文密码;unicodePwd 是一个神奇的属性,它具有服务器端处理功能,可将密码转换为 NT 哈希(加上存储在另一个属性中的 Kerberos AES 密钥)。