DirectoryServicesCOMException when working with System.DirectoryServices.AccountManagement - c#

I'm attempting to determine whether a user is a member of a given group using System.DirectoryServices.AccountManagment.
I'm doing this inside a SharePoint WebPart in SharePoint 2007 on a 64-bit system.
Project targets .NET 3.5
Impersonation is enabled in the web.config.
The IIS Site in question is using an IIS App Pool with a domain user configured as the identity.
I am able to instantiate a PrincipalContext as such:
PrincipalContext pc = new PrincipalContext(ContextType.Domain)
Next, I try to grab a principal:
using (PrincipalContext pc = new PrincipalContext(ContextType.Domain))
{
GroupPrincipal group = GroupPrincipal.FindByIdentity(pc, "MYDOMAIN\somegroup");
// snip: exception thrown by line above.
}
Both the above and UserPrincipal.FindByIdentity with a user SAM throw a DirectoryServicesCOMException: "Logon failure: Unknown user name or bad password"
I've tried passing in a complete SAMAccountName to either FindByIdentity (in the form of MYDOMAIN\username) or just the username with no change in behavior. I've tried executing the code with other credentials using both the HostingEnvironment.Impersonate and SPSecurity.RunWithElevatedPrivileges approaches and also experience the same result.
I've also tried instantiating my context with the domain name in place:
Principal Context pc = new PrincipalContext(ContextType.Domain, "MYDOMAIN");
This throws a PrincipalServerDownException: "The server could not be contacted."
I'm working on a reasonably hardened server. I did not lock the system down so I am unsure exactly what has been done to it. If there are credentials I need to allocate to my pool identity's user or in the domain security policy in order for these to work, I can configure the domain accordingly. Are there any settings that would be preventing my code from running? Am I missing something in the code itself? Is this just not possible in a SharePoint web?
EDIT:
Given further testing, my code functions correctly when tested in a Console application targeting .NET 4.0. I targeted a different framework because I didn't have AccountManagement available to me in the console app when targeting .NET 3.5 for some reason.
using (PrincipalContext pc = new PrincipalContext(ContextType.Domain))
using (UserPrincipal adUser = UserPrincipal.FindByIdentity(pc, "MYDOMAIN\joe.user"))
using (GroupPrincipal adGroup = GroupPrincipal.FindByIdentity(pc, "MYDOMAIN\user group"))
{
if (adUser.IsMemberOf(adGroup))
{
Console.WriteLine("User is a member!");
}
else
{
Console.WriteLine("User is NOT a member.");
}
}
What varies in my SharePoint environment that might prohibit this function from executing?

I added the account used by the IIS Application Pool to the Administrators group and this issue was resolved.

Related

c# check if a windows account is locked out in a specific domain

I'm trying to do something that I don't even know if it is possible.
I have a web application based on C# that runs on a specific server. I want to build a code where the user introduces the domain where the app runs (this server depends on the client, for each client it runs on different servers obviously) and the app returns the local windows user accounts of that domain and information saying if the users are locked out or not.
I've tried to use Win32_UserAccount but it seems to get the users of the network I'm currently using.
Is this possible to do?
Thank you so much
Regards,
Flávio Justino
Try
using(PrincipalContext ctx = new PrincipalContext(ContextType.Domain, "domain"))
{
using(UserPrincipal usr = UserPrincipal.FindByIdentity(ctx, IdentityType.SamAccountName, "username"))
{
usr.IsAccountLockedOut(); //Gets if account is locked out
}
}
You need to add dpendency System.DirectoryServices.AccountManagement.dll for the above code to work.

Intermittent unknown error from Active Directory

I'm using .Net account management libraries to access Active Directory to search the details of current http request user.
My app pool runs with custom account and it also from the same domain. Server and users also belong to same domain.
public string GetEmployeeId(string SAMAccountName)
{
using (PrincipalContext domainContext = new PrincipalContext(ContextType.Domain))
{
using (UserPrincipal userprincipal = new UserPrincipal(domainContext))
{
userprincipal.SamAccountName = SAMAccountName;
using (PrincipalSearcher ps = new PrincipalSearcher())
{
ps.QueryFilter = userprincipal;
UserPrincipal user = ps.FindOne() as UserPrincipal;
return user.EmployeeId;
}
}
}
}
Setup works perfectly but intermittently i get below error from AD.after sometime it works for the same user without any error.
Is there any way to check logs / events from the AD side to find the reason for this error.
System.Runtime.InteropServices.COMException (0x80005000): Unknown error >(0x80005000)
I worked with a Microsoft Engineer for a long time to fix this so hopefully my solution can help others fix their problems.
First off the error code 0x80005000 referrers to an invalid ADSI pathname was passed, which wasn’t particularly helpfully.
We did a lot of tracing which was also not very helpful. Last thing we did was use Process Monitor to trace the Registry.
When the error occurred, I noticed a HIVE UNLOADED result happened (see screenshot)
Based on this we also found this error appearing in the event log.
Log Name: Application
Source: Microsoft-Windows-User Profiles Service
Date: 10/26/2009 8:22:13 AM
Event ID: 1530
Task Category: None
Level: Warning
Keywords: Classic
User: SYSTEM
Computer: SERVERNAME
Description:
Windows detected your registry file is still in use by other applications or services. The file will be unloaded now. The applications or services that hold your registry file may not function properly afterwards.
DETAIL -
1 user registry handles leaked from \Registry\User\S-1-5-21-1049297961-3057247634-349289542-1004_Classes:
Process 2428 (\Device\HarddiskVolume1\Windows\System32\dllhost.exe) has opened key \REGISTRY\USER\S-1-5-21-1123456789-3057247634-349289542-1004_CLASSES
The engineer suggested this article https://support.microsoft.com/en-us/help/2287297/a-com-application-may-stop-working-on-windows-server-2008-when-a-user
Which seem to fix my problem.
Try to identify what domain server you will use:
Something like:
= new PrincipalContext(ContextType.Domain, "YOURADDOMAIN");

Get WindowsIdentifiy from Operating system using a SID

I am sending request via WCF from Machine A to Machine B.
The domain and users are same on both machines.
In Machine B, using a given parameters, I want to create a WindowsIdentity for that user that invoked the operation from Machine A.
I know there is technology to do this via WCF infrastructure - but this technology is not enabled in my project.
So i need to send OperationContext.Current.ServiceSecurityContext.WindowsIdentity.User.Value from Machine A to Machine B.
My question is how do I create a WindowsIdentity using a SID ? Or do i need to send different parameters ?
Notes:
I was trying this:
PrincipalContext ctx = new PrincipalContext(ContextType.Domain, "My_Domain");
GroupPrincipal grp = GroupPrincipal.FindByIdentity(ctx, "userSID");
ofcourse with the right parameters, and then iterated all the GRP.GetMembers(true) to seek for mine - but it was not there.
Update:
The User is: DOMAIN_NT/MyUser123 -> If i change it to MyUser123#DOMAIN_NT and create instance of WindowsIdentity identity = new WindowsIdentitiy("MyUser123#DOMAIN_NT"); - It will work, but its an ugly way.

PrincipalServerDownException on Windows XP but not on Windows 7

We have a WPF application that runs in full trust.
Part of the application checks the membership of a Windows AD group.
This works fine on a Windows 7 machine, but not on a Windows XP machine.
The error occurs on the following line:
PrincipalContext ctx = new PrincipalContext(ContextType.Domain, "domain name");
According to the article Managing Directory Security Principals in the .NET Framework 3.5, the "domain name" variable might not be needed. That is, if you are accessing an Active Directory in the same domain as your application, the domain name is not needed.
You use the name parameter on the PrincipalContext constructor in
order to provide the name of the specific directory to connect to.
This can be the name of a specific server, machine, or domain. It's
important to note that if this parameter is null, AccountManagement
will attempt to determine a default machine or domain for the
connection based on your current security context.
The solution or workaround to the problem (at least what worked for me on both XP and W7) is the following change:
PrincipalContext ctx = new PrincipalContext(ContextType.Domain, null);

.net 3.5 Active Directory User creation error You were not connected because a duplicate name exists on the network

I am trying to create a new Active Directory user in .net 3.5 and I am recieving the following error "You were not connected because a duplicate name exists on the network."
I have googled the error and I can not find anything related to this on Windows server 2008 and .net 3.5.
I can create a new user when using AD users and groups on the server.
We are using identity impersonate and the user has full access to AD.
I can create the user on my local development machine.
This is on a Windows 2008 server using .net 3.5
Here is the code we are using:
newPassword = GeneratePassword()
ctx = New PrincipalContext(ContextType.Domain, "Domain",containerDistinguishedName)
user = New UserPrincipal(ctx, userName, newPassword, enabled)
' Force the user to change the initial password on first logon
user.ExpirePasswordNow()
' Commit the new object to Active Directory
user.Save()
' Return success
Return newPassword
It sounds like the server may be the thing that is not connected to the domain. This is possibly due to the machine being cloned and reusing the SID or name of the machine. Are you able to manage active directory users from this machine using the active directory users and groups tool?

Categories

Resources