Writing binding information programmatically on macOS Catalina and above
In macOS Catalina and Big Sur the /Library/Preferences/OpenDirectory/Configurations
folder appears to be protected by SIP or some other unknown protection mechanism. This leaves the common Open Directory binding installation of placing down the configuration plist files nonfunctional. This can be a hard stop when it comes to fully programmatically provisioning a machine via DEP, with the only workaround before discovering this method being using the Directory Utility GUI to manually enter the binding settings.
To further complicate things, Apple removed Python 2.7 starting with Monterey 12.3 (in fairness, after years of warning us they would do so). The folks at macadmins.org have packaged a purpose-built, self-contained python3 package for exactly this type of administrative need. Therefore, the Monterey version of this script has been modified to use python3 and requires that the python_recommended.pkg from macadmins be installed. Latest versions of this package, signed and unsigned, can be found here: https://github.com/macadmins/python/releases
In a typical Open Directory bind there are three main plist files contained within the Configurations directory, they are as follows:
LDAPv3/ldap.domain.contoso.com.plist
Search.plist
Contacts.plist
When analyzing which of these files are actually used for, the Configurations/ldap.domain.contoso.com.plist
defines the Open Directory server and contains the actual binding information. The Search.plist
defines the macOS user search space and hierarchies when an Open Directory user attempts to login to the device. Without the Search.plist
, while a machine may be bound in the technical sense, it will not let a user login. Lastly there is the Contacts.plist
. This as far as I can tell helps network user contact population and therefore isn't needed, but there is an optional step below to allow for it.
- To write the
ldap.domain.contoso.corp.plist
you have to use the LDAPv3Write.py script and execute it as follows:
python /path/to/LDAPv3Write.py /path/to/ldap.domain.contoso.com.plist
- To edit default
Search.plist
and append your OpenDirectory bind you run the following command:
dscl -q localhost -merge /Search CSPSearchPath /LDAPv3/ldap.domain.contoso.com
Optional: To edit default Contacts.plist
and append your OpenDirectory bind you run the following command:
dscl -q localhost -merge /Contact CSPSearchPath /LDAPv3/ldap.domain.contoso.com
- Add your OD/LDAP Authenticating user to the System keychain using the security command demonstrated below. This username must link to the authenticating user defined within your
ldap.domain.contoso.com.plist
:
security add-generic-password -a 'USERNAME' -s '/LDAPv3/USERNAME' -w 'pA$$WuRD' -A -T '' /Library/Keychains/System.keychain
- Reboot the machine
Your guess is as good as mine
I would recommend using the time the workflow has saved you into migrating to an identity provider that can be bound to using the dsconfigad
or dsconfigldap
binaries. If possible removing the binding in it's entirety. I'd recommend looking at NoMAD Login as a viable replacement option as long as there is the capacity to stand up an Active Directory DC.
For them to fix it you as an admin need to file feedback with them that this is an important workflow for you.
I will direct you to this email thread from 2009 which spells out how dsconfigldap
does not contain the capability to take in custom ldap attribute mappings.
I did not write this script. It was given to me with someone with very in depth knowledge of Apple Devices, but I was given approval to share it out.