Integrating Apple OSX Clients with an OpenLDAP Directory

Please note this was originally written in 2004 and I haven’t had a sysadmin job since 2009. It has been updated a number of times but is now quite out of date, hopefully it is still useful as a starting point. Also please note that it has recently been converted from MoinMoin to Dokuwiki syntax, if you find any mistakes please let me know. — Adam, August 2015

Where I work is primarily a Redhat Linux shop, with a smattering of Microsoft Windows, SGI Irix and Apple OSX. While we will remain primarily a Linux house for cost reasons, OSX is becoming an increasingly important part of our corporate workflow due to our dependence on quicktime, the increasing number of applications available and the increasing preference of both our artists and IT staff.

Because we already had a huge Linux infrastructure built I didn’t want to mess about with Netinfo or using an OSX Server as a bridge between our Macs and our LDAP authentication infrastructure. I wanted our Mac’s to play nicely in our existing world, this meant that authentication, naming (users, groups etc) and automount all had to work with as little fuss or differences as possible.

Assumptions

To keep this howto as simple as possible I had to make some assumptions:

  • That you are moderately familiar with LDAP or willing to struggle through the relatively steep learning curve before tackling this.
  • That you have admin/root privileges on at least one Mac and one Linux server.
  • You are capable of installing and configuring complex packages.
  • That you are using OSX 10.3/Panther as your client (I’m using 10.3.4).
  • That you are using running OpenLDAP 2.0 on a Linux server (I’m using OpenLDAP 2.0.21 on a Redhat Linux 7.3 box).

You may or may not have good luck following these directions with older or newer versions.

Setting Up the OpenLDAP Server

There are plenty of articles out there on setting up an OpenLDAP server, so I won’t go into that here. If you haven’t done this before the best article I’ve found is the Mandrake Secure article (a slightly more evolved version is available on the authors wiki). If you are unfamiliar with LDAP and still want to tackle this probably the single most useful thing you can do is install a good LDAP client and start browsing around to get a feel of how it works. I recommend PHP LDAP Admin as by far the best client I’ve used.

OSX can access normal user and group data so long as you configure it correctly. The hard part, and the almost completely undocumented part, is getting OSX automount to work. OSX comes with two options for automounting directories, AMD and the Apple proprietary automount. I only discuss the automount option because all our attempts at configuring AMD resulted in a horrible unstable mess.1We tried the AMD that shipped with Jaguar, with Panther and the latest version available from the AMD homepage.

  1. Setup and configure an OpenLDAP server.
  2. If possible make sure that you can authenticate to it from a Linux box and that everything works as expected before you continue any further.
  3. Add the apple.schema2I couldn’t get OpenLDAP to accept more recent versions of the apple.schema file. I ransacked the net for older versions and eventually found this one which seems to work. to you LDAP directory:
    1. Download the apple.schema.txt file.
    2. Copy it into your schema directory (normally /etc/openldap/schema).
    3. Because of the way that Apple wrote their automount schema definition, adding it requires that you disable schema checking in your OpenLdap configuration. To turn off schema checking you must add this line to your slapd.conf: schemacheck off.
  4. Restart OpenLDAP for the configuration changes to take effect, watch the logs carefully to make sure that the new schema file was not rejected.
  5. If you have already populated your LDAP directory make sure you have top level containers called ou=people, ou=group and ou=mounts. If you haven’t populated it I’ve included a sample LDIF file which you can use to get started.
  6. Using the sample LDIF as an example, add enough valid user, group and mount entries for you test your configuration.

Note: I have not yet followed the above steps to make sure they are correct and that I haven’t left anything out. If you encounter problems please let me know.

Configuring the Apple OSX Client

These instructions were written for OSX 10.3 (Panther) however they are still approximately correct for anything from 10.2 to 10.4. Once you understand how it works just follow your nose and it should be fairly straight forward.

  1. Open Directory Access (/Applications/Utilities)
  2. Enable the LDAPv3 Plugin
  3. Select the LDAPv3 Plugin and click “Configure”
  4. Click “New”
    1. Enable: tick
    2. Server: ldap01.spack.org
    3. LDAP Mappings: RFC 2307 (Unix)
    4. Search Base Suffix: dc=spack,dc=org
    5. SSL: unticked
  5. Click “Edit”
    1. [optional] Open/Close times out in: 10
    2. [optional] Connection times out in: 10
    3. Use authentication while connecting: unticked
    4. Encrypt using SSL: unticked
    5. Use custom port: unticked
  6. Now Click on “Search & Mappings”3As soon as you make any changes to the mappings, the “LDAP Mapping” will change from “Unix” to “Custom”. This is normal and to be expected.
    1. [optional] Click on “Users”
      1. In the “Search base” box enter ou=people,dc=spack,dc=org
      2. Tick “first level only”
    2. [optional] Click on “Groups”
      1. In the “Search base” box enter ou=group,dc=spack,dc=org
      2. Tick “first level only”
    3. [optional] Click on “Mounts”
      1. In the “Search base” box enter ou=mounts,dc=spack,dc=org
      2. Tick “first level only”
  7. Save back out to the main “Directory Access” screen.
  8. If you’ve made any mistakes now is the time to catch them, use the techniques in the below testing section to verify that you can see users, groups and mounts. If you find any problems you should fix them before you continue or risk an unusable system.
  9. Click on the “Authentication” tab.
    1. Select “Custom” from the “Search:” drop down menu.
    2. Click “Add” at the bottom of the screen.
    3. Select the “LDAPv3 …” option from the “Available Directories” screen.
  10. Exit “Directory Access” and save all changes.

Depending on the exact order you exit “Directory Access”, you may need to reboot for the changes to become live. It can be a bit quirky and I haven’t figured out exactly which things make a difference yet.

Testing

The best program to test your new directory service with is an OSX tool called dscl for “Domain Service command line utility”.4You can also do most of the queries using lookupd, the OSX resolver, however I’m lead to belive that lookupd is likely to be deprecated soon and that we’re all best off learning how to use dscl. If you’re interested a good article on using lookupd can be found here.

You can use dscl to either search all of the available sources for information (via the /Search/Users path) or you can manually specify which particular directory you wish to query (eg./LDAPv3/ldap.spack.org/Users. The difference between Users and People seems to be based on whether the data is keyed on username (uid) or full name (cn/gecos).

Hopefully some examples will make it clear:

## to list only LDAP users
# dscl localhost list /LDAPv3/ldap.spack.org/Users
adam
ben
bill
paul
...<snip>...

## to list all available users (local, LDAP, NIS, whatever)
# dscl localhost list /Search/Users
adam
ben
bill
paul
...<snip>...

# dscl localhost list /LDAPv3/ldap.spack.org/People
Adam Shand
Ben Foo
Bill Bar
Paul Gaz
...<snip>...

# dscl localhost read /LDAPv3/ldap.spack.org/Groups/staff
cn: staff
gidNumber: 10
memberUid: adam ben bill paul
objectClass: posixGroup top
AppleMetaNodeLocation: /LDAPv3/ldap.spack.org
GroupMembership: adam ben bill paul
Member: adam ben bill paul
PasswordPlus: ********
PrimaryGroupID: 10
RecordName: staff

# dscl localhost read /Search/Users/adam
cn: Adam Shand
gecos: Adam Shand
gidNumber: 105
givenName: Adam
homeDirectory: /home/adam
loginShell: /bin/bash
objectClass: top person organizationalPerson inetOrgPerson account posixAccount shadowAccount inetLocalMailRecipient kerberosSecurityObject
sn: Shand
uid: adam
uidNumber: 364
AppleMetaNodeLocation: /LDAPv3/ldap.spack.org
NFSHomeDirectory: /home/adam
PasswordPlus: ********
PrimaryGroupID: 101
RealName: Adam Shand
RecordName: adam
UniqueID: 364
UserShell: /bin/bash

# dscl localhost read /LDAPv3/ldap.spack.org/Mounts/netapp\\:\\/vol\\/vol0\\/home
cn: rhun:/vol/vol0/home
mountDirectory: /home
mountOption: nodev intr hard nfsv3 resvport wsize=8192 rsize=8192
mountType: nfs
objectClass: mount
AppleMetaNodeLocation: /LDAPv3/ldap.spack.org
PasswordPlus: ********
RecordName: rhun:/vol/vol0/home
VFSLinkDir: /home
VFSOpts: nodev intr hard nfsv3 resvport wsize=8192 rsize=8192
VFSType: nfs

If the above works as expected then you should be able to:

  • Log into your OSX box with a username and password that only exists in LDAP.
  • Finger users that only exist in LDAP (e.g. finger -m <username>).
  • Change directories into a network mount location and have it automatically mounted (e.g.. cd /home/adam). This works for home directories as well.
  • Do an ls -l on a file owned by an LDAP user and group and have the uid/gid resolve into proper names.

Trouble Shooting

  • Debugging OSX: I heartily recommend that you turn the debugging up as high as possible. The best way to do this on the client side is to add a line like this to your /etc/syslog.conf and then restart syslog:5Remember that syslog requires tabs not spaces between so don’t cut and paste the below.

    *.* /var/log/debug.log
  • Debugging LDAP: If you are having trouble understanding why OpenLDAP is behaving the way it is, or why client queries don’t seem to be work as you expect, it’s very useful to fire it up in debug mode where it prints everything it’s doing to the screen. To do this stop your LDAP service and run slapd -d 255.
  • LDAP ACLs: Access control lists in LDAP are powerful, complicated and confusing. I recommend you don’t configure any ACL‘s until after you have everything tested and working. After that enabled them one at a time and test copiously to make sure you haven’t introduced unexpected problems.
  • NFS Locks: If you NFS mount your users home directories you may find that your users experience random application hangs, especially applications which use the Addressbook.app. The way to resolve this is disable NFS locking. You can do this either by downloading Marcel Bresink’s [NFS Manager] or by editing /etc/hostconfig and changing the NFS locking line to look like NFSLOCKS=-NO- (you have to reboot for the change to take effect).

Further Thoughts

  • Automount Quirks: The Apple automount doesn’t support a few standard automount features, we’ve worked around them in various ways.
  • The special directory /net (or /hosts in Irix land) allows you to mount any available share by simply changing into a /net/<hostname>/<share> style directory. While not ideal, the best solution I’ve found is to reshare /net from an Linux server via Samba. OSX clients can then get similar functionality by manually mounting the Samba share.
    • Actually, you can mkdir /net and add -m /net -host to the second automount line in /System/Library/StartupItems/NFS to get the /net behavior, or better yet, copy that item to /Library/StartupItems before modifying it so your changes don’t get overwritten. – Anonymous Comment
      • The above doesn’t seem to work on Intel Macs, anyone got any ideas? — Colin Aspin (caspin at mac.com)
  • Wildcard mapping using the * and & characters is typically used by autofs for home directories. The work around is to simply mount all of your home directories rather then rely on the wildcard mapping to mount just the required user home directories. This works fine, but it means that an accidental ls /home can be quite slow.
  • When getting automount maps from LDAP, automount doesn’t seem to be able to create required parent directories (so if you are automounting /foo/bar, you must make sure that the /foo directory exists when automount starts).
  • Automount keys mounts off of the source name instead of the destination name. This is silly since you sometimes have legitimate reasons for having the same share mounted at different points in your filesystem (but by definition can’t mount two shares at the same point in your filesystem).
  • Optimizing Searches: You can make the searches for user, group and mount data a bit more efficient by telling “Directory Access” exactly where it can find the information it’s looking for (as opposed to the default of it searching from the top of the tree down for matching entries):
  • Updating Automount: Sadly automount isn’t capable of automatically rescanning the LDAP server for changes, if you make changes to the automount data in LDAP you must either reboot (ick!) or kill -HUP the automount process (there are two automount processes, you want the one with all the “-m” options and the one without the “-nsl”6The -nsl option isn’t documented in the man pages, but a kind reader has read the source and reported that NSL stands for “Network Services Location”. It is a method of automatically discovering available network shares using multicast DNS and SLP.
  • NFS Mount Options: OSX supports the usual NFS mount options but has two unusual ones. The first is “resvport”, this option is required for OSX to be able to mount shares from many NFS servers, as a general rule I recommend you always use it. The second is the “net” option, for the purposes of making an OSX box behave like a normal Unix box I recommend that you stay far away from it. If you want to learn more then Marcel Bresink’s excellent article is the best place to learn more.
  • Configure Slaves: Before you bring your new system into production I strongly recommend that you configure at least one LDAP slave. Because your new LDAP infrastructure will be responsible for all your authentication, naming and automounting needs, you really want the redundancy provided by a slave server.
  • Providing Redundancy with DNS: I name my master server ldap0.spack.org and my slaves ldap1.spack.org and ldap2.spack.org. I then create a DNS round robin called ldap.spack.org which points at all three addresses. Once you have this setup you should point your clients at the round robin alias ldap.spack.org. Now if one of your LDAP servers fails you can stop clients from talking to it by simply removing the failed server from the DNS round robin.
  • Better Redundancy: Better then a DNS round robin would be to provide redundancy with some sort of layer 7 aware proxy. I don’t know if any of the commercial switch providers offer LDAP aware load balancing switches. There may also be Open Source alternatives that I’m not aware of.
  • Linux AutoFS: The Linux automount daemon can also store it’s entries in the ou=mounts container of your LDAP directory. There does not seem to be any problem with the Linux mount entries coexisting with the OSX mount entries in the same ou.
  • Automation: I have some Perl scripts which will mirror the contents of the Linux auto.master and auto_* files into OSX automount format on an LDAP directory. If get permission, I will post them here.
  • SSL: Before deploying this you should make sure that all of your clients and servers are configured to talk to LDAP over SSL encrypted links.
    • Eamon Caddigan has kindly written in with what he did to make it work: Once unencrypted authentication was working, I followed these instructions for configuring the server to use SSL (part of the expanded Mandrake Secure guide already linked to your site). After restarting slapd, simply tick the “Encrypt using SSL” checkbox (“Use custom port” is left unticked because TLS uses the standard port) in the Directory Access app on the OS X client. Unless I’m missing something (very possible), that’s all there is to it.

Missing Pieces

  • Remove Mapping for Password: In the attribute mapping part, if you remove the password map then OSX will authenticate the user by binding to the LDAP server rather then doing a password comparision. This means your encryption method becomes transparent to your clients and you can get away from crypt. Untested.
  • Use DHCP Supplied LDAP Server: OSX supports getting it’s LDAP information from DNS, I have not successfully made this work yet and am a little confused about how you are supposed to configure it this way since “Directory Access” does it’s pathing seems to require that you know the name of the LDAP server the client will use. Here’s a snippet from a /etc/dhcpd.conf, though I still wonder how to specify two LDAP servers:

    option ldap-server code 95 = text;
    subnet 192.168.1.0
    netmask 255.255.255.0 {
      range 192.168.1.200 192.168.1.250;
      option routers 192.168.1.1;
      option domain-name "spack.org";
      option domain-name-servers 192.168.1.2,192.168.1.3;
      option ldap-server "ldap://192.168.1.2/dc=spack,dc=org";
    }
  • Write Mappings to Server: You can write your custom mappings to the server so that you don’t have to manually configure each client. I have managed to write the mappings to my server but have been unable to make the client pay any attention to them. There is some more information in this http://www.msec.net/advisories/dhcp_vuln.html security advisory.

Feedback

Problems with SSL on Tiger 10.4.4/10.4.5

From: Zhi-Wei Lu <zwlu AT ucdavis DOT edu> 
Subject: Re: OSX tiger fails to bind to OpenLDAP server with SSL
Date: February 16, 2006 6:53:26 PM GMT+13:00

Hi Adam,

Thank you for your quick response and encouragement. I did figure out the problem.
I think that it might be a BUG for tiger (10.4.4 and 10.4.5, upgraded today).

If I turn off the certificate checking in
/etc/openldap/ldap.conf with
TLS_REQCERT never

LDAPv3 with SSL works just fine.

If I turn on the certificate checking in
/etc/openldap/ldap.conf with
TLS_CACERT /Users/certificate_file

Then LDAPv3 with SSL fails miserably.

This is in strike contrast to this Apple instruction:
http://docs.info.apple.com/article.html?artnum=107178

I can verify the server key using my own CA public certificate with
"openssl s_client" and "ldapsearch" commands.  I am wondering where I can
submit the BUG report to APPLE.

Thanks again.

Thanks

  • Marcel Bresink for his fabulous documentation and software.
  • John Fieber for the right pieces of information and encouragement as I was about to give up. Also information on removing password record and testing with dscl.
  • Christian van der leeden for pointers to information on how to make OSX get information from DHCP and write attribute mapping information to LDAP.
  • Eamon Caddigan for information on SSL configuration.
  • All the MacOSX Hints readers who have contributed bits and pieces of information. Thanks everyone!
  • Zhi-Wei Lu for the solution to his problems with getting OSX to authenticate against an LDAP server using SSL.

Comments are closed.