Finding closest Domain Controller through LDAP

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.


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.


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


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


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