Posted on 01-25-2019 12:50 PM
I've been trying to figure out a way to utilize this new service across our mac devices that still require LDAP user authentication. Has anyone else successfully got this to work?
Right off the bat I cannot figure a simple solution of injecting the certificates Google requires to a client and authenticate directly. So I started digging into the idea of running open directory and using stunnel. I ran into some road blocks configuring the .conf file and getting it to communicate to google. Is this the way to go? Or is there is better solution I am not able to find online?
Solved! Go to Solution.
Posted on 10-17-2022 06:30 AM
Posted on 04-10-2020 12:25 PM
Did you find a solution for this. I'm looking into the same scenario
Posted on 04-10-2020 01:01 PM
So I have been looking at this and you want to look at the new "Cloud Identity Providers" section. This document has details on pages 3-9. https://hcsonline.com/images/PDFs/Google_SSO.pdf If you ignore the SSO part this should get you the same functionality according to the docs as configuring an LDAP Server. The latest Admin guide has a section
https://docs.jamf.com/10.20.0/jamf-pro/administrator-guide/Integrating_with_Cloud_Identity_Providers.html
That says:
"Integrating with Cloud Identity Providers, which is similar to integrating with an LDAP directory service, allows you to do the following:
Look up and populate user information from the secure LDAP service for inventory purposes.
Add Jamf Pro user accounts or groups from the secure LDAP service.
Require users to log in to Self Service or the enrollment portal using their LDAP directory accounts.
Require users to log in during mobile device setup using their LDAP directory accounts.
Base the scope of remote management tasks on users or groups from the secure LDAP service."
So the only question I have remaining is if an Enrollment Customization can be configured that uses the Identity Provider ?
I can't answer that yet as I am still waiting for my Google Admins to approve the testing. If you get there before me please let me know.
Posted on 04-10-2020 02:17 PM
We do it with Okta, so you should be able to do with Google. That said I think the macOS may not have all the features that you hope it would bring. : )
C
Posted on 12-10-2020 10:07 AM
Posted on 12-11-2020 07:13 AM
Secure LDAP requires a mobile account and deep configuration of opendirectoryd. Given 2020 and SSO, probably not worth the time investment with solutions like native catalina SSO/Kerb connectors, JAMFConnect, etc that work off normal local accounts and dont have secureToken complexity with the bootstrap token.
Posted on 04-09-2021 08:29 AM
We want to stop binding to local AD in favor of using Google Workspace credentials. How would we configure the native catalina/bigsur SSO/Kerb connectors to use Google Workspace credentials to log into macOS?? Streamlining this into ABM enrollments to Jamf would be huge!!
Posted on 04-22-2021 12:14 PM
So my question for this overall process is in this statement "Require users to log in during mobile device setup using their LDAP directory accounts. Does JAMF mean the mobile device such as iPad do they mean the Mobile account Google Secure LDAP creates to keep the user account on the system in the event of loss of network connection.
Another question, is once the Google Secure LDAP mobile account is created on the local box, can the user sync local/server passwords if the LDAP password is changed?
Posted on 07-29-2022 07:48 PM
We deployed this solution last year &it is working properly with Google Secure LDAP. We are still using Mobile accounts. Once the user log in yes we set Jamf config to create mobile account locally on the computer. This account is working without syncing any user data and it is linked to the google Secure LDAP. If the users change their passwords it will be synced to the local Mobile account on the computer. This Solution is perfect as we don't need to pay any other module like Jamf connect but the question now is for how long does Apple will support directory service & when it will be discontinued? So far Monterey is supported but not sure about any changes apple will make in the future, Any ideas?
Posted on 08-13-2022 11:35 PM
This is exactly what I'm tying to accomplish. Do you happen to have any information on how you set this up?
Following the instructions posted in a link above looks like it would require some advanced scripting. Did you get into that? Anything you could share with me to get a baseline?
Posted on 08-14-2022 11:54 AM
Posted on 10-17-2022 02:45 AM
Jamf connect is not a free solution. Secure LDAP is. I can help if you need more info. Just contact me I would be happy to help. (ayoussef@cacegypt.org).
If anyone have another solution for the for macOS Ventura that would be helpful too.
Amira
Posted on 10-17-2022 06:30 AM
Posted on 10-17-2022 06:31 AM
Posted on 07-23-2024 07:16 AM
#!/usr/bin/managed_python3
from OpenDirectory import ODNode, ODSession, kODNodeTypeConfigure
from Foundation import NSMutableData, NSData
import os
import sys
# Reading plist
GOOGLELDAPCONFIGFILE = open(sys.argv[1], "r")
CONFIG = GOOGLELDAPCONFIGFILE.read()
GOOGLELDAPCONFIGFILE.close()
# Write the plist
od_session = ODSession.defaultSession()
od_conf_node, err = ODNode.nodeWithSession_type_error_(od_session, kODNodeTypeConfigure, None)
request = NSMutableData.dataWithBytes_length_(b'\x00'*32, 32)
request.appendData_(NSData.dataWithBytes_length_(str.encode(CONFIG), len(CONFIG)))
response, err = od_conf_node.customCall_sendData_error_(99991, request, None)
# Edit the default search path and append the new node to allow for login
os.system("dscl -q localhost -append /Search CSPSearchPath /LDAPv3/ldap.google.com")
os.system("dscl -q localhost -append /Contact CSPSearchPath /LDAPv3/ldap.google.com")
os.system("bash -c 'echo -e \"TLS_IDENTITY\tLDAP Client\" >> /etc/openldap/ldap.conf' ")
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>description</key>
<string>ldap.google.com</string>
<key>mappings</key>
<dict>
<key>attributes</key>
<array>
<string>objectClass</string>
</array>
<key>function</key>
<string>ldap:translate_recordtype</string>
<key>recordtypes</key>
<dict>
<key>dsRecTypeStandard:Automount</key>
<dict>
<key>attributetypes</key>
<dict>
<key>dsAttrTypeStandard:AutomountInformation</key>
<dict>
<key>native</key>
<string>automountInformation</string>
</dict>
<key>dsAttrTypeStandard:Comment</key>
<dict>
<key>native</key>
<string>description</string>
</dict>
<key>dsAttrTypeStandard:CreationTimestamp</key>
<dict>
<key>native</key>
<string>createTimestamp</string>
</dict>
<key>dsAttrTypeStandard:ModificationTimestamp</key>
<dict>
<key>native</key>
<string>modifyTimestamp</string>
</dict>
<key>dsAttrTypeStandard:RecordName</key>
<dict>
<key>native</key>
<string>automountKey</string>
</dict>
</dict>
<key>info</key>
<dict>
<key>Group Object Classes</key>
<string>OR</string>
<key>Object Classes</key>
<array>
<string>automount</string>
</array>
<key>Search Base</key>
<string>dc=HERE,dc=YOUR,dc=DOMAIN</string>
</dict>
</dict>
<key>dsRecTypeStandard:AutomountMap</key>
<dict>
<key>attributetypes</key>
<dict>
<key>dsAttrTypeStandard:Comment</key>
<dict>
<key>native</key>
<string>description</string>
</dict>
<key>dsAttrTypeStandard:CreationTimestamp</key>
<dict>
<key>native</key>
<string>createTimestamp</string>
</dict>
<key>dsAttrTypeStandard:ModificationTimestamp</key>
<dict>
<key>native</key>
<string>modifyTimestamp</string>
</dict>
<key>dsAttrTypeStandard:RecordName</key>
<dict>
<key>native</key>
<string>automountMapName</string>
</dict>
</dict>
<key>info</key>
<dict>
<key>Group Object Classes</key>
<string>OR</string>
<key>Object Classes</key>
<array>
<string>automountMap</string>
</array>
<key>Search Base</key>
<string>dc=HERE,dc=YOUR,dc=DOMAIN</string>
</dict>
</dict>
<key>dsRecTypeStandard:CertificateAuthorities</key>
<dict>
<key>attributetypes</key>
<dict>
<key>dsAttrTypeStandard:AuthorityRevocationList</key>
<dict>
<key>native</key>
<string>authorityRevocationList;binary</string>
</dict>
<key>dsAttrTypeStandard:CACertificate</key>
<dict>
<key>native</key>
<string>cACertificate;binary</string>
</dict>
<key>dsAttrTypeStandard:CertificateRevocationList</key>
<dict>
<key>native</key>
<string>certificateRevocationList;binary</string>
</dict>
<key>dsAttrTypeStandard:CreationTimestamp</key>
<dict>
<key>native</key>
<string>createTimestamp</string>
</dict>
<key>dsAttrTypeStandard:CrossCertificatePair</key>
<dict>
<key>native</key>
<string>crossCertificatePair;binary</string>
</dict>
<key>dsAttrTypeStandard:ModificationTimestamp</key>
<dict>
<key>native</key>
<string>modifyTimestamp</string>
</dict>
<key>dsAttrTypeStandard:RecordName</key>
<dict>
<key>native</key>
<string>cn</string>
</dict>
</dict>
<key>info</key>
<dict>
<key>Group Object Classes</key>
<string>OR</string>
<key>Object Classes</key>
<array>
<string>certificationAuthority</string>
</array>
<key>Search Base</key>
<string>dc=HERE,dc=YOUR,dc=DOMAIN</string>
</dict>
</dict>
<key>dsRecTypeStandard:Groups</key>
<dict>
<key>attributetypes</key>
<dict>
<key>dsAttrTypeStandard:CreationTimestamp</key>
<dict>
<key>native</key>
<string>createTimestamp</string>
</dict>
<key>dsAttrTypeStandard:GroupMembership</key>
<dict>
<key>native</key>
<string>memberUid</string>
</dict>
<key>dsAttrTypeStandard:Member</key>
<dict>
<key>native</key>
<string>memberUid</string>
</dict>
<key>dsAttrTypeStandard:ModificationTimestamp</key>
<dict>
<key>native</key>
<string>modifyTimestamp</string>
</dict>
<key>dsAttrTypeStandard:PrimaryGroupID</key>
<dict>
<key>native</key>
<string>gidNumber</string>
</dict>
<key>dsAttrTypeStandard:RecordName</key>
<dict>
<key>native</key>
<string>cn</string>
</dict>
</dict>
<key>info</key>
<dict>
<key>Group Object Classes</key>
<string>OR</string>
<key>Object Classes</key>
<array>
<string>posixGroup</string>
</array>
<key>Search Base</key>
<string>dc=HERE,dc=YOUR,dc=DOMAIN</string>
</dict>
</dict>
<key>dsRecTypeStandard:Mounts</key>
<dict>
<key>attributetypes</key>
<dict>
<key>dsAttrTypeStandard:CreationTimestamp</key>
<dict>
<key>native</key>
<string>createTimestamp</string>
</dict>
<key>dsAttrTypeStandard:ModificationTimestamp</key>
<dict>
<key>native</key>
<string>modifyTimestamp</string>
</dict>
<key>dsAttrTypeStandard:RecordName</key>
<dict>
<key>native</key>
<string>cn</string>
</dict>
<key>dsAttrTypeStandard:VFSDumpFreq</key>
<dict>
<key>native</key>
<string>mountDumpFrequency</string>
</dict>
<key>dsAttrTypeStandard:VFSLinkDir</key>
<dict>
<key>native</key>
<string>mountDirectory</string>
</dict>
<key>dsAttrTypeStandard:VFSOpts</key>
<dict>
<key>native</key>
<string>mountOption</string>
</dict>
<key>dsAttrTypeStandard:VFSPassNo</key>
<dict>
<key>native</key>
<string>mountPassNo</string>
</dict>
<key>dsAttrTypeStandard:VFSType</key>
<dict>
<key>native</key>
<string>mountType</string>
</dict>
</dict>
<key>info</key>
<dict>
<key>Group Object Classes</key>
<string>OR</string>
<key>Object Classes</key>
<array>
<string>mount</string>
</array>
<key>Search Base</key>
<string>dc=HERE,dc=YOUR,dc=DOMAIN</string>
</dict>
</dict>
<key>dsRecTypeStandard:OrganizationalUnit</key>
<dict>
<key>attributetypes</key>
<dict>
<key>dsAttrTypeStandard:AddressLine1</key>
<dict>
<key>native</key>
<string>street</string>
</dict>
<key>dsAttrTypeStandard:City</key>
<dict>
<key>native</key>
<string>l</string>
</dict>
<key>dsAttrTypeStandard:Comment</key>
<dict>
<key>native</key>
<string>description</string>
</dict>
<key>dsAttrTypeStandard:Country</key>
<dict>
<key>native</key>
<string>c</string>
</dict>
<key>dsAttrTypeStandard:FAXNumber</key>
<dict>
<key>native</key>
<string>facsimileTelephoneNumber</string>
</dict>
<key>dsAttrTypeStandard:Password</key>
<dict>
<key>native</key>
<string>userPassword</string>
</dict>
<key>dsAttrTypeStandard:PhoneNumber</key>
<dict>
<key>native</key>
<string>telephoneNumber</string>
</dict>
<key>dsAttrTypeStandard:PostalAddress</key>
<dict>
<key>native</key>
<string>postalAddress</string>
</dict>
<key>dsAttrTypeStandard:PostalCode</key>
<dict>
<key>native</key>
<string>postalCode</string>
</dict>
<key>dsAttrTypeStandard:RealName</key>
<dict>
<key>native</key>
<string>cn</string>
</dict>
<key>dsAttrTypeStandard:RecordName</key>
<dict>
<key>native</key>
<string>ou</string>
</dict>
<key>dsAttrTypeStandard:State</key>
<dict>
<key>native</key>
<string>st</string>
</dict>
<key>dsAttrTypeStandard:Street</key>
<dict>
<key>native</key>
<string>street</string>
</dict>
</dict>
<key>info</key>
<dict>
<key>Group Object Classes</key>
<string>OR</string>
<key>Object Classes</key>
<array>
<string>organizationalUnit</string>
</array>
<key>Search Base</key>
<string>dc=HERE,dc=YOUR,dc=DOMAIN</string>
</dict>
</dict>
<key>dsRecTypeStandard:People</key>
<dict>
<key>attributetypes</key>
<dict>
<key>dsAttrTypeStandard:AddressLine1</key>
<dict>
<key>native</key>
<string>street</string>
</dict>
<key>dsAttrTypeStandard:Building</key>
<dict>
<key>native</key>
<string>buildingName</string>
</dict>
<key>dsAttrTypeStandard:City</key>
<dict>
<key>native</key>
<string>l</string>
</dict>
<key>dsAttrTypeStandard:Country</key>
<dict>
<key>native</key>
<string>c</string>
</dict>
<key>dsAttrTypeStandard:CreationTimestamp</key>
<dict>
<key>native</key>
<string>createTimestamp</string>
</dict>
<key>dsAttrTypeStandard:Department</key>
<dict>
<key>native</key>
<string>departmentNumber</string>
</dict>
<key>dsAttrTypeStandard:EMailAddress</key>
<dict>
<key>native</key>
<string>mail</string>
</dict>
<key>dsAttrTypeStandard:FAXNumber</key>
<dict>
<key>native</key>
<string>facsimileTelephoneNumber</string>
</dict>
<key>dsAttrTypeStandard:FirstName</key>
<dict>
<key>native</key>
<string>givenName</string>
</dict>
<key>dsAttrTypeStandard:HomePhoneNumber</key>
<dict>
<key>native</key>
<string>homePhone</string>
</dict>
<key>dsAttrTypeStandard:JobTitle</key>
<dict>
<key>native</key>
<string>title</string>
</dict>
<key>dsAttrTypeStandard:LastName</key>
<dict>
<key>native</key>
<string>sn</string>
</dict>
<key>dsAttrTypeStandard:MobileNumber</key>
<dict>
<key>native</key>
<string>mobile</string>
</dict>
<key>dsAttrTypeStandard:ModificationTimestamp</key>
<dict>
<key>native</key>
<string>modifyTimestamp</string>
</dict>
<key>dsAttrTypeStandard:OrganizationName</key>
<dict>
<key>native</key>
<string>o</string>
</dict>
<key>dsAttrTypeStandard:PagerNumber</key>
<dict>
<key>native</key>
<string>pager</string>
</dict>
<key>dsAttrTypeStandard:PhoneNumber</key>
<dict>
<key>native</key>
<string>telephoneNumber</string>
</dict>
<key>dsAttrTypeStandard:PostalAddress</key>
<dict>
<key>native</key>
<string>postalAddress</string>
</dict>
<key>dsAttrTypeStandard:PostalCode</key>
<dict>
<key>native</key>
<string>postalCode</string>
</dict>
<key>dsAttrTypeStandard:RealName</key>
<dict>
<key>native</key>
<string>cn</string>
</dict>
<key>dsAttrTypeStandard:RecordName</key>
<dict>
<key>native</key>
<string>cn</string>
</dict>
<key>dsAttrTypeStandard:State</key>
<dict>
<key>native</key>
<string>st</string>
</dict>
<key>dsAttrTypeStandard:Street</key>
<dict>
<key>native</key>
<string>street</string>
</dict>
<key>dsAttrTypeStandard:UserCertificate</key>
<dict>
<key>native</key>
<string>userCertificate;binary</string>
</dict>
<key>dsAttrTypeStandard:UserPKCS12Data</key>
<dict>
<key>native</key>
<string>userPKCS12</string>
</dict>
<key>dsAttrTypeStandard:UserSMIMECertificate</key>
<dict>
<key>native</key>
<string>userSMIMECertificate</string>
</dict>
</dict>
<key>info</key>
<dict>
<key>Group Object Classes</key>
<string>OR</string>
<key>Object Classes</key>
<array>
<string>inetOrgPerson</string>
</array>
<key>Search Base</key>
<string>dc=HERE,dc=YOUR,dc=DOMAIN</string>
</dict>
</dict>
<key>dsRecTypeStandard:Users</key>
<dict>
<key>attributetypes</key>
<dict>
<key>dsAttrTypeStandard:Change</key>
<dict>
<key>native</key>
<string>shadowLastChange</string>
</dict>
<key>dsAttrTypeStandard:Comment</key>
<dict>
<key>native</key>
<string>description</string>
</dict>
<key>dsAttrTypeStandard:CreationTimestamp</key>
<dict>
<key>native</key>
<string>createTimestamp</string>
</dict>
<key>dsAttrTypeStandard:Expire</key>
<dict>
<key>native</key>
<string>shadowExpire</string>
</dict>
<key>dsAttrTypeStandard:GeneratedUID</key>
<dict>
<key>native</key>
<string>apple-generateduid</string>
</dict>
<key>dsAttrTypeStandard:ModificationTimestamp</key>
<dict>
<key>native</key>
<string>modifyTimestamp</string>
</dict>
<key>dsAttrTypeStandard:NFSHomeDirectory</key>
<dict>
<key>native</key>
<string>#/Users/$uid$</string>
</dict>
<key>dsAttrTypeStandard:Password</key>
<dict>
<key>native</key>
<string>userPassword</string>
</dict>
<key>dsAttrTypeStandard:PrimaryGroupID</key>
<dict>
<key>native</key>
<string>gidNumber</string>
</dict>
<key>dsAttrTypeStandard:RealName</key>
<dict>
<key>native</key>
<string>cn</string>
</dict>
<key>dsAttrTypeStandard:RecordName</key>
<dict>
<key>native</key>
<string>uid</string>
</dict>
<key>dsAttrTypeStandard:UniqueID</key>
<dict>
<key>native</key>
<string>uidNumber</string>
</dict>
<key>dsAttrTypeStandard:UserShell</key>
<dict>
<key>native</key>
<string>loginShell</string>
</dict>
</dict>
<key>info</key>
<dict>
<key>Group Object Classes</key>
<string>OR</string>
<key>Object Classes</key>
<array>
<string>posixAccount</string>
<string>inetOrgPerson</string>
<string>shadowAccount</string>
</array>
<key>Search Base</key>
<string>dc=HERE,dc=YOUR,dc=DOMAIN</string>
</dict>
</dict>
</dict>
</dict>
<key>module options</key>
<dict>
<key>AppleODClient</key>
<dict>
<key>Server Mappings</key>
<false/>
</dict>
<key>ldap</key>
<dict>
<key>Template Search Base Suffix</key>
<string>dc=HERE,dc=YOU,dc=DOMAIN</string>
</dict>
</dict>
<key>node name</key>
<string>/LDAPv3/ldap.google.com</string>
<key>options</key>
<dict>
<key>connection idle disconnect</key>
<integer>120</integer>
<key>destination</key>
<dict>
<key>host</key>
<string>ldap.google.com</string>
<key>other</key>
<string>ldaps</string>
<key>port</key>
<integer>636</integer>
</dict>
<key>man-in-the-middle</key>
<false/>
<key>no cleartext authentication</key>
<false/>
<key>packet encryption</key>
<integer>3</integer>
<key>packet signing</key>
<integer>1</integer>
</dict>
<key>template</key>
<string>LDAPv3</string>
<key>trusttype</key>
<string>anonymous</string>
<key>uuid</key>
<string>YOUR UUID</string>
</dict>
</plist>
I personally created binary from the script (ldap.py) for connivance. You need a lot of python modules to be installed for it to run. After i created .pkg with ldap.google.com.plist, binary and postinstall script to run the binary. Sing it, load it into your prestage and you basically can login with Google LDAP for prestage user creation. Its very simple just run .pkg and you're connected.