5

I am on a Unix host and am looking for a programatic way to determine the closest DC. Microsoft has an excellent article explaining how to perform the DNS lookup, and I am able to find the list of available DCs easily like this:

dig -t SRV _ldap._tcp.dc._msdcs.example.com

But regarding finding the closest, it explains:

After the client locates a domain controller, it establishes communication by using LDAP to gain access to Active Directory. As part of that negotiation, the domain controller identifies which site the client is in based on the IP subnet of that client. If the client is communicating with a domain controller that is not in the closest (most optimal) site, the domain controller returns the name of the client's site.

So far I have not been able to find where this "returns the name of the client's site" occurs during LDAP queries. Is there a particular query I should perform to get this, or some other technique that can be performed on a Unix host not joined to the domain?

EDIT: Thanks to Sim's pointer, I've learned how to find the correct DC once I know my site (in this example, "mysite" as part of example.com):

dig -t SRV _ldap._tcp.mysite._sites.dc._msdcs.example.com

But this leaves open the question of how to determine my site. Repeatedly the docs indicate that any DC I connect to will work this out for me, but I can't find the doc that says how it returns me the information. I've even tried sending DNS queries directly to DCs to see if they'll order the SRV results with my site on the top, but they don't.

3
  • Have you asked this question at StackOverflow?
    – Sim
    Oct 24, 2009 at 23:28
  • Funny you ask... I'm a regular contributor at SO, and this is the kind of question that would generally get referred here :D It's really about AD, LDAP and server configuration, not programming (though I will eventually write the solution in C).
    – Rob Napier
    Oct 24, 2009 at 23:36
  • Yes I realised that after reading the question more carefully.
    – Sim
    Oct 24, 2009 at 23:37

5 Answers 5

3

This TechNet article walks you through the logic of Finding a Domain Controller in the Closest Site if that helps.

Since you are on Unix have you looked at how Samba does this? It looks like this is done with CLDAP. This blog entry - Joining a Samba Domain might provide some more answers.

6
  • This link is a big step forward, and provides me critical information about the SRV records. I'm not expecting it all to be in DNS; clearly much of it is in LDAP calls. What is unclear is yet another reference like this one: "the domain controller looks up the client site on the basis of the client IP address by comparing the address to the sites that are identified in Active Directory, and returns the name of the site that is closest to the client." But how does it return the name of the site to the client?
    – Rob Napier
    Oct 24, 2009 at 23:50
  • From my very quick look it appears to be returning the site information via a CLDAP call. I'll have another look later when I have more time and see what I can find.
    – Sim
    Oct 25, 2009 at 0:58
  • Your pointer to (MS-)CLDAP finally led me down the right road. This looks like it will be complicated, but between Samba, OpenLDAP and Wireshark, I believe this protocol has been dissected enough for me to write some code against. Do you know of any way to bridge OpenLDAP to MS-CLDAP? Otherwise, I'll take that part of the question to SO. Thanks again; you probably saved me two days of research and wireshark.
    – Rob Napier
    Oct 25, 2009 at 2:19
  • Sorry Rob I can't help you with the OpenLDAP to MS-CLDAP bridge. I did find <a href="download.boulder.ibm.com/ibmdl/pub/software/dw/library/… Directory Domain Controller Location Service</a> while I was looking around though - more background info on CLDAP than anything. I'd say that the Samba mailing lists would be another place to ask.
    – Sim
    Oct 25, 2009 at 10:09
  • Thanks again. Helpful as always. It seems that this is a solvable problem, but far from a simple problem. The linked paper gave one more piece of the puzzle that will be important (DNS-compressed hostnames).
    – Rob Napier
    Oct 26, 2009 at 2:09
3

The whole algorithm looks like

  1. Resolve _ldap._tcp.dc._msdcs.example.com
  2. Select one according to rfc-2782
  3. Send LDAP Ping to it and read Client Site if returned
  4. Resolve _ldap._tcp.Client-Site._sites.dc._msdcs.example.com
  5. Select one according to rfc-2782

Done!

LDAP Ping is

ldapsearch -H CLDAP://server -b '' -s base '(&(NtVer=\06\00\00\00)(AAC=\00\00\00\00))' netlogon

then read it as NETLOGON_SAM_LOGON_RESPONSE_EX. See here https://msdn.microsoft.com/en-us/library/cc223807.aspx

2

You can find an implementation of cldap in the source code of Samba in this file *./examples/misc/cldap.pl. Just call it with ./cldap.pl -d domain -s domaincontroller and you will get the SITENAME which you can use in further DNS queries. A MSDN Document: Domain Controller Response to an LDAP Ping

2

First of all get a list of domain controllers on the network(may or may not be closest).

nslookup -query=srv _ldap._tcp.example.net.local

You can then query one of them to find the name of your site based on your subnet.

ldapsearch -H ldap://dc123.example.net.local -b 'CN=Subnets,CN=Sites,CN=Configuration,dc=net,dc=local' '(cn=10.10.10.0/24)' siteObject

Make sure to replace the IP and subnet mask with the one of the machine you want to identify the nearest DC of.

You can then find the domain controllers that belong to that site.

nslookup -query=srv _ldap._tcp.sitename._sites.example.net.local
0

The python-active-directory appears to have some code that is able to perform the "LDAP ping" and parse the results.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .