Since I saw lot of posts about the exception which is shown below, And most of guys were stuck with it painfully.
Exception Message: "The server is not operational"
Source: "System.DirectoryServices"
Recently It happened on me. But finally I figure it out .I thought I should share my experience here so that in future it could be helpful for someone else who has the same problem as me.
The program I was working with is using AD authentication. And it works fine in my computer which belongs to the AD Domain. The code is below.
public static bool IsAuthenticated(string srvr, string usr, string pwd)
{
bool authenticated = false;
try
{
DirectoryEntry deRoot = new DirectoryEntry(srvr);
DirectoryEntry entry = new DirectoryEntry(srvr, usr, pwd);
object nativeObject = entry.NativeObject;//this will cause exception Until setting the right DNS address.
authenticated = true;
}
catch (DirectoryServicesCOMException cex)
{
//not authenticated; reason why is in cex
HttpContext.Current.Response.Write(cex.Message);
}
catch (Exception ex)
{
//not authenticated due to some other exception [this is optional]
HttpContext.Current.Response.Write(ex.Message);
}
return authenticated;
}
One day as our IT environment requirement changed, My computer IP is switched from 10.50.70.64 to 169.254.135.249. Because my net adapter IP and DNS always set to Obtain address automatically.In this case , I can log in my computer using the AD account successfully. But the program run with a big fat exception. So I doubted if there is something wrong with my Net Adapter settings. Finally I found If I set the right DNS address of our IT environment. The Exception was gone. I don't know why. So I also hope someone can explain more about it. Thanks.
Before authenticating user and password in AD domain, it need to parse the domain path against DSN server.
Related
I have created two test accounts test and test1.
I am able to login to one local windows user account "test" using the following code.
bool result = false;
ContextType contextType = ContextType.Machine;
//if (InDomain())
//{
// contextType = ContextType.Domain;
//}
try
{
using (PrincipalContext principalContext = new PrincipalContext(contextType))
{
result = principalContext.ValidateCredentials(
userName,
new NetworkCredential(string.Empty, password).Password
);
}
}
catch (PrincipalOperationException)
{
// Account disabled? Considering as Login failed
result = false;
}
catch (Exception)
{
throw;
}
return result;
However when I try to login with another account "test1", it throws the following exception.
Multiple connections to a server or shared resource by the same user, using more than one user name, are not allowed. Disconnect all previous connections to the server or shared resource and try again
It seems to me that the previous user "test" is already connected and occupies the resources, that is why it is not letting the user "test1" to get logged in and acquire the resources.
I have tried to find a way so that the first user "test" can be disconnected (or logged off) so that the 2nd user can get logged in.
I had tried to access the UserPrinciple through following code to get the connected user to disconnect but there is no method available in UserPrinciple
UserPrincipal userPrincipal = UserPrincipal.FindByIdentity(principalContext, "test");
There must be some way to log off (or disconnect) the logged in user.
I don't know whether there's a nicer solution, but you could try a workaround using the net use command. By hand:
Run net use
Identify the relevant connections
Run net use /d <connection> for all relevant connections
Connect using the new user
I'm using the EWS (2.2.1.0) and i need to read emails with my application for automate some tasks.
I would like to show a warning message if the inserted credentials are wrong or, if the connection is missing, just display an error icon in the status bar.
I need to distinguish if the user credentials are wrong or just the connection is missing.
The problem is that the AutodiscoverUrl() method in both cases return the same AutodiscoverLocalException:
The Autodiscover service couldn't be located.
This is weird and make no sense.
My code as follow:
try
{
exService.TraceEnabled = true;
exService.Credentials = new WebCredentials(UserSettings.Email.EmailAddress, UserSettings.Email.EmailPassword);
exService.AutodiscoverUrl(UserSettings.Email.EmailAddress, (string redirectionUrl) => {
bool result = false;
Uri redirectionUri = new Uri(redirectionUrl);
if (redirectionUri.Scheme == "https")
result = true;
return result;
});
}
catch(Exception ex)
{
Thread.Sleep(ApplicationSettings.General.WaitForNextConnectionRetry);
}
Can someone explain me how to check if the user credentials are wrong or the service is just unreachable?
Thanks in advance
Test Sample link: Get started with EWS Managed API client applications
I think there is no good way to distinguish the user credential or Uri. For me, I just to add "try catch" to detect the error. Also, I tested the sample code above and provide a wrong pwd. Then the error occurred in service.AutodiscoverUrl line. Please see the trace messsage:
Or maybe we can get the Trace message to detect it.
I have C# Windows Form application to test the LDAP SSL authentication.
Here is the code. First, I made a function.
using System.DirectoryServices;
private bool VerifyDomainUserUsignLDAP(string UserName, string Password, string Domain,string mode, out string message)
{
bool retVal = false;
message = null;
DirectoryEntry de;
try
{ if (mode =="Plain")
//plain mode
de = new DirectoryEntry(Domain, UserName, Password);
else
//SSL mode
de = new DirectoryEntry(Domain, UserName, Password,
AuthenticationTypes.Secure | AuthenticationTypes.SecureSocketsLayer);
DirectorySearcher ds = new DirectorySearcher(de);
SearchResult sr= ds.FindOne();
lblResult.Text = "Authentication Passed! " + sr.ToString();
retVal = true;
}
catch (Exception ex)
{
retVal = false;
lblResult.Text = ex.Message;
}
return retVal;
}
My problem is the invoke.
Share with some background first.
We have multiple domain control servers (Windows). dcserver001.mydomain.com is one of them. (of course, we have dcserver002.mydomain.com, dcserver003.mydomain.com, etc). each server provides LDAPS service.
And we created a VIP name ldap.mydomain.com in F5 (Load balance), we put all above dc servers into the Load balance. All DC servers are Windows servers.
Days before, if I use following line to invoke above function for LDAP authenticate on the VIP name - ldap.mydomain.com.
For e.g.
VerifyDomainUserUsignLDAP("mydomain\\myuserid", "mypassword",
#"LDAP://ldap.mydomain.com", "SSL" ,out Message);
It always worked fine and the user was authenticated.
However, some days before, our LDAP service team made a registry change (LdapEnforceChannelBinding) on each ldap servers to
enhance the security based on MS suggestion.
In short, they changed following key value from 0 to 2
Path: HKEY_LOCAL_MACHINE/System/CurrentControlSet/Services/NTDS/Parameters
Key: LdapEnforceChannelBinding
Here is detail page about the setting on MS web site.
Use the LdapEnforceChannelBinding registry entry to make LDAP authentication over SSL/TLS more secure
https://support.microsoft.com/en-hk/help/4034879/how-to-add-the-ldapenforcechannelbinding-registry-entry
After that, I noticed my above function stop working.
i.e. if I use same line to invoke above function for LDAP authenticate.
For e.g.
VerifyDomainUserUsignLDAP("mydomain\\myuserid", "mypassword",
#"LDAP://ldap.mydomain.com", "SSL" ,out Message);
It always returned exception "Logon failure: unknown user name or password."
(I promise password and user name were correct.)
Then, I did further investigation.
I tried to use following line to invoke above function for LDAP authenticate on any individual dc server, e.g.
dcserver001.mydomain.com.
VerifyDomainUserUsignLDAP("mydomain\\myuserid", "mypassword",
#"LDAP://dcserver001.mydomain.com", "SSL" ,out Message);
It worked fine as well.
I actually tested all individual dc servers one by one, thwy were all working.
So, it looks like the ldap request with same invoke parameters works well on the individual dc server, but it doesn't work on the VIP name.
Then, I asked the ldap server team to rollback to LdapEnforceChannelBinding change to value 0. Then, I re-tested ldap against both individual server and VIP name, both worked.
I checked with our metwork team and got got some more information as follwoing.
They said this won't work with LDAPS VIPs because the SSL channel from client is terminated on F5, and reestablished to DC.
the reason why it works directly to the dc is because its one continuous packet.
The update addresses this vulnerability by incorporating support for Extended Protection for Authentication security feature, which allows the LDAP server to detect and block such forwarded authentication requests once enabled.
What I need help is - is there anyone here encountered the similar ldap ssl logon issue against F5 VIP and with the LdapEnforceChannelBinding registry value = 1 or 2?
If LdapEnforceChannelBinding registry value = 1 or 2 on the LDAP servers, what changes need to be done to resolve above LDAPS logon issue?
Thanks a lot!
Jun
I have an asp.net application that uses delegation to perform actions on the Active Directory as the authenticating user. The application works perfectly on some computers and doesn't work at all on other computers, on these other computers they receive a COMexception error code 0x80072020 the stack trace is:
System.Runtime.InteropServices.COMException (0x80072020): An operations error occurred.
at System.DirectoryServices.DirectoryEntry.Bind(Boolean throwIfFail)
at System.DirectoryServices.DirectoryEntry.Bind()
at System.DirectoryServices.DirectoryEntry.get_AdsObject()
at System.DirectoryServices.DirectorySearcher.FindAll(Boolean findMoreThanOne)
at System.DirectoryServices.DirectorySearcher.FineOne()
at ResetUnlockAccount.ResetUnlockAccount.ExecuteImpersonation(String username)
The code that is throwing the error is:
WindowsIdentity winId = (WindowsIdentity)HttpContext.Current.User.Identity;
WindowsImpersonationContext ctx = null;
try
{
ctx=winId.Impersonate();
using (DirectoryEntry directoryObject = new DirectoryEntry(ROOT))
{
using (DirectorySearcher search = new DirectorySearcher(directoryObject))
{
search.Filter = "(&(objectClass=user)(SAMAccountName=username))";
search.SearchScope = SearchScope.Subtree;
///////////////////////////////////////////////////////////////////
This line is causing the issue.
---------->SearchResult result = search.FindOne();
using (DirectoryEntry user = result.GetDirectoryEntry())
{
user.Invoke("SetPassword", new object[] { password });
user.Properties["pwdLastSet"][0] = 0;
user.CommitChanges();
lblOutput.Text = "It worked";
}
}
}
}
catch (Exception ex)
{
lblOutput.Text += ex.ToString();
}
finally
{
if (ctx != null)
ctx.Undo();
}
At first I thought it was a User permission issue, so I tested it by trying my credentials on one of the computers that was having issues, I encountered the same issues. To confirm it wasn't User permission issues I tried it on my workstation with the other persons credentials and it worked perfectly.
I wrote a quick test program that would show me the impersonation level of the users, when working correctly it should be Delegation. When I ran it on my machine the output was:
Authentication Type: Negotiate
Token: 9999
Name: domain\username
Is Authenticated: True
Impersonation level: Delegation
When I ran it on the other Workstation:
Authentication Type: Negotiate
Token: 9999
Name: domain\username
Is Authenticated: True
Impersonation level: Impersonation
Server: IIS 7.0
Browser: IE 8
I don't know what is causing the issue with only certain computers, if anyone knows of a specific setting that should be changed for delegation to work properly I would be grateful. Below I have posted two other links that will help give more insight into my problem.
.GetDirectoryEntry throws COM exception, code:0x800720720 when attempting to bind to object
asp.net application userprincipal.findbyidentity works with browser on server, throws exception from my machine
I presume this is by design (and hence might be a silly question) however is there any way to determine the authentication issue generated when connecting to Dynamics CRM.
I am creating a third party application which connects and I would like to say "Invalid Password" rather than "Authentication Failure". The following is what I have.
namespace MyCRM
{
public class MyCRMClass
{
public static void ConnectToCRM()
{
Uri serverURI = new Uri('https://myorganisation.api.crm5.dynamics.com/XrmServices/2011/Organization.svc');
ClientCredentials clientCredentials = new ClientCredentials();
clientCredentials.UserName.UserName = 'Username';
clientCredentials.UserName.Password = 'Password';
OrganizationServiceProxy serviceProxy = new OrganizationServiceProxy(serverURI, null, clientCredentials, null);
serviceProxy.EnableProxyTypes();
try
{
Guid UserId = ((WhoAmIResponse)serviceProxy.Execute(new WhoAmIRequest())).UserId;
}
catch (Exception ex)
{
// Throws Authentication Issue
}
}
}
}
By calling the WhoAMIRequest I can get an Authentication error however I really want to know what error so I can assist staff with fixing their own issue.
Am I right in suggesting that this is not possible using the CRM webservices?
You'll never be able to get error information like you're requesting from the client side. You could theoretically turn on trace logging on the server, but that would be a bad idea for a whole slew of reasons.
Generally saying the password is invalid is a security issue because it allows hackers to know that the account is valid and if they could just figure out the password, they're in.