GroupPrincipal.FindByIdentity Unknown COM Exception - c#

When deploying this code to a web application where the identity is the app pool user the following code throws an unknown COM exception. The exception is happening when the FindByIdentity method is invoked.
System.Runtime.InteropServices.COMException: Unknown error
(0x8000500c)
using (PrincipalContext prinCon = new PrincipalContext(ContextType.Domain))
{
GroupPrincipal groupPrin = GroupPrincipal.FindByIdentity(prinCon, name);
}
If I change the application pool identity to a domain user this problem is resolved. Which initially leads me to believe it is a permission/security issue. However, this error does not happen on all servers, just some. Additionally, a restart will fix this issue.
So, my question is why would restarting the server fix this issue? And is there a way I make this work without restarting?
I've done a fair amount of googling and haven't come across anyone with the same problem, a few permission similar issues, but none that help solve my problem.
Thanks in advance.

Changing the app pool account is what worked for me. It was ApplicationPoolIdentity user, but after I changed to Network Service, this error went away and the AD code works fine. I hope this helps.

You didn't specify an identity type, but then you're feeding it a string. Perhaps its not knowing how to search for the string. For example, maybe it is assuming the string is a guid and then attempting to parse it and then failing.
Try something like:
var groupPrin = GroupPrincipal.FindByIdentity(prinCon, IdentityType.Name , name);
Also, try to set your PrincipalContext with some credentials that definitely have authority to perform these operations such as an admin or services account.

Related

UserPrincipal.Current throws COMException from one day to the next

This morning I started noticing some problems with several of my programs regarding Active Directory read operations. I noticed that all those applications (client and server) use the System.DirectoryServices.AccountManagement.UserPrincipal class for those read operations, while the programs still running correctly use System.DirectoryServices.DirectorySearcher.
So in order to narrow the problem down, I built the following, very simple console application
class Program
{
static void Main(string[] args)
{
//this works great
Console.WriteLine($"Enviroment.Username:{Environment.UserName}");
//this works great
PrincipalContext pcFull = new PrincipalContext(ContextType.Domain, "my.company.de", "dc=my,dc=company,dc=de");
UserPrincipal upPrincipalContextFull = UserPrincipal.FindByIdentity(pcFull, Environment.UserName);
//this doesn't work at all
//Exception: “The specified directory service attribute or value does not exist”
PrincipalContext pc = new PrincipalContext(ContextType.Domain);
UserPrincipal upPrincipalContext = UserPrincipal.FindByIdentity(pc, Environment.UserName);
//this doesn't either, same exception
UserPrincipal upCurrent = UserPrincipal.Current;
Console.ReadKey();
}
}
As you can see in the comments, the two latter operations will fail on every Computer in the domain i tested it on, even though they worked perfectly for several years. The following Exception occurs when I call UserPrincipal.Currentor UserPrincipal.FindByIdentity(pc, Environment.UserName); without specifying the Container in the PrincipalContext:
System.Runtime.InteropServices.COMException: “The specified directory service attribute or value does not exist”
Here is what I know:
none of the applications that suddenly stopped working received an update within the last two weeks
all of those applications, the UserPrincipal.Current-Property and the UserPrincipal.FindByIdentity-Method worked perfectly yesterday
Workstations did not receive Windows or .Net updates in the last week
the phenomenon does not relate to a single workstation, user or OS, but occures for a lot of different users, on a lot of different machines running Windows 7 or 10.
Domain Controllers received updates a week ago. Apparently one of those updates has a known issue about LDAP queries: Due to a defect in WLDAP32.DLL, applications that perform LDAP referral chasing can consume too many dynamic TCP ports. It seems unlikely that this is the reason for the sudden failures because a) that patch was installed a week ago and the Problems only occurred today and b) the suggested Workarounds from Microsoft (restarting Services) don't have any effect
What might cause such a behavior "overnight"? If it really is related to a Windows update, other users will soon be experiencing this bug too!
I can obviously build Workarounds, so I don't have to use the failing methods and properties, but I still have to know why it stopped working in the first place.
Edit
To start with, it would be useful to understand the difference between
public PrincipalContext(ContextType contextType); and public PrincipalContext(ContextType contextType, string name, string container);. The PrincipalContext constructed without container still has to obtain that container somehow, doesn't it?
By default the PrincipalContext searches in the "OU=Computers"-Container.
This fails if the reading permission is not set for the Container and will throw a COM Exception.

security exception accessing registry when the program runs as scheduled task

the following small line throws a System.Security.SecurityException: Requested registry access is not allowed:
RegistryKey _key = HKLM.OpenSubKey("path\\to\\my settings", false);
Now.. what's the point some would ask? The point is that this runs ONLY when I am logged on. The exception is thrown if the program runs as scheduled task and nobody is logged on.
the user who runs that task is local administrator
the program does not run from a network share, it is located on the local disk
I even tried setting Code Access Security
the user has the rights to log on as a batch job
I have XP SP3 with all patches applied. The program is written in C# .Net 2.0 (tested 3.5 too)
Does anyone know whats the point here?
Torsten
EDIT: see http://gist.github.com/638576
Mhhhh...it seems related to Authorization problem too. Have you tried to use the API: OpenSubKey(...., RegistryKeyPermissionCheck) to see if something change? I guess it could be related to parent key and its authorization.
Try to see: http://msdn.microsoft.com/it-it/library/microsoft.win32.registrykeypermissioncheck.aspx (in your language). I hope it could help you...
Can you adapt this
WindowsPrincipal principal = new WindowsPrincipal(WindowsIdentity.GetCurrent());
string isAdmin = principal.IsInRole(WindowsBuiltInRole.Administrator) ? "Yes" : "No";
to check that the process really is successfully impersonating when there's no current user?
It seems that this is a problem of this specific computer. I tested it on another workstation and it works even without administrator privileges.
I assumed this - the program did run for years without any problems... Anyway, thanks to all!

.Net's Directory Services throws a strange exception

I have a small C# solution used to check users credentials. It works fine for two of my teammates, but on my PC I get an exception.
The relevant code:
PrincipalContext context = new PrincipalContext(ContextType.Domain);
if (context.ValidateCredentials(System.Environment.UserDomainName + "\\" + usr, pwd))
return true;
else
return false;
And the exception is:
DirectoryOperationException, "The server cannot handle directory requests.".
I tried creating context with the explicit server name and the 636 port number, but this didn't help as well.
Any ideas?
I had this problem too using IIS Express and VS 2010. What fixed it for me was a comment on another thread.
Validate a username and password against Active Directory?
but i'll save you the click and search... :) Just add ContextOpations.Negotiate to you Validate Credentials call like below.
bool valid = context.ValidateCredentials(user, pass, ***ContextOptions.Negotiate***);
I had this issue: things were working on my dev machine but didn't work on the server. Turned out that IIS on the server was set up to run as LocalMachine. I changed it to NetworkService (the default) and things started working.
So basically check the user of the app pool if this is running on IIS.
I had to just create a new app pool and assign it .NET 2.0, then assign the new app pool to our web app, and it started working. We had .NET 3.5 SP2, so the hotfix wasn't ideal for us. Since the WWW service is usually Local System, I questioned that too. But since it was .NET and security related, I gave a shot at the app pool first and it worked.
Perhaps you need the hotfix?
FIX: DirectoryOperationException exception
And you are an Admin or the id that your service is running under is an Admin on your PC right?
I take it you already looked into this:
System.DirectoryServices.Protocols
"You may receive a less than helpful DirectoryOperationException(“The server cannot handle directory requests.”) what isn’t quite so amusing about this is that it didn’t even try to communicate with the server. The solution was to add the port number to the server. So instead of passing “Server” to open the LdapConnection, I passed “server:636”. By the way, LDAPS is port 636 – rather than the 389 port used by LDAP."
Good point, I wouldn't expect that Win7/.NET 3.5 would need that patch. How about the info provided in this question:
Setting user's password via System.DirectoryServices.Protocols in AD 2008 R2

Accessing messageQueue from anonymous web service

I have a public message queue with full permissions to everyone, that I attempt to access from an anonymous web service.
Method MessageQueue.Exists -> Returns false all the time. If the queue is public and everyone has permissions, why can't I find it?
I changed my code to look like this:
MessageQueue queue = new MessageQueue(name);
return queue.Peek(expireInterval);
But this throws exception that the queue does not exist or I have no permissions to access it.
The web service must remain anonymous, why isn't it enough to give permissions on the queue?
I even tried giving full control to ANONYMOUS account, nada.
Someone please explain this voodoo to me, thanks in advance :)
After doing some research, I found a similar question asked in this site that was answered with changing the queue path from ".\QueueName" to "FormatName:DIRECT=OS:.\QueueName".
This indeed helped, although I couldn't find why.
I then found this article:
http://www.infosysblogs.com/microsoft/2007/02/msmq_sending_message_to_remote.html
which explains that accessing a MSMQ remotely requires using FormatName syntax.
I still don't understand why this works when the WS is running under integrated security.

How should I validate a user's credentials against an ADAM instance over SSL?

Apologies in advance as I haven't had much experience with directories before.
I have an ASP.net application, and I have to validate its users against an Active Directory Application Mode instance running on Server 2k3. I was previously attempting a connection with DirectoryEntry and catching the COMException if the user's credentials (userPrincipalName & password) were wrong, but I had a number of problems when trying to bind as users who weren't a member of any ADAM groups (which is a requirement).
I recently found the System.DirectoryServices.AccountManagement library, which seems a lot more promising, but although it works on my local machine, I'm having some troubles when testing this in our testbed environment. Chances are I'm simply misunderstanding how to use these objects correctly, as I wasn't able to find any great documentation on the matter. Currently I am creating a PrincipalContext with a Windows username and password, then calling the AuthenticateCredentials with the user's userPrincipalName and password. Here's a very short exert of what I'm doing:
using (var serviceContext = new PrincipalContext(
ContextType.ApplicationDirectory,
serverAddress,
rootContainer,
ContextOptions.Negotiate | ContextOptions.SecureSocketLayer,
serviceAccountUsername,
serviceAccountPassword)) {
bool credentialsValid = serviceContext.ValidateCredentials(userID, password, ContextOptions.SecureSocketLayer | ContextOptions.SimpleBind)
}
If the user's credentials are valid, I then go on to perform other operations with that principal context. As I said, this works for both users with and without roles in my own environment, but not in our testbed environment. My old DirectoryEntry way of checking the user's credentials still works with the same configuration.
After a very long morning, I was able to figure out the problem!
The exception message I was receiving when calling ValidateCredentials was extremely vague. After installing Visual Studio 2008 in the test environment (which is on the other side of the country, mind you!), I was able to debug and retrieve the HRESULT of the error. After some very deep searching in to Google, I found some very vague comments about "SSL Warnings" being picked up as other exceptions, and that enabling "SCHANNEL logging" (which I'm very unfamiliar with!) might reveal some more insight. So, after switching that on in the registry and retrying the connection, I was presented with this:
The certificate received from the remote server does not contain the expected name. It is therefore not possible to determine whether we are connecting to the correct server. The server name we were expecting is ADAMServer. The SSL connection request has failed. The attached data contains the server certificate.
I found this rather strange, as the old method of connecting via SSL worked fine. In any case, my co-worker was able to spot the problem - the name on the SSL certificate that had been issued on the server was that of the DNS name ("adam2.net") and not the host name ("adamserver"). Although I'm told that's the norm, it just wasn't resolving the correct name when using PrincipalContext.
Long story short; re-issuing a certificate with the computer name and not the DNS name fixed the problem!

Categories