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

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.

Related

How to read AD user groups from LotusScript in IBM Notes

Is there any way to read all groups for an Active Directory user from LotusScript or #Formula in IBM Notes, if the Active Directory was added to Directory Assistance DB on the Domino server?
Assuming that your code will be running on a Windows machine, you can use ADODB.Connection as described in the answer to a previous question. And as described on this TechNet page, the filter you are going to need to issue will look something like this:
(member:1.2.840.113556.1.4.1941:=cn=Jim Smith,ou=West,dc=Domain,dc=com)
The sequence of numbers is explained on this page. It is what will give you a recursive search through nested groups.
The baseDN in the LDAP URL in your ADODV.Command call will be the root of your groups in AD, and the scope will be ?sub for a subtree search. That's explained in this answer to yet another question. And here's some documentation of LDAP URL format to help you put this all together.

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.

Generalise LDAP query for groups

I use the following query to find the groups each user is a member of:
(&(objectClass=group)(|(member=cn=UID,OU=ServiceAccounts,OU=MC,DC=ads,DC=myCompany,DC=com,DC=au)(member=cn=UID,OU=BTLY,OU=Sites,OU=MC,DC=ads,DC=myCompany,DC=com,DC=au)))
This query works and runs using the following Base DN:
OU=MC,DC=ads,DC=myCompany,DC=com,DC=au
I have few problems with the query:
I don't like having to use the OR operator to find Service Account users and BTLY users.
I don't want to hard-code the BTLY site, there are others, too.
Ideally, I'd just like to have the query as:
(&(objectClass=group)(|(member=cn=UID,OU=MC,DC=ads,DC=myCompany,DC=com,DC=au))
This way, I don't care whether the user account is a service account nor which site the account belongs to. Unfortunately, that query doesn't work.
Can someone please help me generalise the LDAP query? I'm a bit of a newbie, so I'm most likely missing something completely obvious!
Thanks!
Thanks for the reply. What you've said makes sense, but it doesn't help me, unfortunately. We're using GlassFish (a Java app server), and have configured it to point to the local AD server. Normally, a person can tell GlassFish how to retrieve users, eg
(&(objectCategory=user)(CN=UID))
and GlassFish will pick up all the groups (perhaps by using the memberOf attribute).
This time round we're using a different AD server which hosts a different directory of users. GlassFish isn't able to retrieve the groups by itself. So, there is a field where we can give GlassFish a custom query to find groups. In this field, I've put the query I've posted which works, but is ugly and verbose.
What I'd love to be able to do is:
(&(objectClass=group)(member=cn=UID))
but this doesn't work.
Is there anyway to do this?
Thanks,
Muel.
My guess is that using this technique is not possible. You would need to use wildcard here:
(&(objectCategory=group)(member=CN=UID,*))
and this is not acceptable for DN attributes (like the one stored in 'member' property):
http://msdn.microsoft.com/en-us/library/ms676930(v=vs.85).aspx
My suggestion here would be: use some tool to generate 'ugly' query for you (using syntax mentioned above) and "feed" your tool with end result. Can't see any option, sorry...
I just try to reformulate your question, but it's to much text for a comment.
You are trying to find all the groups the user CN=UID belongs to begining from the nod OU=MC,DC=ads,DC=myCompany,DC=com,DC=au.
This can be done by retreiving the memberOf attribute of the user itself. The only problem (perhaps not in your case) is that the primary group is not in this list of DN, it's coded appart using primaryGroupId attribute.
so
(&(objectCategory=user)(CN=UID))
Will do the job test :
ldifde -f t.ldf -D "OU=MC,DC=ads,DC=myCompany,DC=com,DC=au" -r "(&(objectCategory=user)(CN=UID))" -l memberof
Remark : samAccountName or userPrincipalName are attributes you can rely on for uniqueness of the entry in Active-Directory, that is not the case of CN (an admin can change it)

Documentum user creation using Active Directory

Is there any way that we can programatically create a Documentum user by using Active Directory information? (I have very little knowledge on ADT and know that it stores user info thats all.)
In Documentum Administrator you can sync the ActiveDirectory Users by running the Job dm_LDAPSynchronization. This should do.
Hope this helps,
Max
edit: You can also create a User using DFC-Methods:
IDfUser newUser = (IDfUser) session.newObject("dm_user");
newUser.setUserName("New User");
newUser.setUserLoginName("newuser");
newUser.setString("user_source","inline password");
newUser.setString("user_password","new_password");
newUser.setDefaultFolder("/newuser",true);
newUser.save();
Instead of putting inline_password as the user_source, you probably can choose LDAP and remove the user_password. This most probably needs more information, but I don't have the DFC Documentation with me at the moment. I could look it up in the evening, but for now this should give you a good point to start.
You could also make a Server Method out of it and assign it to a custom Job.
BUT: I don't think that you can CREATE new LDAP-Users from Documentum...they need to be present in the ActiveDirectory when you import them into Documentum!
Cheers,
Max
You can configure LDAP through DA and set all the connection info, user id password and than configure the ldapsync job to do this ,whenever a new user is added into ldap,it will be imported into documentum by that job and deactivated if user is removed from ldap.
Thats the best way to avoid any programming .
The LDAP synchronization is quite limited and shortsighted. You can concatenate two LDAP attributes for a user like this : ${sn}_${givenname}#company.com. You can also substring, starting from left to a given number. Thats it. No more. I wonder why they bothered.
A proper solution would have been standarsing on a expression language - all from XQuery to RegEx. There are lots to choose from.

LDAP and Active Directory Learning Curve

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.

Resources