This should be really easy but for some reason it doesn't seem to be. I want to ask AD if the current machine is a member of a particular group. Direct membership is fine.
Group only contains 8 PC's and is extremely unlikely to grow beyond 30.
C# code examples appreciated!
Here's an example method using the System.DirectoryServices namespace:
public bool BelongsToGroup(string computerName, string groupName, string domain)
{
PrincipalContext domainContext = new PrincipalContext(ContextType.Domain, domain);
ComputerPrincipal computer = ComputerPrincipal.FindByIdentity(domainContext, computerName);
foreach (Principal result in computer.GetGroups())
{
if (result.Name == groupName)
{
return true;
}
}
return false;
}
So you could call it like this:
string computerName = Environment.MachineName;
string groupName = "Group Name";
string domainName = "Domain Name";
bool test = BelongsToGroup(computerName, groupName, domainName);
Related
I'm trying this code:
public bool isTravelAdmin(string srvr, string usr, string password)
{
System.Diagnostics.Debug.WriteLine("I'm in isTravelAdmin!");
PrincipalContext domainctx = new PrincipalContext(ContextType.Domain, srvr);
UserPrincipal userPrincipal = UserPrincipal.FindByIdentity(domainctx, IdentityType.SamAccountName, usr);
bool isMember = userPrincipal.IsMemberOf(domainctx, IdentityType.Name, "traveladmin");
if (isMember)
{
System.Diagnostics.Debug.WriteLine("This user is INDEED a member of that group");
return true;
}
else
{
System.Diagnostics.Debug.WriteLine("This user is *NOT* member of that group");
return false;
}
}
Which is supposed to check if a user belongs to a certain group ("traveladmin"), but I'm getting
System.DirectoryServices.AccountManagement.PrincipalServerDownException
Any idea why and how to solve? by the way:
srvr = "LDAP://192.168.56.101/CN=Users,DC=estagioit,DC=local"
PS: I'm using the same srvr on another method and it's working and connecting.
PSS: If this is not the best way to go about this I'm open to suggestions.
The problem is how the "Principal Context" is written... it should be:
PrincipalContext thisPrincipalContext = new PrincipalContext(ContextType.Domain, "DCESTAGIO");
in this case.
If you look at the documentation for the PrincipalContext constructors, it should be quite clear:
public PrincipalContext(ContextType contextType, string name)
or
public PrincipalContext(ContextType contextType, string name, string container)
So you basically need:
your context type (here: ContextType.Domain)
the domain name (try just the "Netbios" name, e.g. "YOURDOMAIN" -
or leave NULL for "default" domain)
optionally a container (as an LDAP path - a "distinguished" name,
full path but without any LDAP:// prefix)
as seen in this answer.
In your case just change your srvr to:
srvr = "DCESTAGIO"
I'm writing a web service that checks if the user exists in Active Directory and if the user account is enabled. Once it checks that, I then go ahead validate their user account. Once they successfully enter username and password, I would like to get the GUID or NativeGuid for the person I'm authenticating. I would like to use GUID or NativeGUID to build a relationship inside SQL Server database.
Here's the approach I'm taking:
public string isAuthenticated (string serverName, string userName, string pwd)
{
string _serverName, _userName, _pwd;
_serverName = serverName;
_userName = userName;
_pwd = pwd;
string message;
if (DoesUserExist (_userName) == true)
{
if (isActive(userName) == true)
{
try
{
DirectoryEntry entry = new DirectoryEntry(_serverName, _userName, _pwd);
object nativeObject = entry.NativeObject;
//issue is here
string GUID = entry.Guid.ToString();
string GUIDID = entry.NativeGuid;
//end of issue
message = "Successfully authenticated";
}
catch(DirectoryServicesCOMException ex)
{
message = ex.Message;
}
}
else
{
message = "Account is disabled";
}
}
else
{
message = "There's an issue with your account.";
}
return message;
}
When I try to get the GUID or NativeGUID it's returning me the same ID every single time for different users.
Is there a different approach I can take to get a UNIQUE ID for different objects in Active Directory?
Thanks
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, _userName);
if(user != null)
{
// get the GUID
var objectGuid = user.Guid;
}
}
The new S.DS.AM makes it really easy to play around with users and groups in AD! I don't have an AD lying around right now to test - but I hope this will indeed give you the user object's objectGuid property value.
I'm using the System.DirectoryServices.AccountManagement namespace to find domain users and their corresponding AD security groups. This works well.
I'm also using that namespace to query the local security groups on a remote server. I am able to find a security group and then list the users of that group no problem.
What I'm having issues with is displaying which LOCAL groups a DOMAIN user belongs to:
PrincipalContext localmachine = new PrincipalContext(ContextType.Machine, "ServerName");
PrincipalContext domain = new PrincipalContext(ContextType.Domain);
// find the user using the domain context (Works fine)
UserPrincipal user = UserPrincipal.FindByIdentity(domain, userName);
// if found - grab its groups
if (user != null)
{
// The get groups method is the only method that would accept a new context
PrincipalSearchResult<Principal> groups = user.GetGroups(localMachine);
// no groups are returned .... removed rest of code
}
I'm attempting to use the GetGroups method passing in the localMachine PrincipalContext but no groups are returned.
The users exists only in the Domain AD. There is not an entry for this user in the local users on the localMachine. The domain users are added to local security groups.
Any ideas? I'd like to be able to pull a list of all local groups this domain user belongs to and then see if a certain groups exists in that list. The only option that is working now is for me to search certain groups on the system and see if the domain user belongs to that group.
The following code will return the local groups that a domain user is member of:
PrincipalContext domain = new PrincipalContext(ContextType.Domain);
UserPrincipal user = UserPrincipal.FindByIdentity(domain, userName);
foreach (GroupPrincipal group in user.GetAuthorizationGroups())
{
if (group.Context.ConnectedServer == serverName)
Console.Out.WriteLine("{0}\\{1}", group.Context.Name, group.SamAccountName);
}
I know my answer is late, but this worked for me (after I tried all sorts of permutations):
private static IList<string> GetUserLocalGroups(string userAccountName, string computerName, string domainName)
{
List<string> groups = new List<string>();
// We have to deal with a local computer
DirectoryEntry root = new DirectoryEntry(String.Format("WinNT://{0},Computer", computerName), null, null, AuthenticationTypes.Secure);
foreach (DirectoryEntry groupDirectoryEntry in root.Children)
{
if (groupDirectoryEntry.SchemaClassName != "Group")
continue;
string groupName = groupDirectoryEntry.Name;
Console.WriteLine("Checking: {0}", groupName);
if (IsUserMemberOfGroup(groupDirectoryEntry, String.Format("WinNT://{0}/{1}", domainName, userAccountName)))
{
groups.Add(groupName);
}
}
return groups;
}
private static bool IsUserMemberOfGroup(DirectoryEntry group, string userPath)
{
return (bool)group.Invoke(
"IsMember",
new object[] { userPath }
);
}
The call is something like this:
GetUserLocalGroups("samaccountname", "computerName.yourdomain", "yourdomain");
We have an application that needs a user to be connected to the VPN to run. THe issue is we rely on Windows Authentication for the application to be authenticated. However , we have come across some machines whose windows login name and their AD login Names are different.
Can somebody suggest a way for us to read the AD login name which is the same as the VPN login Name at all times ?
PS: we use checkpoint VPN Secure Client
you can try this if you are using ActiveDirectory but I am not sure if you are familiar with AD but this will be a good learning tool for you especially if it works..
static void Main(string[] args)
{
string groupName = "Domain Users";
string domainName = "";
PrincipalContext ctx = new PrincipalContext(ContextType.Domain, domainName);
GroupPrincipal grp = GroupPrincipal.FindByIdentity(ctx, IdentityType.SamAccountName, groupName);
if (grp != null)
{
foreach (Principal p in grp.GetMembers(false))
{
Console.WriteLine(p.SamAccountName + " - " + p.DisplayName);
}
grp.Dispose();
ctx.Dispose();
Console.ReadLine();
}
else
{
Console.WriteLine("\nWe did not find that group in that domain, perhaps the group resides in a different domain?");
Console.ReadLine();
}
}
or you can try that one specified in this link on How to get Users Belonging to Active Directory group
The User.Identity.Name property returns the domain login id.
Which class/property exposes the actual user name?
For user "John Doe" who logs into the web application supplying my_domain\jdoe
**User.Identity.Name -**
Returns : *my_domain\jdoe*
**System.Environment.UserName**
Returns: *jdoe*
Which class/property returns? ... "John Doe"
If you are thinking Active Directory, you'll need to find the UserPrincipal that corresponds to the given samAccountName and get the DisplayName property from it. Note that it may not be set.
string fullName = null;
using (PrincipalContext context = new PrincipalContext( ContextType.Domain ))
{
using (UserPrincipal user
= UserPrincipal.FindByIdentity( context,
User.Identity.Name ))
{
if (user != null)
{
fullName = user.DisplayName;
}
}
}
Sounds like instead of the login name, you are after the display name of an Active Directory user account. What you might want to do is to do an AD search (DirectorySearcher) and get the display name from the search result property.
I'm assuming that you are in an AD environment, since you tagged the question adsi.
Note: If you are working with .NET 3.5, you might want to look at tvanfosson's post.
The IIdentity interface is that which provides the Name property on User.Identity. The IIdentity interface can be implemented on any number of classes which know how to lookup users from a data-store (SQL Server, Active Directory, etc).
There is no property of the IIdentity interface which provides "John Doe". If that information is located in your data-store then you'll need to use the tools specific to that data-store to access it.
That said, its entirely possible that the object which is returned by User.Identity has a property which contains "John Doe" that you might be able to access through some other interface besides IIdentity (our custom IIdentity implementation does this, for example).
using System.DirectoryServices;
public static string GetFullName(string strLogin)
{
string str = "";
string strDomain;
string strName;
// Parse the string to check if domain name is present.
int idx = strLogin.IndexOf('\\');
if (idx == -1)
{
idx = strLogin.IndexOf('#');
}
if (idx != -1)
{
strDomain = strLogin.Substring(0, idx);
strName = strLogin.Substring(idx + 1);
}
else
{
strDomain = Environment.MachineName;
strName = strLogin;
}
DirectoryEntry obDirEntry = null;
try
{
obDirEntry = new DirectoryEntry("WinNT://" + strDomain + "/" + strName);
System.DirectoryServices.PropertyCollection coll = obDirEntry.Properties;
object obVal = coll["FullName"].Value;
str = obVal.ToString();
}
catch (Exception ex)
{
str = ex.Message;
}
return str;
}
and the you can just call
var strJonDoeName = GetFullName(User.Identity.Name)
code mock it from here
Maybe I have made a mistake somewhere, but WinNT://... hasn't worked for domain accounts for me. Additionally, if the user isn't in the same domain as the machine, than PrincipalContext may not find the wanted element (as it searches in the current context, if used as above).
The following should translate the "friendly domain name" as provided by User.Identity.Name to an ldap compliant domain. Using the distinguishName of the domain delivers the needed ldap path information (which has solved my cross domain problem):
(VB.NET, sorry)
Imports System.DirectoryServices
Imports System.DirectoryServices.AccountManagement
Imports System.DirectoryServices.ActiveDirectory
...
Dim strUserName As String
Dim objDirContext As DirectoryContext
Dim objContext As PrincipalContext
Dim objPrincipal As Principal
Dim strLDAPDomainPath As String
...
// User.Identity.Name delivers domain\account or account#domain
// Split User.Identity.Name in domain and account as specified above
strDomain = "my_domain"
strAccount = "jdoe"
// Get LDAP domain relative path (distinguishName) from short domain name (e.g. my_domain -> us.my_domain.com -> DC=us,DC=my_domain,DC=com)
Try
objDirContext = New DirectoryContext(DirectoryContextType.Domain, strDomain)
strLDAPDomainPath = Domain.GetDomain(objDirContext).GetDirectoryEntry.Properties("distinguishedName").Value.ToString
Catch objException As DirectoryServicesCOMException
Throw New Exception("Couldn't get LDAP domain: " & objException.Message)
End Try
// Find user in LDAP
// Nothing results in using current domain controller
Try
objContext = New PrincipalContext(ContextType.Domain, Nothing, strLDAPDomainPath)
objPrincipal = Principal.FindByIdentity(objContext, IdentityType.Name, strAccount)
If Not IsNothing(objPrincipal) Then
strUserName = objPrincipal.DisplayName
End If
Catch objException As Exception
Throw New Exception("Couldn't get user display name: " & objException.Message)
End Try
// strUserName should now contain the wanted full name