Justin Dearing | 11 Oct 17:06
Gravatar

Guessing root DNs for active directory

Hi,

Let me know if this is the wrong list for this question, and where best to ask this.

I am trying to write a simple program in java that "guesses" if the machine is running on active directory and connects to the domain controller via LDAP. My goal is to submit a patch to JXPlorer (and eventually other software like apache directory studio) to "detect" active directory and "auto-configure" a connection to it.

Right now I am grabing the envirormental variable "USERDNSDOMAIN", and transforming it from "foo.com" to "dc=foo,dc=com". This works good enough. However, Is it possible via some sort of LDAP query to get the base DN of either the domain I am authenticated to, or better yet all domains in the forest?

If anyone cares to help me in my research, or laugh at a .NET programmer trying to write JAVA, feel free to take a poke at my code in SVN, http://nightelves.svn.sourceforge.net/viewvc/nightelves/LI-PHP/LDAP/LDAP.Tests/src/LDAP/Tests.java?revision=57&view=markup

Thanks and Regards,

Justin Dearing
Dustin Puryear | 11 Oct 21:05

Re: Guessing root DNs for active directory

For obvious reasons you can't rely on an environmental variable. You can
however rely on most LDAP servers, including AD, giving you some basic
information using a query like this:

ldapsearch -x -s base -b "" -h DC-HOSTNAME

For AD, this gives you some useful information, including
defaultNamingContext and dsServiceName.

There are sites where this may be locked down. At those sites I think
any "automated configuration" of jxplorer won't be possible, but that's
the idea behind those sites locking down AD. ;)

--
Dustin Puryear
President and Sr. Consultant
Puryear Information Technology, LLC
225-706-8414 x112
http://www.puryear-it.com

Author, "Best Practices for Managing Linux and UNIX Servers"
  http://www.puryear-it.com/pubs/linux-unix-best-practices/

Justin Dearing wrote:
> Hi,
> 
> Let me know if this is the wrong list for this question, and where best
> to ask this.
> 
> I am trying to write a simple program in java that "guesses" if the
> machine is running on active directory and connects to the domain
> controller via LDAP. My goal is to submit a patch to JXPlorer (and
> eventually other software like apache directory studio) to "detect"
> active directory and "auto-configure" a connection to it.
> 
> Right now I am grabing the envirormental variable "USERDNSDOMAIN", and
> transforming it from "foo.com <http://foo.com>" to "dc=foo,dc=com". This
> works good enough. However, Is it possible via some sort of LDAP query
> to get the base DN of either the domain I am authenticated to, or better
> yet all domains in the forest?
> 
> If anyone cares to help me in my research, or laugh at a .NET programmer
> trying to write JAVA, feel free to take a poke at my code in
> SVN, http://nightelves.svn.sourceforge.net/viewvc/nightelves/LI-PHP/LDAP/LDAP.Tests/src/LDAP/Tests.java?revision=57&view=markup
> <http://nightelves.svn.sourceforge.net/viewvc/nightelves/LI-PHP/LDAP/LDAP.Tests/src/LDAP/Tests.java?revision=57&view=markup>
> 
> Thanks and Regards,
> 
> Justin Dearing
> 
> -- 
> This message was scanned by ESVA and is believed to be clean.
> Click here to report this message as spam. <
> http://esva.puryear-it.com/cgi-bin/learn-msg.cgi?id= >

joe | 13 Oct 16:52

Re: Guessing root DNs for active directory

You can't lock down AD's (or ADAM's) ability to return the RootDSE
attributes unless it is done through outright blocking of LDAP traffic to
the DSA which would kind of take the fun out of any LDAP queries. 

When the OP says "running on Active Directory", I will assume it means the
machine is participating in a Windows 2000 or better domain. Then from there
there are two questions, is this Windows or is this some other OS client
because Kerberos enabled clients of any flavor can participate in a Windows
AD realm through Kerberos. However we will focus on the Windows; the answer
on all other clients in the universe will depend on the type and version of
the client though it will likely involve finding the current krb5.conf file
and parsing it.

I will prefix this with I am not a Java developer but the "proper" way to do
this on Windows would be to issue a call to Windows API call DsGetDCName
with a null computername for the first parameter and null domainname for the
second parameter as well as proper values for the rest of the params
depending on exactly what you want. That will then give you the default DC
for the local machine. If you are using the Windows WLDAP32 library then you
can bypass this and simply do a serverless bind and it will figure it out in
the background for you; but you won't likely get access to that lib with
ldapsearch or the Java LDAP stuff. 

If you don't want to use Windows API calls directly, you could look at the
environment variables but take care or you could look at the domain or NV
Domain values under hklm\system\currentcontrolset\services\tcpip\parameters.
However, if the machine is running with a disjoint name from the domain it
is a member of, this will be incorrect. This is not usually a problem in
smaller environments but disjoints do occur in larger orgs. 

An alternate registry method would be to go look at the group policy info
stored in the registry, this is under
hklm\software\microsoft\windows\currentversion\group policy. Specifically
dig into the GUID keys under History and you will find a value with the name
of "filesyspath" which will contain something like
\\domain\sysvol\domain\policies\blah... You can parse the string and take
the \\domain\ part and use that to get started in collecting info.

   joe

 
--
O'Reilly Active Directory Third Edition -
http://www.joeware.net/win/ad3e.htm 

-----Original Message-----
From: bounce-ldap-5210650@...
[mailto:bounce-ldap-5210650@...] On Behalf Of Dustin
Puryear
Sent: Saturday, October 11, 2008 3:06 PM
To: Justin Dearing
Cc: ldap@...
Subject: [ldap] Re: Guessing root DNs for active directory

For obvious reasons you can't rely on an environmental variable. You can
however rely on most LDAP servers, including AD, giving you some basic
information using a query like this:

ldapsearch -x -s base -b "" -h DC-HOSTNAME

For AD, this gives you some useful information, including
defaultNamingContext and dsServiceName.

There are sites where this may be locked down. At those sites I think any
"automated configuration" of jxplorer won't be possible, but that's the idea
behind those sites locking down AD. ;)

--
Dustin Puryear
President and Sr. Consultant
Puryear Information Technology, LLC
225-706-8414 x112
http://www.puryear-it.com

Author, "Best Practices for Managing Linux and UNIX Servers"
  http://www.puryear-it.com/pubs/linux-unix-best-practices/

Justin Dearing wrote:
> Hi,
> 
> Let me know if this is the wrong list for this question, and where 
> best to ask this.
> 
> I am trying to write a simple program in java that "guesses" if the 
> machine is running on active directory and connects to the domain 
> controller via LDAP. My goal is to submit a patch to JXPlorer (and 
> eventually other software like apache directory studio) to "detect"
> active directory and "auto-configure" a connection to it.
> 
> Right now I am grabing the envirormental variable "USERDNSDOMAIN", and 
> transforming it from "foo.com <http://foo.com>" to "dc=foo,dc=com". 
> This works good enough. However, Is it possible via some sort of LDAP 
> query to get the base DN of either the domain I am authenticated to, 
> or better yet all domains in the forest?
> 
> If anyone cares to help me in my research, or laugh at a .NET 
> programmer trying to write JAVA, feel free to take a poke at my code 
> in SVN, 
> http://nightelves.svn.sourceforge.net/viewvc/nightelves/LI-PHP/LDAP/LD
> AP.Tests/src/LDAP/Tests.java?revision=57&view=markup
> <http://nightelves.svn.sourceforge.net/viewvc/nightelves/LI-PHP/LDAP/L
> DAP.Tests/src/LDAP/Tests.java?revision=57&view=markup>
> 
> Thanks and Regards,
> 
> Justin Dearing
> 
> --
> This message was scanned by ESVA and is believed to be clean.
> Click here to report this message as spam. < 
> http://esva.puryear-it.com/cgi-bin/learn-msg.cgi?id= >

Mark H. Wood | 13 Oct 17:36
Favicon

Re: Guessing root DNs for active directory

There's a DNS way to probe for LDAP (and Kerberos) services.  If a
machine is joined to ADS, then it should be possible to take its FQDN,
snip off the hostname, prepend "_tcp._ldap", and ask for SRV RRs by
that name.  If not found, keep removing one domain element at a time,
prepending "_tcp._ldap", and asking again until you have only two
domain elements left.

That is:  if the machine is named "host.baz.bar.foo.xcorp.com" you
would try to resolve:

  _tcp._ldap.baz.bar.foo.xcorp.com  SRV
  _tcp._ldap.bar.foo.xcorp.com      SRV
  _tcp._ldap.foo.xcorp.com          SRV
  _tcp._ldap.xcorp.com              SRV

When any SRV RRs are returned, they should point to the DCs for that
context.

As another poster pointed out, if you are doing this on Windows then
there is probably a simpler (except for DCOM OO goop) way to do it.

--

-- 
Mark H. Wood, Lead System Programmer   mwood@...
Typically when a software vendor says that a product is "intuitive" he
means the exact opposite.

Justin Dearing | 13 Oct 18:00
Gravatar

Re: Guessing root DNs for active directory

On Mon, Oct 13, 2008 at 11:36 AM, Mark H. Wood <mwood@...> wrote:
> There's a DNS way to probe for LDAP (and Kerberos) services.
><snip/>
>
> That is:  if the machine is named "host.baz.bar.foo.xcorp.com" you
> would try to resolve:
>
>  _tcp._ldap.baz.bar.foo.xcorp.com  SRV
>  _tcp._ldap.bar.foo.xcorp.com      SRV
>  _tcp._ldap.foo.xcorp.com          SRV
>  _tcp._ldap.xcorp.com              SRV
>
> When any SRV RRs are returned, they should point to the DCs for that
> context.

That will be quite useful. Right now I have two "guesses" as to the
ldap server. I will add this DNS resolution as another guess.

joe | 13 Oct 18:43

Re: Guessing root DNs for active directory

But make sure you qualify this as a "GUESS" or swag. As mentioned in my
previous response, the machine FQDN can be disjoint from the AD Domain. This
is fully supported by Microsoft (though occasionally their own apps screw it
up like MOM/SMS). I have seen it quite a few times out in corporate America,
especially in Fortune 5/10/50 level companies.  

It is usually when there is a long standing preexisting DNS implementation
and the company had good UNIX DNS people and said, we aren't changing our
whole structure just for Microsoft... Or alternately they didn't want,
understandably, to have 100,000 hosts in a single zone called something like
company.com or northamerica.company.com because of scaling or difficulting
in delegation, etc. Doesn't matter why, could even be because the sky was
grey the day they designed the DNS hierarchy, the point is that it could be
that way so be aware.

What this means from an example standpoint is that the FQDN of the machine
could be machinename.annarbor.mi.company.com but it could be a member of the
domain northamerica.company.com or even northamerica.ad or
northamerica.company.local or even subcompany.parentcompany.com...  If you
know the logical layout of DNS for a given company, then of course you might
be able to make the guess a bit more scientific, but in a truly generic "you
don't know what you are starting with" environment, you have to be very
careful with this.

While I am at it, something else I have seen people do when trying to guess
AD structure is that you also need to be careful about guessing the
hierarchy of the forest. AD allows for multiple domain trees, so if you see
northamerica.domain.com, there is no guarantee there is a domain.com, it may
in fact be someotherdomain.com that is the forest root. I.E. A structure
that looks like

     (forest root aka rootDomainNamingContext)

someotherdomain.com------------------------------------northamerica.domain.c
om
         |                                                           |
       execs.someotherdomain.com
hr.northamerica.domain.com

I have seen more than one script or utility that would run again
hr.northamerica.domain.com machine and then just assume the root of the
forest was northamerica.domain.com or even domain.com and then screw up
wildly. This can be particularly painful if you need to search the entire
directory for something. You can't specify either someotherdomain.com or
northamerica.domain.com as a base and search everything. So you need to
execute a subtree query against the GC port of a global catalog with a null
search base. Alternately, you can execute a query against the normal LDAP
port of the same type against a global catalog and specify the phantom root
server side search control.

To wrap up though... the proper way on Windows to get a bootstrap DC is to
query the DsGetDCName API. The proper way on other OSes is going to vary.

   joe

--
O'Reilly Active Directory Third Edition -
http://www.joeware.net/win/ad3e.htm 

-----Original Message-----
From: bounce-ldap-5210650@...
[mailto:bounce-ldap-5210650@...] On Behalf Of Justin
Dearing
Sent: Monday, October 13, 2008 12:00 PM
To: ldap@...
Subject: [ldap] Re: Guessing root DNs for active directory

On Mon, Oct 13, 2008 at 11:36 AM, Mark H. Wood <mwood@...> wrote:
> There's a DNS way to probe for LDAP (and Kerberos) services.
><snip/>
>
> That is:  if the machine is named "host.baz.bar.foo.xcorp.com" you 
> would try to resolve:
>
>  _tcp._ldap.baz.bar.foo.xcorp.com  SRV
>  _tcp._ldap.bar.foo.xcorp.com      SRV
>  _tcp._ldap.foo.xcorp.com          SRV
>  _tcp._ldap.xcorp.com              SRV
>
> When any SRV RRs are returned, they should point to the DCs for that 
> context.

That will be quite useful. Right now I have two "guesses" as to the ldap
server. I will add this DNS resolution as another guess.

Justin Dearing | 25 Oct 21:09
Gravatar

Re: Guessing root DNs for active directory

Mark,

Finally got to give this a try, One small mistake on your part. It's
_ldap._tcp.domain. Corrected queries below. Just pointing this out to
not fustrate anyone that finds this thread later.

On Mon, Oct 13, 2008 at 11:36 AM, Mark H. Wood <mwood@...> wrote:

> That is:  if the machine is named "host.baz.bar.foo.xcorp.com" you
> would try to resolve:
>
_ldap._tcp.baz.bar.foo.xcorp.com  SRV
_ldap._tcp.bar.foo.xcorp.com      SRV
_ldap._tcp.foo.xcorp.com          SRV
_ldap._tcp.xcorp.com              SRV


Gmane