Kerberos密码更改协议



我正试图使用RFC 3244中的Kerberos密码协议,从C++/CLI库(将由另一个服务调用)对ActiveDirectory中的用户执行许多密码操作。

我用C#(这是我的首选语言)模拟了一个序列,使用LogoUser模拟管理员,然后使用DirectoryServices.AccountManagement命名空间在用户条目上调用SetPassword。SetPassword使用三种方法尝试更改LDAPS、Kerberos和RPC。如果我查看Wireshark跟踪,我可以看到模拟管理员时的Kerberos握手,然后是LDAP尝试(由于缺乏SSL而失败),然后是Kerberos密码交换。

试图复制这一点是C++LogoUser不会启动Kerberos交换,因此当调用SetPassword时,该方法会失败到RPC(它成功了,但不满足我们使用Kerberos的要求)。

有没有一种方法可以强制使用Kerberos?

有没有更好的解决方案可以与.net中的Kerberos密码协议交互,而不是依赖SetPassword?

最小代码示例:

C#

SafeTokenHandle handle;
LogonUser("serviceAccount", "Test", "aPassw0rd", 2, 0, out handle);
WindowsIdentity.Impersonate(handle.DangerousGetHandle());
DirectoryEntry usr = new DirectoryEntry();
usr.Path = "LDAP://"+"dctest.test.com/"+"CN=testuser,CN=Users,DC=test,DC=com";
usr.AuthenticationType = AuthenticationTypes.Sealing | AuthenticationTypes.Secure;
object ret = usr.Invoke("SetPassword", "aPassw0rd");
usr.CommitChanges();
usr.Close();
Console.WriteLine("Completed");

这种方法成功地模拟了服务帐户,然后通过464使用KPASSWD执行设置密码。

C++/CLI

HANDLE _handle;
LogonUser(L"serviceAccount",L"Test",L"aPassw0rd",LOGON32_LOGON_INTERACTIVE,LOGON32_PROVIDER_DEFAULT,&_handle)
ImpersonateLoggedOnUser(_handle);
DirectoryEntry^ usr = gcnew DirectoryEntry();
usr->Path = "LDAP://"+"dctest.test.com/"+"CN=testuser,CN=Users,DC=test,DC=com";
usr->AuthenticationType = AuthenticationTypes::Sealing | AuthenticationTypes::Secure;
Object^ ret = usr->Invoke("SetPassword", "aPassw0rd");
usr->CommitChanges();
usr->Close();
Console::WriteLine("Completed");

这种方法模拟管理员帐户,然后当设置密码时调用kerberos交换(超过88,所以我猜这是auth),但随后又回到使用RPC。

如果我获取C#代码并从C++/CLI包装器调用它,则行为将更改为代码在C++中时显示的行为。

前几天通过一个反射器运行输出,终于追踪到了这一点。C++/CLI类的项目属性包括将字符集设置为unicode。使用此设置,输出将使用LogonUserW方法。但是,如果此设置更改为"未设置",则将使用LogoUser方法,并且setPassword的Kerberos身份验证路径将正常运行。

相关内容

最新更新