Configuring ActiveDirectory Group Security with C# using directory services - c#

I'm trying to create an app to configure a fresh install of AD or reset an AD to default values. This means using the DirectoryServices API.
My plan is to create some OU's, then some Groups (each with their own security poperties - ForeFront and CA is also installed). Then I will create some users and add them to the groups.
I know how to create OU's, groups, and users, and I know how to add users to groups.
But I don't know how to set the security properties of a group or a user.
I found this code, but it's not working for me:
static void SecurityStuff(string groupFQDN,string user)
{
DirectoryEntry directoryEntry = new DirectoryEntry(string.Format("LDAP://{0}",dudu.test.com/cn=batata,ou=Users and Groups,ou=FIM,ou=Local,dc=dudu,dc=test,dc=com),"username","password");
ActiveDirectorySecurity adSecurity = directoryEntry.ObjectSecurity;
string sd = adSecurity.GetSecurityDescriptorSddlForm(AccessControlSections.All);
IdentityReference newidentity = new System.Security.Principal.NTAccount("dudu.test.com",user);
ActiveDirectoryAccessRule newAccessRule = new ActiveDirectoryAccessRule(newidentity, ActiveDirectoryRights.WriteProperty, AccessControlType.Allow);
try
{
directoryEntry.ObjectSecurity.AddAccessRule(newAccessRule);
}
catch (Exception e)
{
Console.WriteLine(e.Message.ToString());
}
directoryEntry.CommitChanges();
}
I get this error from the code:
Some or all identity references could not be translated.
Please point me in the right direction.

Related

My website crashes when trying to use active directory instead of ADFS, what should I do?

I have some code that was working when just using active directory,however, when publishing it gives an error.
//Allow Active Directory Credentials to remove someone from the global unsubscribe
protected void Remove_Click(object sender, EventArgs e)
{
using (PrincipalContext pc = new PrincipalContext(ContextType.Domain, "Domain"))
{
// find the group in question
GroupPrincipal group = GroupPrincipal.FindByIdentity(pc, "IT Group");
if (group != null)
{ // remove user}
This now crashes the webpage and i get the following error:
Runtime Error
Description: An application error occurred on the server. The current custom error settings for this application prevent the details of the application error from being viewed remotely (for security reasons). It could, however, be viewed by browsers running on the local server machine.
Update:
Principal user can't be used with ASP.NET forms instead you must use a claims form and check your claims/roles.
// Cast the Thread.CurrentPrincipal
ClaimsPrincipal icp = User as ClaimsPrincipal;
// Access IClaimsIdentity which contains claims
ClaimsIdentity claimsIdentity = (ClaimsIdentity)icp.Identity;
// what we are doing here is using a for each to get to the claim
foreach (Claim claim in claimsIdentity.Claims)
{
//The claim we are looking for is in this directory /groupsid
if (claim.Type == "http://schemas.microsoft.com/claims/groupsid")
{
//We use a for loop to go through this because it reads it like a JSON and will either pull the first or last
//Basic for loop incrementing until it finds our group (IT ALL)
for (int i = 0; i <= 0; i++)
{
//If our claim contains IT ALL (which it does) then do something...
if (claim.Value.Contains("Name of Group"))
{
//I'm storing the result here so we can call it otherwise we lose it...
lblResultq.Text = (claim.Value.ToString());
Hope this will help someone in the future!

C# Get Domain Active directory Information by Windows Credentials

I've been searching a lot on the web for Active Directories and windows authentications. I've succeded on getting the User information from the Domain AD but I had to pass the User name AND PASSWORD. So to put you into my context :
I have a Domain where I've set my users. Each Users will be connecting to the domain with their given credentials. So they will log into their PC and when they open a VS 2013 C# application it will check if the users Exists on the Domain if he does then return the AD information if the users doesn't exist then show a Login Page to enter the Credentials. Since I can have external users connecting to my Domain etc ...
right now I cannot access the AD with the user's windows authentication it gives me a Unkown error on the Search.FindOne();
public static void GetActiveDirectoryUser(string UserName)
{
try
{
// Create LDAP connetion object
DirectoryEntry ldapConnection = CreateDirectoryEntry();
// Create Search object which operates on LDAP connection object
// and set search object to only find the user specified
DirectorySearcher search = new DirectorySearcher(ldapConnection);
// Create results objects from search object
SearchResult result = search.FindOne();
if (result != null)
{
// User exists, cycle through LDAP fields (cn, telephonenumber, etc.)
ResultPropertyCollection fields = result.Properties;
foreach (string ldapField in fields.PropertyNames)
{
// Cycle through objects in each field e.g group membership
foreach (Object objCollection in fields[ldapField])
{
Console.WriteLine(String.Format("{0, -20} : {1}", ldapField, objCollection.ToString()));
}
}
}
}
catch (Exception e)
{
Console.WriteLine("Exception Caught:\n\n" + e.ToString());
}
}
static DirectoryEntry CreateDirectoryEntry()
{
string pathDomainName = "WinNT://MyDomain/Fred,Person";
DirectoryEntry ldapConnection = new DirectoryEntry(pathDomainName);
return ldapConnection;
}
This is the error I'm getting
System.Runtime.InteropServices.COMException (0x80005000): Unknown error (0x80005000)
at System.DirectoryServices.DirectoryEntry.Bind(Boolean throwIfFail)
at System.DirectoryServices.DirectoryEntry.Bind()
at System.DirectoryServices.DirectoryEntry.get_AdsObject()
at System.DirectoryServices.DirectorySearcher.FindAll(Boolean findMoreThanOne)
at System.DirectoryServices.DirectorySearcher.FindOne()
but when I use this string
string pathDomainName = "LDAP://MyDomain";
DirectoryEntry directoryEntry = new DirectoryEntry(pathDomainName, "Fred", "f12345!");
it works, it returns me all the AD for the user, but I've already logged in with the windows authentication, why would I pass the credentials again ? I just need to know that if the user exists on the domain that's it
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, "SomeUserName");
if(user != null)
{
// do something here....
}
// or alternatively: get the currently logged in user
UserPrincipal current = UserPrincipal.Current;
.....
}
The new S.DS.AM makes it really easy to play around with users and groups in AD!

Is user (outside of domain) part of active directory group

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.

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.

Accessing AD (active directory) Properties

I access the AD properties thru the below method. It works fine in my Local VHD (where I'm the domain/local/enterprise Admin) - but the same doesn't work when I access from a Domain user(who has only local admin access).
But the same Domain user(only with local admin access) access all the AD property details using the ADExplorer(SysInternal) tools.
Is it because that is unmanaged code and have Windows APIs to access and in .Net I need domain admin or some privilege ?
Or is there another way - which I'm missing in .Net to access the AD Properties without having an extra domain-level-privilege ??
public void getCurrentUserADDetails(string UserName)
{
string ladpQueryStr = "LDAP://sp.com";
DirectoryEntry dirEntry = new DirectoryEntry(ladpQueryStr);
DirectorySearcher srch = new DirectorySearcher(dirEntry);
srch.Filter = "(cn=" + UserName.ToLowerInvariant().Trim() + ")";
srch.PropertiesToLoad.Add("name");
srch.PropertiesToLoad.Add("memberOf");
srch.PropertiesToLoad.Add("prop123");
SearchResult searcResult = srch.FindOne();
if (searcResult != null)
{
ResultPropertyCollection propertiesCollection = searcResult.Properties;
List<DisplayClass> grdDataList = new List<DisplayClass>();
foreach (string strKey in propertiesCollection.PropertyNames)
{
DisplayClass dispC = new DisplayClass();
dispC.pName = strKey;
dispC.pValue = Convert.ToString(propertiesCollection[strKey][0]);
grdDataList.Add(dispC);
}
dataGridView1.DataSource = grdDataList;
}
}
This is going to run in ASP.Net
thanks in advance :)
I assume you're using integrated authentification - in order for this to work you have to setup account delegation, unless you're running your application on a domain controller. This is a pretty tricky process, but there are a ton of info in Google.
By using Explicit authentication and changing the Search filter, i got the results.
DirectoryEntry dirEntry = new DirectoryEntry(path, username, password, AuthenticationType);

Categories

Resources