Is user (outside of domain) part of active directory group - c#

In C#, I'm trying to authenticate a user against a group in ActiveDirectory. The code below works fine for users within our domain, but we also have users in other countries that log in to our vpn and need to access my program. The code below crashes when they attempt to run it. I've tried everything and I just can't figure this out.
var principalContext = new PrincipalContext(ContextType.Domain)
var groupPrincipal = GroupPrincipal.FindByIdentity(principalContext, IdentityType.Name, "myGroup")
var members = groupPrincipal.GetMembers(true).ToList()
var isMember = members.Any(m => m.Guid == userPrincipal.Guid)
How can I test to see if a user is part of an Active Directory group that is outside of our domain?
Thankx

Are the VPN users authenticating against the domain? Also, how are you getting the userPrincipal?
Here's some code that tackles the problem from the other side. It's a little older but I used it to verify users could run a small program of mine.
var userGroups = WindowsIdentity.GetCurrent().Groups;
foreach (var domainGroup in userGroups)
{
var group = domainGroup.Translate(typeof(NTAccount));
if (group.Value == "domain\\myGroup")
{
isMember = true;
}
}
Of course you can translate that into the appropriate linq statement if need be.

Related

c# Query Active Directory for users who have never logged in

I need to identify users who are in an Active Directory who have not logged in after so long or who have not logged in ever.
I have the code working for querying based on a login date, but I am stuck on how to find users who have never logged in.
Here is the code I have so far:
UserPrincipal userTmpl = new UserPrincipal(pc);
if(prmLoginDate.HasValue)
userTmpl.AdvancedSearchFilter.LastLogonTime(prmLoginDate.Value, MatchType.LessThanOrEquals);
else
userTmpl.LastLogon = //This is where I would like to just say 'null' or something like that;
PrincipalSearcher srch = new PrincipalSearcher(userTmpl);
foreach (Principal p in srch.FindAll())
{
//... Do stuff here
}
Any help on how to do this particular search would be greatly appreciated.

How to get all groups on a local machine with managed code (no P/Invoke)

So I was looking on SO for the answer to this question and it seemed as everything I came across was for Active Directory or something similar. There were no examples for this for the local machine.
Basically the goal here is to get all the user groups in the system. The same ones you'd see if you launch Computer Management, traverse to System Tools > Local Users and Groups > Groups
using (PrincipalContext context = new PrincipalContext(ContextType.Machine))
{
using (GroupPrincipal groupPrincipal = new GroupPrincipal(context))
{
groupPrincipal.Name = "*";
PrincipalSearcher principalSearcher = new PrincipalSearcher();
principalSearcher.QueryFilter = groupPrincipal;
PrincipalSearchResult<Principal> groupList = principalSearcher.FindAll();
foreach (Principal group in groupList)
{
// Do something with info
}
}
}

How to get all accounts including Local System account in c#?

Im developing a winforms wizard and in one page of this wizard i need to list all the accounts to enable the user select one. So my working code is:
private static IEnumerable<string> GetUsersAccountName()
{
var searcher = new ManagementObjectSearcher(new SelectQuery("Win32_UserAccount"));
var usersAccounts = (from ManagementBaseObject envVar in searcher.Get()
select envVar["Name"].ToString());
return users.ToList();
}
So with this method i get the name of the accounts, but not get the "local system account", how to get this account name too?
You're right, there's a little stuff you need to do, in order to receive the account name. You can do look up by SID. In fact, SID is always the same for LocalSystem(S-1-5-18).
To actually convert it, try this:
string localSysAccountName = new SecurityIdentifier("S-1-5-18")
.Translate(typeof(NTAccount)).ToString();
In case that does not seem to work well, have a look at LookupAccountSid.

Simple means to get user's roles from AD?

I am writing a standalone application that needs to, given a AD account name, figure out if the user is a member of a particular group. I am writing the application in .NET (C#). The structure in AD looks like this:
Organization
Team 1
David (user)
Groups
Application A
Team 1 (group from above)
Just listing the memberships for David will not show that he is a member of the Application A group.
I understand from Microsoft's documentation that (using the principals) I could simply use the IsInRole call, but I cannot find any case that doesn't require David to be logged on to the machine or running the application performing the check. I think my limited understanding of the security model also comes into play here.
Could someone please point me in the right direction? What I am looking for is hints on how to solve above (references, tips, snippets) in C#, without depending on David having to run any application.
Let me know if anything can be clarified.
Add a reference to DirectoryServices.AccountManagement
Then add a using statement:
using System.DirectoryServices.AccountManagement;
Then in your main procedure (or somewhere else, where required, call the Procedure IsMember:
string userName = "David";
string GroupName = "Team 1";
bool test = IsMember(userName, GroupName);
public static bool IsMember(string UserName, string GroupName)
{
try
{
UserPrincipal user = UserPrincipal.FindByIdentity(
new PrincipalContext(ContextType.Domain),
UserName);
foreach (Principal result in user.GetAuthorizationGroups())
{
if (string.Compare(result.Name, GroupName, true) == 0)
return true;
}
return false;
}
catch (Exception E)
{
throw E;
}
}
If David is in Team 1, the procedure will return true, otherwise false.
You can use UserPrincipal.FindByIdentity to obtain a UserPrincipal object from the directory. This isn't exactly like the other principal objects you may have found, but it does have an IsMemberOf method to allow you to query group membership.
I use this in my AD environment
var pc = new PrincipalContext(ContextType.Domain);
var group = GroupPrincipal.FindByIdentity(pc, "GROUPNAME");
var existsInGroup = group.GetMembers(true).Where(p => p.UserPrincipalName == "username#domain").Any();
If you don't want to check subgroups, pass false to GetMembers.
It doesn't require given user has to be logged on. Hope it helps.

Getting file permissions across the network

I have a situation where I need to confirm that I am able to get write access to a particular folder on the network. So firstly I check is the user or one of the groups it is part of (domain groups) one of the identities in the access rules. If that is not the case then I need to go through and check all the local groups on the remote machine, to see if my user or one of the user's groups is a member of the local groups on the machine. For example on this particular machine I am a member of BUILTIN\Administrators, which means I do have write access to the given folder. However I am not clear how to get that local group from the remote machine to check if I have write access.
In the code below, when I try and use GroupPrincipal.FindByIdentity, it gives an exception "The binding handle is invalid." I'm not clear what is invalid. If I just try and verify my username and password (a domain username), by using ctx.ValidateCredentials(UserName, Password), it gives exactly the same error.
If I give the machine name as just "pvr-pc", it says it cannot find the name on the network, but "\\pvr-pc" does get past that problem fine.
The same code correctly discovers that I one of the groups I am part of is a group in BUILTIN\Administrators on my local machine, so it's something about the network access that is the problem.
Does anyone have any ideas what I've done wrong?
The code looks like this:
using (WindowsIdentity identity = GetUserIdentity())
{
if (identity != null)
{
try
{
FileInfo fi = new FileInfo(#"\\pvr-pc\c\installers\");
AuthorizationRuleCollection acl = fi.GetAccessControl().GetAccessRules
(true, true, typeof (SecurityIdentifier));
var rules = acl.Cast<FileSystemAccessRule>();
List<string> sids = new List<string>();
sids.Add(identity.User.Value);
sids.AddRange(identity.Groups.Select(identityReference => identityReference.Value));
// check for a direct user match
var matches = from r in rules where sids.Contains(r.IdentityReference.Value) select r;
foreach (FileSystemAccessRule accessRule in matches)
{
// apply rules
}
foreach (FileSystemAccessRule rule in rules)
{
// if it is built in, try and get the group
var groupDetail = rule.IdentityReference.Translate(typeof (NTAccount));
if (!groupDetail.Value.StartsWith("BUILTIN\\")) continue;
PrincipalContext ctx = new PrincipalContext(ContextType.Machine, #"\\pvr-pc", null,
ContextOptions.Negotiate, UserName, Password);
GroupPrincipal grp = GroupPrincipal.FindByIdentity(ctx, IdentityType.Sid,
rule.IdentityReference.Value);
if (grp != null)
{
//// find out if we are a member of the group
var isInGroup = (from g in grp.GetMembers(true)
where sids.Contains(g.Sid.ToString())
select g).Any();
if (isInGroup)
{
// apply rules
}
}
}
}
catch (Exception ex)
{
}
Thanks,
Stefan
Would it not be easier to simply read or write to the folder and then catch the Exception; then inform the user s/he has no access.

Categories

Resources