AD Binding in Read Only Domain Controller environment

rihardsp
New Contributor III

Hi,

I know there is a large number of topics about AD binding, but I couldn't find a solution for my issue.

Long story short, what was working with El Capitan isn't working with Sierra anymore and that is specifying a DC to bind against.

Our organisation has an external data centre and a number of branch offices, which are all connected via VPNs. The only writable domain controllers are in the data centre, and in the branch offices we have read-only controllers. I was using configuration profile for AD binding where I specified a writable DC which was located in the data centre and all was working fine - computer object was created automatically in AD, and mac computer binded.
This doesn't work with Sierra. Same config, and I get an error. Tried directly with dsconfigad - and nothing.
If I create a computer object prior to binding, mac shows that it's binded, but the computer object isn't updated with computer info and dns, and 801.x profile for wifi isn't installed as a result of this. For binding tests I am using domain admin account, so all is good with permissions.

Currently the only option for binding a mac to AD is to connect the computer via VPN to the data centre and do the binding, but I need it to work directly from a branch local network.

Anyone has came across such issue and resolved this?

Thanks!

7 REPLIES 7

rihardsp
New Contributor III

Anyone?

talkingmoose
Moderator
Moderator

You mentioned a RoDC twice but said you're not pointing to that. How is it coming into play in your issue? Because this type of domain controller is immutable, you won't be able to use it for binding.

What were the errors you received using dsconfigad against a writeable DC? That's where you need to be collecting evidence. Was there anything in jamf.log about the failure? Is that server accessible? If so, has something changed with your binding account's credentials?

You might also see if you get more insight by manually binding using the Directory Utility.

bofh
New Contributor III

I guess you are using the

Prefer this domain server

setting in Directory Bindings?

Actually that didnt really work in previous versions aswell, we had a fail-rate of about 10%-20% while having 2x RODC and 3x DC.
This just got better after removing/promoting the RODC installations.

Here is our old script for binding. This was working a bit better then the "Active Directory Binding" via Policies or Configuration Profiles.
Maybe this will help you a bit, atleast for debugging

#!/bin/bash
#############
#
# LRZ - Manual Directory Bind
#
# last change: 15.01.14
# version: 1.0
# Usage: manualDirectoryBind.sh <directory-type> <domain> <preferred-server> <username> <password> <ou> <additional-parameters> <logfile>
#
#

###
### PRESETS
###
ADUSER=""
ADPASS=""
DSPlist="/Library/Preferences/DirectoryService/DirectoryService.plist"

if [ -f "/usr/local/jamf/bin/jamf" ]
then
    JAMF='/usr/local/jamf/bin/jamf'
else
    JAMF='/usr/sbin/jamf'
fi

###
###
###


# Mappings
type=${4}
domain=${5}
prefsrv=${6}
if [ "${7}" != "" ]
then
    username=${7}
else
    username=${ADUSER}
fi
if [ "${8}" != "" ]
then
    password=${8}
else
    password=${ADPASS}
fi
password=${8}
ou=${9}
parameter=${10}
logfile=${11}



if [ -f ${DSPlist} ]
then
    adstatus=`defaults read ${DSPlist} "Active Directory"`
    if [ "${adstatus}" == "Active" ]
    then
        echo "Already bound to Active Directory, exiting" >> $logfile
        exit
    fi
fi

echo "Checking ${prefsrv} (${domain}) if they are available"  >> ${logfile}
dcs=`nslookup ${prefsrv} | grep Address |grep -v "#" | tr -d 'Address: '`
for i in ${dcs}
do
        cping=`ping -c 1 $i`
        if [ "`echo ${cping} | grep timeout`" == "" ]
        then
                time=`echo ${cping} |grep round |tr '/' ' ' |awk '{print $35}'`
                echo "${i}: ONLINE (${time}ms)"  >> ${logfile}
        else
                echo "${i}: OFFLINE"  >> ${logfile}
        fi
done

echo "Binding Parameters:" >> ${logfile}
echo "Username: ${username}" >> ${logfile}
echo "Password: XXXXXXX" >> ${logfile}
echo "Domain: ${domain}" >> ${logfile}
echo "Preferred Servers: ${prefsrv}" >> ${logfile}
echo "Organsational Unit: ${ou}" >> ${logfile}
echo "Additional Parameters: ${parameter}" >> ${logfile}
echo "Logfile: ${logfile}" >> ${logfile}

echo "start Binding time: `date`"  >> ${logfile}
${JAMF} bind -type ${type} -domain ${domain} -username ${username} -ou ${ou} -password ${password} -preferredServer ${prefsrv}  ${parameter} >> ${logfile}
echo "finish Binding time: `date`"  >> ${logfile}

rihardsp
New Contributor III

So, I spent some time to understand how the binding works in a Mac. It's all known basically, but let's sum this up.

It doesn't matter what method you are using - GUI, policy, config profile or anything else - they are just wrappers to pass the commands to dsconfigad. All the errors or log entries are generated from the result of dsconfigad. In my case it's error 10001 with no additional information.

Dsconfigad does the following:

-1.queries the domain for domain servers (basically gets similar info as nslookup domain.name). If you specify a preferred server, it will be the server whom it queries the first. That's it, the rest of the communication is done based on what information it gets.

-2.queries the first DC from the list it got to get the list of _kerberos SRV records. Again, receives a list of random servers with _kerberos SRV records.

-3.Attempts to authenticate against the first server in the list using provided credentials and when succesful, queries the DC for domain schema information.

-4. Queries the DC to get contents of "Domain Controllers" OU

-5. Jumps across the AD forest like a bunny making different LDAP queries, like checking if the AD computer container already exists

-6. Eventually gets client AD zone information and if there is DC in the same zone

-7. If there is a DC in the same zone, it doesn't matter if it's a writable or read only, it connects to it and makes an attempt to write in to the specified AD computer container, or modify it.

-8. If it fails to write, the connection is closed. Done. No retries, no fallbacks no nothing.

In the attached screenshot you can see which properties it tries to write on 192.168.96.252, which is a local RODC, located in the same site as the client. The next line is the result - an error, and in the next line the connection is closed. In the LDAP language "bind" means "connect to LDAP", not actually bind the computer to AD.

So if Apple doesn't fix or update dsconfigad, it will remain like this. I cannot think of any workaround.

0e9bd9ef25784acc94c28b6012f7a38c

talkingmoose
Moderator
Moderator

@rihardsp, you've mentioned trying to bind to a read-only domain controller (RODC).

Binding a Mac to AD creates a computer record in Active Directory. I don't see how you can do this with a RODC because it's read-only. You need to bind to a normal domain controller with an AD account that has permission to bind and create computer objects in whatever Container or OU you specify.

guidotti
Contributor II

So you are saying, basically, that the command dsconfigad -preferred 'domain.company.net' is no longer working on Sierra/High Sierra?

rihardsp
New Contributor III

@talkingmoose Our main server infrastructure is located in external data centers, and there we also have the writable domain controllers. In the branches, where the macs are actually located, we have RODCs only.
"I" am not trying to bind to RODC, dsconfigad is. It's binding to the closest DC based on AD sites information no matter what. I cannot make it write to a DC in an other subnet where there are writable DCs.

@guidotti It's working, yes. But only for the initial DNS and domain lookup. Dsconfigad then receives a list of the domain DNS servers and servers with _kerberos SRV records, then connects to the first ones in the list to query the LDAP schema further, then goes to the closest DC based on AD site information to make or modify the record. If the closest one turns out to be a RODC, it just quits.