Active Directory security - is user on computer? - c#

I have a task to select specific group of computers. Their unique property is that their security list contains permission for specific user. In AD tool - right click on computer, Security tab, Group or user names as seen on screenshot:
I can get the ComputerPrincipal object of relevant host, UserPrincipal of user, and both underlying DirectoryEntry objects, but I struggle to make a "join" and find if user is on the list.
I use C#, .NET3.5.

You will have to loop through every group, and for each group you could do something like this (assuming you have a groupDe, which is a DirectoryEntry for the group):
foreach (var identityReference in groupDe.ObjectSecurity.GetAccessRules(true, false, typeof(System.Security.Principal.SecurityIdentifier)) {
var nt_name = identityReference.Translate(typeof(NTAccount)).Value;
//nt_name.Value is now domain\username of the user this permission is for
//so you can match this against your list of users
}
The false in the call to GetAccessRules makes it not look at inherited permissions (I assumed that's what you want).
I haven't tested this, so it might need some tweaking.
This will probably be a very slow process, depending on how many groups you're looking through. You might be able to make it go faster by omitting the call to Translate. identityReference.Value would have (I believe) a SID, so you could try to match by SID rather than translating to something else before matching.

Related

How does UserPrincipal.FindByIdentity(PrincipalContext context, string identityValue) query Active Directory?

I am using .NET Framework 4.8 by necessity. I am running into an issue where:
UserPrincipal.FindByIdentity(context, username); is resulting in a System.DirectoryServices.AccountManagement.MultipleMatchesException exception for a specific username. I can retrieve other users just fine.
There are two accounts in my Active Directory that this user utilizes, however, both of them have different UPNs, sAMAccountNames, etc.
I took a look at the IdentityType enum and the FindByIdentity overload that allows for an exact IdentityType look-up. With this information, I used each possible IdentityType and tried the searches:
None of these lines of code result in a System.DirectoryServices.AccountManagement.MultipleMatchesException exception. The Sid and Guid look-ups fail because the username field isn't in the right format, and the other look-ups either pull the user or pull null.
So what am I missing here? Does the overload that leaves out a specific IdentityType do a different look-up than anything that's possible by supplying an IdentityType?
Edit #1: As Alex pointed out, I left out that I tried IdentityType.UserPrincipalName from my screenshot. This was just a cropping mistake. That call also does not throw an exception.
When you don't specify which identifier you're using, it's going to try them all at once. The source code is available now. The code that actually builds the query and executes it is here. Specifically it's line 617 where it starts building the filter. The source for IdentityClaimToFilter is here. Then it puts each condition in an OR.
So if we ignore Guid, Sid, and DistinguishedName, since we know those won't match, this is the relevant LDAP query (assuming the username you're using is "UserName"):
(|(sAMAccountName=UserName)(userPrincipalName=UserName)(name=UserName))
Try making that query in PowerShell and see if you get multiple matches (I'm assuming the computer you run this from is joined to the domain you want to search):
$search = [adsisearcher]"(|(sAMAccountName=UserName)(userPrincipalName=UserName)(name=UserName))"
$search.FindAll()
If the sAMAccountName of one account matches the name of another account, for example, you will get multiple matches.

Google Admin API - Moving User to Different OU

I've seen code snippets and answers for setting a user to an Org Unit (OU) during user creation, but nothing regarding moving a user from one OU to another after it's been created.
NOTE: Prior to this I retrieved the user I wanted to modify, which is what the user variable refers to.
user.OrgUnitPath = "/NLWC";
var updateResult = await _service.Users.Update(user, user.Id).ExecuteAsync();
updateResult returns a User object. When I view the OrgUnitPath in the returned user I view the desired OU path (and also, when I query that same user in the future I get the same result).
But when I view the user in the Gsuite admin console, the OU hasn't changed.
In fact, I manually moved the user to the OU, and queried the user object again. After manually moving it, the OrgUnitPath is still the same.
Additionally, I queried the Org Units to verify I have the right path, and it shows the following:
I can't understand why it's not moving the user to the right OU, what am I missing?

C# - Filtering a DirectorySearcher for groupmembers

my issue is about filtering members of a specific group to be not shown in the userlist.
So far to that, this is my code to filter them out so far:
searcher.Filter = string.Format("(&(cn=*{0}*)(objectCategory=person)(objectClass=user)(!(adminCount=1))(!(cn=*Admin*)))",SuchfeldNachName.Text).Replace("**","*");
This is how I am trying to filter it right now. Obviously, I am trying to not show admins in the userlist. But thats not a fine solution for me, because in the final state, I want it to filter out four specific Active Directory groups.
These are the four groups I want to filter out:
Domain Admins
Enterprise Admins
Policy Creator Owner
Schema Admins
Now my question:
Is there a possible way to filter out the groupID's? So that the users in these groups are not shown in my userlist.
My idea was something like
(!(primaryGroupID= 512))
Second part of my question: Is there a list for all the group ID's?
Appreciate help in advance!

How to check if input string is valid active directory userPrincipalName?

User will input his wanted login name and I need to create active directory user by given name. So I need to validate it for AD userPrincipalName rules. How can I do it?
You need only query the UPN (Forest wide so do a globalcatalog search). If the DirectorySearcher returns an object, the UPN is in use.
You would also need to check that the planed samAccountName is not in use in the target domain, and that the planed user Name is not in the destination OU or Container. In both searches, as above, if the DirectorySearcher returns results, you must not continue, but chose alternatives.
Look here to find which attributes must be unique, but bear in mind, although the user's Name attribute is not mentioned in the table, it is being refered to in example 1.

IPrincipal.IsInRole() only works when I truncate the role names - why?

I have an application that relies heavily on authorization of users. Within it, I am using IPrincipal.IsInRole() to check whether users are in the correct groups:
IPrincipal principal = Thread.CurrentPrincipal;
bool inRole = principal.IsInRole("mydomainname\some role with a long name");
This works fine for the most part, but fails (returns an incorrect result) if the principal is an instance of a WindowsPrincipal. I have found that to make it work correctly, I have to truncate the name of the role that I pass in to be 32 characters long (including the domain name and the \):
IPrincipal principal = Thread.CurrentPrincipal; // <- returns a WindowsPrincipal
bool inRole = principal.IsInRole("mydomainname\some role with a lo");
Truncating the role name then works correctly. Why? Is this a bug/feature/documented issue? I have an inkling that it may be related to Win2000 domains, but cannot find any info on it.
Some extra info:
This is a problem because the application can be configured to use either active directory or "custom" for its authorization ("custom" being any authorization provider that supports an interface - could be SQL-based, file-based, etc..). When custom is configured, the roles most likely do not need truncating and so I don't want to have to deal with this special case in my code. Additionally, I have another part of the application that uses classes in the System.DirectoryServices.AccountManagement namespace to look up groups memberships. This requires the full role name and does not work if they are truncated.
After much trial and error, I have figured out what is going on.
When a group is created in Active Directory, it is given two names:
It seems to be that WindowsPrincipal uses the pre-Windows 2000 group name when IsInRole is called.
After searching extensively, this does not seem to be documented anywhere. The closest I got was this speculative answer to a similar question here on SO.
In my case, the groups I was querying against on the domain had a long name, but a truncated pre-Windows 2000 name (truncated to 32 characters for some reason). Passing in the long name does not work as it was checking against the wrong group name.

Categories

Resources