Hi Bob,
There is no way those paths you have are going to be working correctly.
LDAP distinguished names (DN) are similar to file system paths in that they
suggest the directory hierarchy, but with three key differences:
- They are listed in opposite order (most specific first instead of last
like a file system path)
- Each component in the hierarchy has a two part name called a relative
distinguished name (RDN) that is made up of the naming attribute and value.
For example, CN=someuser could be an RDN where CN is the naming attribute
and someuser is the value of CN for that object. AD uses just three naming
attributes: CN, OU and DC, although LDAP in general can be much more varied.
- The top level object in the hierarchy (called the naming context name or
domain root in some cases) may consist of more than one RDN component. For
example, you might have the NC name as DC=domain,DC=com.
As such, a typical DN for a user might be
CN=someuser,CN=Users,DC=domain,DC=com. Here, CN=someuser points to the user
object, CN=Users points to the default container in AD where users are
stored and DC=domain,DC=com points to the domain root.
Now, with an ADsPath (which is used by ADSI and System.DirectoryServices),
the path is a combo of the provider, the server (which can be optional) and
the object name. It goes like:
<provider>://<server>/<object>
In LDAP, the provider is always "LDAP" (upper case is important) unless you
are talking to the global catalog, in which it is GC. The server name is
optional and can be the DNS name of the DC, the DNS name of the domain, the
NetBIOS name of the domain or the IP address of the DC. I generally
recommend using either the DNS name of the domain or nothing (called
"serverless binding" in ADSI terms). However, when you use nothing, ADSI
uses the current security context of the thread to figure out what domain to
contact and this can get complex in web apps, so you can get unexpected
failures this way. Adding the domain name is safe. The object name is the
distinguished name of the object. As such, a valid ADsPath for the DN of
the example object above might be:
LDAP://domain.com/CN=someuser,CN=Users,DC=domain,DC=com
or
LDAP://mydc.domain.com/CN=someuser,CN=Users,DC=domain,DC=com
or
LDAP://CN=someuser,CN=Users,DC=domain,DC=com
Remember that with S.DS, the constructor doesn't actually bind the object
(it is late binding), so you'll generally get an object back when you use
the constructor. It will just fail later when you attempt to use it. This
is a little different than ADSI in VB or VBScript.
My recommendation would be to pick up Marc's browser that he wrote (good
sample code inside) or just get LDP.exe which comes with ADAM or the Windows
adminpack. I like it especially, as it is sort of the "query analyzer" for
LDAP. It kind of forces you to know what you are doing, but it also shows
you exactly what is going and and can really help you prototype your
queries.
My book (that Marc aluded to) has a bunch of other helpful stuff. You may
run into issues related to security context when you move this into
production and have everything on different boxes. It is very much like
getting SSPI auth to work with a remote SQL server. You need to understand
security context and delegation quite well, especially if you are using
impersonation and want to connect to AD as the authenticated user instead of
the app pool process identity.
LDAP can be an annoying struggle for those seeing it for the first time,
even for experienced devs like you, but it all comes together once you get a
few things down.
Joe K.
--
Joe Kaplan-MS MVP Directory Services Programming
Co-author of "The .NET Developer's Guide to Directory Services Programming"
http://www.directoryprogramming.net
--
Bob Mixon said:
Hi Marc,
I really appreciate your response. I have done quite a bit of reading and
am still struggling with getting this to work. I am a seasoned developer,
just not with using Directory Services and LDAP.
Here is what I have. I have a Windows 2003 Server VM that I use for
SharePoint development efforts. In this type of "sandbox" environment, it
is very common to have everything installed on the single server. This VM
is an AD DC, running SQL Server 2005 and MOSS. I understand this won't be
the same in a "real" production environment. The server is named "w2k3"
and the domain is simply "moss".
I am first trying to simply see if an LDAP entry exist. The entry
"LDAP://DC=moss" returns a valid DirectoryService object instance. And so
does "LDAP://DC=moss/CN=Users". However, the entry "LDAP://DC=moss/CN=Bob
Mixon" and "LDAP://DC=moss,CN=Bob Mixon" both fail. The account "Bob
Mixon" is valid in AD; i.e. user id bob.mixon, name "Bob Mixon".
Ultimately all I want to do is locate a user account then retrieve that
users manager information. This can't be that difficult.
Thank you for your time!
Bob Mixon [Microsoft SharePoint MVP]
http://www.ShareSquared.com
http://www.ShareSquared.com/blogs/BobMixon