You don’t have to use insecure clear text Simple BIND authentication for accessing your LDAP servers.
Get list of supported authentication mechanisms:
ldapsearch -h example.com -x -b "" -s base -LLL supportedSASLMechanisms
Kerberos GSSAPI Example:
kinit ldapsearch -v -Y GSSAPI -h example.com -b "DC=example,DC=com" "(sAMAccountName=someusername)"
ldapsearch -v -Y DIGEST-MD5 -h example.com -U someusername -R example.com -b "DC=example,DC=com"\ "(sAMAccountName=someusername)"
I was getting random AD plugin connection issues after joining to Active Directory. dsconfigad showed no errors, but sometimes I would not get a connection and I would have to rejoin. The problem turned out to be related to replication.
The AD plugin initially has no knowledge of which AD site and domain controllers are considered local to your subnet, so it discovers any domain controllers and contacts one to lookup the site information. During this process, and in general, the AD Plugin keeps an LDAP connection open to the domain controller. The AD plugin likes to reuse these LDAP connections, presumably for performance reasons. When it is time to actually add the computer to the domain, the AD Plugin reuses this existing connection. The problem is that this domain controller is not necessarily one within your AD site.
At this point, if the Mac is restarted or DirectoryService is killed, any new connections will be made to a DC in the subnet’s AD site, but if your computer was added to a non-local DC, the local DCs may have no knowledge of your computer because the computer account has not yet replicated to them.
This problem can appear to be quite random because sometimes you’ll get lucky and get a local DC for the join, or you might catch the replication at the right time. You might also see bad password errors in the DirectoryService debug logs. I have filed a bug report on this, and I don’t have a good workaround for now other than — don’t reboot or restart DirectoryService after a join. Of course if you know your replication schedules, you could just wait until you are sure replication is completed.
This same issue can present itself with unjoins and rejoins.
You can see what domain controllers you are connecting to during the join using the following shell command assuming your are joining using dsconfigad:
while [ 1 ]; do if netstat -a | grep ldap| grep ESTAB; then ps auxww | grep dsconfigad | grep -v grep; date;fi; done
If you have joined, unjoined, and rejoined and think you may be seeing replication issues, compare the whenCreated attribute of the computer account on different domain controllers using ldapsearch.
ldapsearch -LLL -v -W -x -h domaincontrollerfromsite1.subdomain.forest.com -D email@example.com -b "OU=Computers,DC=subdomain,DC=forest,DC=com" CN=machine-join-name | grep whenCreated:
If an older out of sync computer account exists, its whenCreated date will be different from the domain controller the computer was just added to until the last join has replicated to all the servers.
The slow login times in the Leopard AD plugin seem to be related to a search by macAddress. If you killall -USR1 DirectoryService, and login on a Leopard machine bound to AD, you’ll notice a query on macAddress in the /Library/Logs/DirectoryService/DirectoryService.debug.log. I am not sure the purpose of this query, but our computer objects don’t even use the macAddress attribute, so the query always results in no records found.
I can manually execute the same query and the time almost perfectly matches the delay I see with logins; about 45 seconds.
time ldapsearch -v -w password -x -h domaincontroller.domain.forest.com -D firstname.lastname@example.org -b "DC=domain,DC=forest,DC=com" "(&(objectCategory=cn=computer,cn=schema,cn=configuration,dc=forest,dc=com)
Just substitute your own domain, forest, domain controller, username, password, and mac address etc to test.
I’ve tried manually mapping macAddress to another attribute, but it didn’t make a difference, so I don’t have any workaround to offer. Adding the macAddress attribute to your computer objects in AD might speed things up, but I have not tested this. I’ve notified Apple of the issue in radar 5752763, which is marked as a Duplicate of 5679705. If you see this macAddress query taking a long time, please report this to Apple so it can get fixed sooner rather than later. Actually, this same query is used during the join process, which may explain the long join times while it searches for an existing computer.
The AD Plugin uses information in Sites in your Active Directory Configuration to get a list of Domain Controllers to use for LDAP and Kerberos connections. Sites are a method of configuring Active Directory based on a physical or network based location. Clients connecting to Active Directory use this information to determine which domain controllers are nearby and therefore likely to respond the fastest. Plus if you have Domain Controllers in remote or distant locations, without using Sites, you are pushing traffic over a WAN unnecessarily.
This is one of the steps you’ll see when joining a machine to AD. Locating Domain Controllers… or something like that.
First it uses DNS to lookup SVR records to locate ANY domain controller. You can do the same using the dig command:
dig any _kerberos._tcp.yourdomain.yourforest.com
This will give you a list of domain controllers to choose from. Once you have one of your domain controllers to talk to, you can read the same information that the AD Plugin does to figure out your Site by querying AD with ldapsearch and your subnet:
ldapsearch -x -h "somedomaincontroller.yourforest.com" -b "CN=Subnets,CN=Sites,CN=Configuration,dc=yourforest,dc=com" -D "email@example.com" -W "(cn=10.31.0.0/16)" siteObject
From this you will get your Site, which you can then use with ldapsearch again to get a list of domain controllers for your site:
ldapsearch -x -h "somedomaincontroller.yourforest.com" -b "CN=SERVERS,CN=YOURSITENAME,CN=Sites,CN=Configuration,dc=yourforest,dc=com" -D "firstname.lastname@example.org" -W dNSHostName | grep dNSHostName
Pretty cool. Takes some more of the mystery out of the AD plugin.
Notes: Enter each command as a single line. Substitute ‘yourdomain’ with your own domain and ‘yourforest’ with your own forest and ‘username’ with a your username for your domain and ’10.31.0.0/16′ with your own subnet and ‘YOURSITENAME’ with the site name you found in the previous step. Also, using ldapsearch in this way does a simple BIND authentication which sends your password in CLEAR TEXT. Change your password after using this command if you are in a secure environment.
Update: I was using this method recently and realized I was getting domain controllers that were in my site, but weren’t hosting my specific domain. If you want to get just the servers hosting your domain, you need to filter the ldapsearch like so, but you won’t get the fully qualified dNSHostName:
ldapsearch -x -h "somedomaincontroller.yourforest.com" -b "CN=SERVERS,CN=YOURSITENAME,CN=Sites,CN=Configuration,dc=yourforest,dc=com" -D "email@example.com" -W msDS-HasDomainNCs="DC=subdomain,DC=forest,DC=com" dn | grep dn: