LDAP and Active Directory Learning Curve - active-directory

We are thinking about using LDAP with Active Directory for user management of many web applications instead of a custom relational database solution. Is there a high learning curve when doing this or is it easy as 1,2,3?

LDAP a bit funny and a bit "different" than traditional data stores - so there's definitely a learning curve involved.
The most challenging part would be to get a "grip" on the LDAP paths and how to build those up and use them. Also: permissions to connect to LDAP are always a bit issue. And if you want to start searching for objects in your LDAP store, then the rather tricky syntax of LDAP filters might also be a bit of a challenge to wrap your brain around :-)
If you intend to talk to and use Active Directory on Windows, then you should definitely check out the SelfADSI site with lots of useful information.
You didn't mention what language/programming environment you intend to use - if you're on .NET 3.5 or newer (C#, VB.NET), 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 namespace makes it really easy to play around with users and groups in AD in C#/VB.NET!

See also: "LDAP: Programming Practices" for information on writing code for LDAP server interaction will be robust, insulated and desensitized from any vendor specific LDAP knowledge. Writing code with specific knowledge of an implementation will result in brittle, hard to maintain code that may experience unexpected results when an aspect of the server implementation changes, such as the server itself, or the configuration of the server, or load balancers, or anything related to the infrastructure.
Avoid writing Microsoft specific code or creating Microsoft specific configurations wherever possible. Stick to the LDAP standards documents to the letter.

Related

Systems that Access AD Attributes

I have been assigned a task to export the AD Attributes than find out what systems are using these attributes. I have not had much luck in scripting or a tool that can provide just that. Is this feasible and if so how? I have already exported attributes. Just need to find what systems are using them.
This isn't possible with any reasonable accuracy, especially if "using" isn't defined for you.
The event logs on the domain controllers will tell you where login events are coming from, but only by IP. That doesn't tell you which application is authenticating. You would have to do monitoring on that computer and see which application is making the connection. But then the logs would be cluttered with connections made by Windows itself, or Exchange (if you use Exchange for email). It it would be very difficult to identify what is coming from an 3rd-party application rather than Windows itself.
Also, applications can request more information than they need. It's very easy when programming with LDAP to request every attribute for an object, even if you only intend to use one. For example, take this C# code:
var de = new DirectoryEntry("LDAP://example.com");
Console.WriteLine(de.Properties["name"].Value);
That only "uses" the name attribute. But because of the way LDAP works, it actually requests every non-constructed attribute that has a value. (there is a way to specifically ask for only one attribute, but you have to know that and use that)
So even if you could find logs saying that "this IP requested all of these attributes", and then figure out which application made that request, that doesn't mean it "used" all of those attributes.

Data studio connector using two api keys to authenticate

I am trying to build a connector that needs to access an API which requires API_KEY and API_SECRET. Currently Data Studio doesn't support authentication with two keys. So I thought I'd use auyhentication type NONE and then in getConfig() function I would prompt the user to input two required keys. However it seemms an awkward thing to do so I am asking more experienced developers. Am I introducing any security issue here? From what I understand there is no deifference whether I check and store user credentials in getConfig() or setCredentials(). They all end up stored in PropertiesService so I don't see any major difference. However, I may be wrong...
Currently(Nov 2019) there isn't support for API_KEY+API_SECRET. You have a few alternatives:
Use USER_PASS and in the connector description, instruct the user to use API_KEY for USER and API_SECRET for PASS.
Use NONE and get the info in getConfig().
Until the Data Studio team implements a solution, I recommend using #1. This will make it easier for you to migrate code and existing users once an official solution becomes available.

Get AD Site from LDAP Property

In a domain with AD Sites and Services configured is it possible to get the Site of a computer from LDAP? Is it stored as an attribute?
Unless this has changed over the last couple of years outside of my knowledge, there is not. Historically this was never done as AD site knowledge was ephemeral...the assumption was that computers move around so storing where they are is silly. Plus there was no global need for the knowledge.
You could of course add this. By this i mean, you could do something like, extend the schema with a new attribute for this and set a start-up script on your domain-joined machines to write this (if it has changed since they last wrote) to the directory. Obviously you'll want to test this well to ensure it doesn't create more problems than it solves...
On the Win32 point of view you've got the DsAddressToSiteNamesEx API. I don't know how to find it using pure LDAP.

What is the NativeGuid in DirectoryEntry when querying via the WinNT provider?

I'm writing an application which I want to work with both Active Directory and local users and groups. I thought I could use the NativeGuid property of a DirectoryEntry as a unique identifier which was retrieved using the WinNT provider against LocalHost. However, using the following code in LinqPad I get the same NativeGuid for both entries. Querying Active Dirctory with the LDAP provider appears to yield unique results, but now I'm unsure.
System.DirectoryServices.DirectoryEntry localuserde =
new System.DirectoryServices.DirectoryEntry("WinNT://localhost/localuser");
localuserde.NativeGuid.Dump("localUser Guid");
System.DirectoryServices.DirectoryEntry adminde =
new System.DirectoryServices.DirectoryEntry("WinNT://localhost/administrator");
adminde.NativeGuid.Dump("administrator Guid");
Can someone please explain what the NativeGuid represents when using the WinNT provider, and is there a good alternative for a uniqueId or is the SID a better choice?
To run the above in LinqPad hit F4 and add System.DirectoryServices.dll to the list of assemblies. Then make sure that localuser either exists or change the name to a local user on the system. Then hit F5.
Thanks,
Shane Holder
I would think the SID is probably your best bet in any user- and group-related scenario here. There's really no other unique identifier - especially not with the WinNT provider.
For more info on the WinNT vs. LDAP discussion and for great reference Excel sheets on what properties each of those providers really expose (and what their names are), visit Richard Mueller's Hilltop Lab. Richard is an ADSI MVP and has excellent contents for anyone interested in Active Directory and LDAP.
Marc
This other question says not to use NativeGuid. I would use the "SID" instead.

FindByIdentity in System.DirectoryServices.AccountManagment Memory Issues

I'm working on an active directory managament application. In addition to the typical Create A New User, Enable/Disable an account, reset my password etc. it also managages application permissions for all of the clients web applications. Application management is handled by thousands of AD groups such as which are built from 3 letter codes for the application, section and site, there are also hundreds of AD groups which determine which applications and locations a coordinator can grant rights to. All of these groups in turn belong to other groups so I typically filter the groups list with the MemberOf property to find the groups that a user directly belongs to (or everyone has rights to do everything). I've made extensive use of the System.DirectoryServices.AccountManagment namespace using the FindByIdentity method in 31 places throughout the application. This method calls a private method FindPrincipalByIdentRefHelper on the internal ADStoreCtx class. A SearchResultCollection is created but not disposed so eventually typically once or twice a day the web server runs out of memory and all of the applications on the web server stop responsing until iis is reset because the resources used by the com objects aren't ever relased.
There are places where I fall back to the underlying directory objects, but there are lot of places where I'm using the properties on the Principal - it's a vast improvement over using the esoteric ad property names in the .Net 2.0 Directory services code.
I've contacted microsoft about the problem and it's been fixed in .Net 4.0 but they don't currently have plans to fix it in 3.5 unless there is intrest in the community about it.
I only found information about it in a couple of places
the MDSN documentation in the community content state's there is a memory leak at the bottom (guess I should have read that before using the the method)
http://msdn.microsoft.com/en-us/library/bb345628.aspx
And the class in question is internal and doesn't expose SearchResultsCollection outside the offending method so I can't get at the results to dispose them or inherit from the class and override the method.
So my questions are
Has anyone else encountered this problem? If so were you able to work around it?
Do I have any option besides rewriting the application not using any of the .Net 3.5 active directory code?
Thanks
I have encountered the same error, and no, I don't have a workaround other than using the DirectoryEntry approach.
Wrap your calls to directorysearcher inside a using block and also wrap the resultcollection inside a using block and call .Dispose() on the results explicitly. See answer here:
Memory Leak when using PrincipalSearcher.FindAll()

Resources