简体   繁体   English

LDAP 从域外重置密码。网络 C# 错误:RPC 服务器不可用。 (hresult 的异常:0x800706ba)

[英]LDAP reset password from outside the domain network C# Error: RPC server is unavailable. (exception from hresult: 0x800706ba)

We're trying to Reset LDAP password , its working on development environment but not working on production environment.我们正在尝试重置 LDAP 密码,它适用于开发环境,但不适用于生产环境。

Our development environment is inside the Domain and production environment is outside the Domain.我们的开发环境在域内,生产环境在域外。

In development to connect LDAP, we have used Domain name like abc.com and production environment we use IPaddress:389 , which is already working for LDAP User authentication in both environment.在连接 LDAP 的开发中,我们使用了像abc.com这样的域名,在生产环境中我们使用了 IP 地址IPaddress:389 ,它已经在两种环境中用于 LDAP用户身份验证 But not working for LDAP reset password .但不适用于LDAP 重置密码

Error: RPC server is unavailable. (exception from hresult: 0x800706ba)

Developement: (working)发展:(工作)

PrincipalContext principalContext =
    new PrincipalContext(ContextType.Domain, "<domain.com>", container: "<DC=domain,DC=com>",
    "<username>", "<password>");
UserPrincipal user = UserPrincipal.FindByIdentity(principalContext, "<LdapUserName>");
// "<username>", "<password>" are Administrative credential.
bool isValid = user.ValidateCredentials("<username>", "<password>");
_logger.Log($"Is Connection: {isValid}");
**// Output: Is Connection: True**
user.UserCannotChangePassword = false;
user.SetPassword("<NewPassword>");
// Password has been successfully reset.

Production: (working) Also we are authenticate LDAP users using below method its working on Production:生产:(工作)我们还使用以下方法对 LDAP 用户进行身份验证,其在生产中工作:

Check user has LDAP account or not:检查用户是否有LDAP账号:

// "<username>", "<password>" are Administrative credential.
var entry = new DirectoryEntry($"LDAP://{"<IP:389>"}", "<username>", "<password>",
    AuthenticationTypes.Secure | AuthenticationTypes.Sealing | AuthenticationTypes.ServerBind);
var search = new DirectorySearcher(entry);
var strFilter = $"(mail={"<UserEmailId>"})";
search.Filter = strFilter;
var result = await Task.Run(() => search.FindOne());
if (result != null)
{
    //IsLdapUser = true;
    //result.Properties["samaccountname"][0]);
}
else
{
    //IsLdapUser = false;
}
// Successfully


// Authenticate LDAP user:
var ldapConnection = new LdapConnection(new LdapDirectoryIdentifier("<IP:389>", false, false));                    
var nc = new NetworkCredential("<LdapUserName>", "<LdapUserPassword>", "<IP:389>");
ldapConnection.Credential = nc;
ldapConnection.AuthType = AuthType.Negotiate;
ldapConnection.Bind(nc);
// Successfully

Production: (not working)生产:(不工作)

// "<username>", "<password>" are Administrative credential.
PrincipalContext principalContext =
    new PrincipalContext(ContextType.Domain, "<IP:389>", container: "<DC=domain,DC=com>",
    "<username>", "<password>");
UserPrincipal user = UserPrincipal.FindByIdentity(principalContext, "<LdapUserName>");
bool isValid = user.ValidateCredentials("<username>", "<password>");
_logger.Log($"Is Connection: {isValid}");
**// Output: Is Connection: True**
user.UserCannotChangePassword = false;
user.SetPassword("<NewPassword>");
// Error: RPC server is unavailable. (exception from hresult: 0x800706ba)

Also tried with below code (not working)还尝试使用以下代码(不工作)

// "<username>", "<password>" are Administrative credential.
DirectoryEntry de = new DirectoryEntry("<IP:389>","<username>", "<password>", 
AuthenticationTypes.Secure | AuthenticationTypes.Sealing | AuthenticationTypes.ServerBind);
// LDAP Search Filter
DirectorySearcher ds = new DirectorySearcher(de);
ds.Filter = "(&(objectClass=user)(|(sAMAccountName=" + "<LdapUserName>"+ ")))";

// LDAP Properties to Load
ds.PropertiesToLoad.Add("displayName");
ds.PropertiesToLoad.Add("sAMAccountName");
ds.PropertiesToLoad.Add("DistinguishedName");
ds.PropertiesToLoad.Add("CN");

// Execute Search
SearchResult result = await Task.Run(() => ds.FindOne());

string dn = result.Properties["DistinguishedName"][0].ToString();

DirectoryEntry uEntry = result.GetDirectoryEntry();

uEntry.Invoke("SetPassword", new object[] { "<NewPassword>"});  //Set New Password                        
uEntry.CommitChanges();
uEntry.Close();
// Error: RPC server is unavailable. (exception from hresult: 0x800706ba)

The attribute used to modify the password is unicodePwd .用于修改密码的属性是unicodePwd That documentation reveals some conditions that must be met for the password to be changed.该文档揭示了更改密码必须满足的一些条件。 Primarily, the connection must be encrypted.首先,连接必须加密。

Calling .Invoke("SetPassword", ...) actually calls the native Windows IADsUser::SetPassword method.调用.Invoke("SetPassword", ...)实际上调用本机 Windows IADsUser::SetPassword方法。 That documentation shows that it automatically attempts a few different ways to encrypt.该文档显示它会自动尝试几种不同的加密方式。 The exception happens because none of these methods worked.发生异常是因为这些方法均无效。

You can actually modify the unicodePwd attribute directly, without calling SetPassword , which I'll get to, but regardless, you have to resolve the issue of encryption first.实际上,您可以直接修改unicodePwd属性,而无需调用SetPassword ,我将进行介绍,但无论如何,您必须先解决加密问题。

When you're running this from a computer inside the.network, AuthenticationTypes.Sealing is enough.当您从 .network 内的计算机运行它时, AuthenticationTypes.Sealing就足够了。 As the documentation says , the effect is that it uses Kerberos to encrypt the connection.正如文档所说,效果是它使用 Kerberos 来加密连接。

But when you're connecting from outside the domain, Kerberos won't work (maybe it will with effort - I'm no Kerberos expert).但是当您从域外连接时,Kerberos 将不起作用(也许它会努力 - 我不是 Kerberos 专家)。 So the only usable encryption method is SSL. The SetPassword method does actually attempt to use SSL, but clearly it didn't work.所以唯一可用的加密方法是SetPassword方法实际上尝试使用 SSL,但显然它没有用。

One problem I see right away is that you're using an IP address to connect to the DC, and SSL won't work using an IP address, since the domain name name on the SSL certificate must match the name you are using to access to the server, and the SSL cert will not have the IP address on it.我马上看到的一个问题是您正在使用 IP 地址连接到 DC,而 SSL 将无法使用 IP 地址,因为 SSL 证书上的域名名称必须与您用于访问的名称匹配到服务器,SSL 证书上将没有 IP 地址。 So you will have to change that to use the domain name.因此,您必须更改它才能使用域名。 If DNS will not resolve the name, you can add it to your hosts file.如果 DNS 无法解析该名称,您可以将其添加到您的主机文件中。

Changing that may fix everything.改变它可能会解决所有问题。 If not, there can be two other issues:如果不是,可能还有另外两个问题:

  1. Port 636 is not accessible (a firewall in the way).端口 636 不可访问(路上有防火墙)。
  2. The SSL certificate is not trusted on the computer you run this on SSL 证书在您运行此程序的计算机上不受信任

LDAP over SSL (LDAPS) works on port 636. You can test this connection in PowerShell: LDAP over SSL (LDAPS) 在端口 636 上工作。您可以在 PowerShell 中测试此连接:

Test-NetConnection example.com -Port 636

If that fails, fix that first.如果失败,请先修复它。

Next, check the certificate.接下来,检查证书。 You can download the certificate with this PowerShell script:您可以使用此 PowerShell 脚本下载证书:

$webRequest = [Net.WebRequest]::Create("https://example.com:636")
try { $webRequest.GetResponse() } catch {}
$cert = $webRequest.ServicePoint.Certificate
$bytes = $cert.Export([Security.Cryptography.X509Certificates.X509ContentType]::Cert)
set-content -value $bytes -encoding byte -path "certificate.cer"

Change the example.com in the first line to your domain name (leave the https:// and :636 ).将第一行中的example.com更改为您的域名(保留https://:636 )。 Then you will have a file called certificate.cer in the current directory that you can open and inspect.然后您将在当前目录中有一个名为certificate.cer的文件,您可以打开并检查该文件。 It will warn you if it is not trusted.如果它不受信任,它会警告您。 If it's not trusted, then you will have to install the root certificate on the server as a Trusted Root Certificate.如果它不受信任,则您必须将根证书作为受信任的根证书安装在服务器上。

If it is already trusted, make sure the "Issued to:" domain name on the cert matches the name you used to connect.如果它已被信任,请确保证书上的“颁发给:”域名与您用于连接的名称相匹配。 In our environment, the SSL certificates are in the name of each domain controller ( dc1.example.com ), not the domain name ( example.com ).在我们的环境中,SSL 证书位于每个域 controller ( dc1.example.com ) 的名称中,而不是域名 ( example.com )。 So I have to target a specific domain controller for LDAPS to work.所以我必须针对特定域 controller 才能使 LDAPS 工作。

Once you get all of that sorted out, your code should work.一旦你把所有这些都整理好,你的代码就应该可以工作了。

If you want to change the unicodePwd attribute directly instead of using SetPassword (which may or may not perform a little faster), you will need to make the original connection via SSL. For example:如果您想直接更改unicodePwd属性而不是使用SetPassword (它可能会或可能不会执行得更快),您将需要通过 SSL 建立原始连接。例如:

DirectoryEntry de = new DirectoryEntry("LDAP://dc1.example.com:636","<username>", "<password>", 
    AuthenticationTypes.Secure | AuthenticationTypes.SecureSocketsLayer | AuthenticationTypes.ServerBind);

Only use AuthenticationTypes.ServerBind if you are targeting a specific DC.如果您的目标是特定 DC,则仅使用AuthenticationTypes.ServerBind

Then you can update the unicodePwd attribute in the very specific way that it wants:然后你可以用它想要的非常具体的方式更新unicodePwd属性:

uEntry.Properties["unicodePwd"].Value = Encoding.Unicode.GetBytes("\"NewPassword\"");
uEntry.CommitChanges();

Note that the new password must be enclosed in quotes.请注意,新密码必须用引号引起来。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 System.Runtime.InteropServices.COMException(0x800706BA):RPC服务器不可用。 (HRESULT异常:0x800706BA) - System.Runtime.InteropServices.COMException (0x800706BA): The RPC server is unavailable. (Exception from HRESULT: 0x800706BA) WMI RPC服务器不可用。 (来自HRESULT的异常:0x800706BA) - WMI The RPC server is unavailable. (Exception from HRESULT: 0x800706BA) RPC服务器不可用。 (来自HRESULT的异常:0x800706BA)-Excel - The RPC server is unavailable. (Exception from HRESULT: 0x800706BA) - Excel RPC服务器不可用。 连接到远程计算机时(来自HRESULT的异常:0x800706BA) - The RPC server is unavailable. (Exception from HRESULT: 0x800706BA) when connecting to remote computer 如何处理 System.Runtime.InteropServices.COMException (0x800706BA):RPC 服务器不可用。 (来自 HRESULT 的异常:0x800706BA) - How to handle System.Runtime.InteropServices.COMException (0x800706BA): The RPC server is unavailable. (Exception from HRESULT: 0x800706BA) WMI:RPC服务器不可用。 (尝试连接到远程计算机时抛出HRESULT异常:0x800706BA) - WMI: The RPC server is unavailable. (Exception from HRESULT: 0x800706BA) throws when try to connect to remote machine 如何修复“CCertRequest::Submit:RPC 服务器不可用。0x800706ba”错误? - How to fix "CCertRequest::Submit: The RPC server is unavailable. 0x800706ba" error? 在错误0x800706BA之前捕获RPC锁定 - Catch RPC lock before error 0x800706BA 通过 C# 从 powerpoint 幻灯片创建视频 throws 远程过程调用失败。 (HRESULT 异常:0x800706BE) - Create video from powerpoint slides via C# throws The remote procedure call failed. (Exception from HRESULT: 0x800706BE) LDAP服务器不可用。 C#ASP.net - LDAP server unavailable. C# ASP.net
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM