我使用以下C#代码通过DirectoryEntry类设置用户密码:
user.Invoke("SetPassword", password);
代码包含在DLL中。加载DLL并在运行在GMSA下的服务中使用此代码需要60秒才能返回,尽管成功。但是,加载DLL并使用命令行可执行文件的代码可以正常工作--即使我使用psexec
在GMSA下运行命令行。
据报道,有几个类似的问题,我试图通过上面的测试来消除,例如访问端口464,或不同机制下的SetPassword函数。
为什么在SetPassword上调用DirectoryEntry需要60秒才能成功?或者,我可以做什么调试来确定为什么会发生这种情况?
发布于 2021-12-10 14:28:02
在文档中,它列出了几种试图设置密码的机制,因为您需要一个安全的连接。我猜第一个没有起作用,所以它必须尝试2甚至全部三种。
用于创建user
的LDAP字符串可以确定SetPassword
需要运行多少圈才能找到可接受的安全方法。从另一台计算机运行也会产生不同的机制,这取决于防火墙限制,或者如果其中一台计算机没有连接到相同的域,而另一台计算机是。
SetPassword
不是设置密码的唯一方法。您可以通过直接设置unicodePwd
属性来做到这一点,这是文献资料描述的非常具体的方式。在C#中如下所示:
user.Properties["unicodePwd"].Value = Encoding.Unicode.GetBytes("\"NewPassword\"");
user.CommitChanges();
但你必须确保你是以安全的方式连接。这并没有像对待SetPassword
那样照顾你。您可以使用LDAPS (LDAP通过SSL),这要求服务器使用可信证书(注意端口636):
var user = new DirectoryEntry("LDAP://example.com:636/CN=SomePerson,OU=Users,DC=example,DC=com");
或者,如果您正在运行的计算机被连接到同一个域或受信任的域,则可以使用Kerberos,这是通过在构造函数中传递AuthenticationTypes.Sealing
来完成的:
var user = new DirectoryEntry("LDAP://CN=SomePerson,OU=Users,DC=example,DC=com"
, null, null, AuthenticationTypes.Secure | AuthenticationTypes.Sealing);
这是一种显式告诉它如何安全地连接的方法,而不是让SetPassword
尝试不同的方法,直到它找到一个。这样可以节省时间。
https://stackoverflow.com/questions/70298957
复制相似问题