Any way to distinguish between "people user accounts" and "computer user accounts"? - c#

When querying Active Directory for users - is there a way to filter out user accounts created for computers? Ideally a way which is common across most typical networks. e.g.:
DirectorySearcher ds = new DirectorySearcher(new DirectoryEntry([Users_OU_root]));
ds.filter = "(&(objectClass=User)([CRITERIA_TO_FILTER_OUT_COMPUTER_USER_ACCOUNTS]))";
ds.FindAll();
...

If you're on .NET 3.5 and up, you should check out the System.DirectoryServices.AccountManagement (S.DS.AM) namespace. Read all about it here:
Managing Directory Security Principals in the .NET Framework 3.5
MSDN docs on System.DirectoryServices.AccountManagement
Basically, you can define a domain context and easily find users and/or groups in AD:
// set up domain context
PrincipalContext ctx = new PrincipalContext(ContextType.Domain);
// find a user
UserPrincipal user = UserPrincipal.FindByIdentity(ctx, "SomeUserName");
if(user != null)
{
// do something here....
}
// find the group in question
GroupPrincipal group = GroupPrincipal.FindByIdentity(ctx, "YourGroupNameHere");
// if found....
if (group != null)
{
// iterate over members
foreach (Principal p in group.GetMembers())
{
Console.WriteLine("{0}: {1}", p.StructuralObjectClass, p.DisplayName);
// do whatever you need to do to those members
}
}
The new S.DS.AM makes it really easy to play around with users and groups in AD:
Computer accounts will show up as ComputerPrincipal (derived from Principal) - so you can easily keep users and computer accounts apart.
If you cannot or don't want to move to S.DS.AM - you can also keep user and computers apart by using the objectCategory instead of the objectClass in your LDAP filter. objectCategory is beneficial anyway, since it's indexed, and not multi-valued - so query performance will be much better.
For a real-life user, use objectCategory = Person, while for a computer, use objectCategory = Computer in your LDAP filter.

Even if I agree with the answer. Active-Directory remain an LDAP server. Here is the filter you are looking for :
(&(objectCategory=user)(objectClass=user)(...))
'objectCategory=user' is a shortcut for 'objectCategory=CN=User,CN=Schema,CN=Configuration,DC=dom,DC=fr' understood by Active-Directory but it's also a way in others Directories, that's why I put an answer, even if another answer is accepted.

Related

Determine usergroups/claims of user given LDAP server details in C#

We have a test active directory LDAP server. I also have some user names and passwords. I would like to determine the claims/user groups of a particular user, whilst logged into another domain. Can this be done with some C# code? I presume I will have to use System.DirectoryServices.dll
If you can use .Net 3.5 of higher, then try System.DirectoryServices.AccountManagement.dll assembly. It provides System.DirectoryServices.AccountManagement namespace and Principal-based classes, such as UserPrincipal and GroupPrincipal. They represent higher level of abstraction and are easier to use.
For example, to connect to LDAP server in another domain (get Principal Context in terms of this abstraction) you need to create an instance of PrincipalContext class with this constructor:
PrincipalContext anotherDomainContext = new PrincipalContext(ContextType.Domain, DomainDnsName, RootOU, ContextOptions.SimpleBind, QueryUserName, QueryUserPassword);
RootOU is something like "DC=Company,DC=COM", therefore DomainDnsName will be like "company.com" or "ldapserver.company.com". If you have serveral domains in your AD forest then try to connect to global catalog (DomainDnsName = "ldapserver.company.com:3268"). QueryUserName and QueryUserPassword are plain strings with username and password which are used to connect to LDAP server. Username may include domain name, for example:
string QueryUserName = #"company\username";
Once connected to LDAP server you can search for users:
UserPrincipal user = UserPrincipal.FindByIdentity(anotherDomainContext , IdentityType.SamAccountName, samAccountName);
where you supply samAccountName and context (connection).
With an instance of UserPrincipal at hands you gain access to its properties and methods. For example, get security groups for user:
PrincipalSearchResult<Principal> searchResults = user.GetGroups();
List<GroupPrincipal> groupsList = searchResults.Select(result => result as GroupPrincipal).
Where(group => (group != null) &&
(group.IsSecurityGroup.HasValue) &&
(group.IsSecurityGroup.Value))
Note that GetGroups returns only groups to which user belongs directrly. To get all user groups including nested, call GetAuthorizationGroups. Also, you can avoid using LINQ, it's just for filtering security groups from GetGroups.
With GroupPrincipal you can check Name property, or Members collecion.

Searching active directory doesn't pull up the user record when applying a specific filter

DirectoryEntry deEntry = new DirectoryEntry("LDAP://test.com");
DirectorySearcher dsSearcher = new DirectorySearcher(deEntry);
dsSearcher.Filter = "(&(objectclass=user)(objectcategory=person))";
When I apply that filter, the user doesn't show up. But I've checked his attributes and those properties have those values.
But when I add his last name in the filter, he does show up.
dsSearcher.Filter = "(&(objectclass=user)(objectcategory=person)(sn=harper))";
Here is a picture with the deubg info that shows that his attributes are set correctly.
I have no idea what's going on. Any ideas?
If you're on .NET 3.5 and up, you should check out the System.DirectoryServices.AccountManagement (S.DS.AM) namespace. Read all about it here:
Managing Directory Security Principals in the .NET Framework 3.5
MSDN docs on System.DirectoryServices.AccountManagement
Basically, you can define a domain context and easily find users and/or groups in AD:
// set up domain context
using (PrincipalContext ctx = new PrincipalContext(ContextType.Domain))
{
// find a user
UserPrincipal user = UserPrincipal.FindByIdentity(ctx, "harper");
if(user != null)
{
// do something here....
}
}
The new S.DS.AM makes it really easy to play around with users and groups in AD!

System.DirectoryServices use And limitation

In my application I need to fetch users email from Active Directory.
I came across the System.DirectoryServices namespace for accessing Active Directory. I have no idea on how it works. I have few questions.
Can I simply use this namespace and access AD with proper queries? Is there any pre-requisite
like access to LDAP etc.
Please let me know how this actually works
FYI I use .net 4.0
If you're on .NET 3.5 and up, you should check out the System.DirectoryServices.AccountManagement (S.DS.AM) namespace. Read all about it here:
Managing Directory Security Principals in the .NET Framework 3.5
MSDN docs on System.DirectoryServices.AccountManagement
Basically, you can define a domain context and easily find users and/or groups in AD:
// set up domain context
using (PrincipalContext ctx = new PrincipalContext(ContextType.Domain))
{
// find a user
UserPrincipal user = UserPrincipal.FindByIdentity(ctx, "SomeUserName");
if(user != null)
{
// do something here....
}
// find the group in question
GroupPrincipal group = GroupPrincipal.FindByIdentity(ctx, "YourGroupNameHere");
// if found....
if (group != null)
{
// iterate over members
foreach (Principal p in group.GetMembers())
{
Console.WriteLine("{0}: {1}", p.StructuralObjectClass, p.DisplayName);
// do whatever you need to do to those members
}
}
}
The new S.DS.AM makes it really easy to play around with users and groups in AD!

How can I find a user's group using AD authentication in aspx?

So I followed this tutorial and I can successfully login, but now I was trying to find out if a user belongs to a group, I've tried:
if (User.IsInRole("group"))
along with
enableSearchMethods="true"
Nothing seems to work though, perhaps I'm looking at the wrong place... Anyone has any tips?
If you're on .NET 3.5 and up, you should check out the System.DirectoryServices.AccountManagement (S.DS.AM) namespace. Read all about it here:
Managing Directory Security Principals in the .NET Framework 3.5
MSDN docs on System.DirectoryServices.AccountManagement
Basically, you can define a domain context and easily find users and/or groups in AD:
// set up domain context
PrincipalContext ctx = new PrincipalContext(ContextType.Domain);
// find a user
UserPrincipal user = UserPrincipal.FindByIdentity(ctx, "SomeUserName");
if(user != null)
{
// do something here....
PrincipalSearchResult<Principal> groups = user.GetAuthorizationGroups();
// enumerate the groups found - check to find your group in question
}
The new S.DS.AM makes it really easy to play around with users and groups in AD!
Alternatively, you can also find the user and the group principals:
// set up domain context
PrincipalContext ctx = new PrincipalContext(ContextType.Domain);
// find a user
UserPrincipal user = UserPrincipal.FindByIdentity(ctx, "SomeUserName");
GroupPrincipal groupToCheck = GroupPrincipal.FindByIdentity(ctx, "YourGroupNameHere");
if(user != null && groupToCheck != null)
{
// this call will tell you - yes or no - whether that user is member of that group
bool isMember = user.IsMemberOf(groupToCheck);
}

ASP.NET Active Directory C# field specification

We've got an active directory here. provided the unique user id of the user, I need to access the organization->manager->name attribute related to that userid. Basically this will be used to send an approval form to the manager of the person submitting request.
Any idea how this could be done?
You can use the following code :
/* Retreiving object from SID
*/
string SidLDAPURLForm = "LDAP://WM2008R2ENT:389/<SID={0}>";
System.Security.Principal.SecurityIdentifier sidToFind = new System.Security.Principal.SecurityIdentifier("S-1-5-21-3115856885-816991240-3296679909-1106");
/*
System.Security.Principal.NTAccount user = new System.Security.Principal.NTAccount("SomeUsername");
System.Security.Principal.SecurityIdentifier sidToFind = user.Translate(System.Security.Principal.SecurityIdentifier)
*/
DirectoryEntry userEntry = new DirectoryEntry(string.Format(SidLDAPURLForm, sidToFind.Value));
string managerDn = userEntry.Properties["manager"].Value.ToString();
But you can also find in this post other ways to seach bind to Active-directory.
Since you're on .NET 3.5 and up, you should check out the System.DirectoryServices.AccountManagement (S.DS.AM) namespace. Read all about it here:
Managing Directory Security Principals in the .NET Framework 3.5
MSDN docs on System.DirectoryServices.AccountManagement
Basically, you can define a domain context and easily find users and/or groups in AD:
// set up domain context
PrincipalContext ctx = new PrincipalContext(ContextType.Domain);
// find a user
UserPrincipal user = UserPrincipal.FindByIdentity(ctx, "SomeUserName");
if(user != null)
{
// do something here....
}
// find the group in question
GroupPrincipal group = GroupPrincipal.FindByIdentity(ctx, "YourGroupNameHere");
// if found....
if (group != null)
{
// iterate over members
foreach (Principal p in group.GetMembers())
{
Console.WriteLine("{0}: {1}", p.StructuralObjectClass, p.DisplayName);
// do whatever you need to do to those members
}
}
The new S.DS.AM makes it really easy to play around with users and groups in AD!
I'm not 100% sure what you want to do in your concrete case... the UserPrincipal has an EmployeeId property - is that what you want to search for?
Use the System.DirectoryServices.DirectoryEntry class to read out the appropriate property of the user object. The constructor of DirectoryEntry requires that you have an LDAP path to the user. Getting the LDAP path can often be tricky though as IIS prefers handing over the SAM account name only. If you provide more details of what the user id you have looks like it is easier to point you in the right direction.
To do this the account which runs the ASP.NET application needs read access to the AD, which probably doesn't have by default. Changing the application pool to run under "NetworkService" is the easiest way if the web server belongs to the AD. The ASP.NET app will then use the MACHINE$ account of the server to access the AD.

Categories