[Tutorial] OpenLDAP server + Mac OSX clients

Lately I have been busy trying to get my Mac clients to bind to OpenLDAP. I found the learning curve of OpenLDAP very steep. Almost 2 years ago now I did some experimenting with OpenLDAP and quitted because of the lack of tutorials that actually worked at once. I hoped to find an install script that could take away the pain of the configuration. Right now I’ve written one myself and if you just came for that, go on and skip to the download section.

LDAP server with Mac, Windows & Linux clients

LDAP server with Mac, Windows and Linux clients

For people who have never heard of LDAP, Active Directory or Open Directory: you should probably just keep it that way. But if you’re very interested or just want to spend a lot of time frustrating yourself, please read on.

OpenLDAP is an open source implementation of LDAP, which stands for Lightweight Directory Access Protocol. It basically is a database that is optimized for reading and is mainly used for storing information about clients, users and groups.  A lot of Unix programs are written to support LDAP. For example Contacts, Mail and iCal from Apple can use LDAP to get contact information. Beside client programs, LDAP is also the basis of Directory protocols like Active Directory and Open Directory, protocols respectively developed at Microsoft and Apple.

Home Situation & OS X Server

Kernel PanicSince I try to centralize the data and information services in our home I setup a Mac OS X Server about a year ago. All computers in our home could login to this server to get the user home directories and shared data like photo’s, movies and our iTunes library. This way allowing my family to use whatever computer they needed (speed, word-processing), being able to switch computers and not having to buy fast computers only. But after a while, there was one computer short, so I let them login to the server as well. Making that machine a client and a server at the same time. That was a bad choice! Since I’m kind of a Hackintosh-guy the server was a Hackintosh running Snow Leopard Server. And although Mac OS X is a very stable operating system, sometimes things get screwed up. I think the problem was the unmounting of local NFS drives when logging out of the server, but I’m not sure on that one. Anyway, the server hangs sometimes with a “You need to restart your computer”-kernel-error-message and this being also the server meant all clients losing there connection to the home directories hanging all clients too. The situation had to be changed.

OpenLDAP versions

Since I’m also into open source and Apple announced that it would drop it’s Xserve line, raising questions about the persistence of OS X Server edition I decided to give up on OS X Server and go for OpenLDAP running on a Ubuntu Server.

I can’t say there aren’t any good tutorials out there for setting up an environment for Mac, Windows and Linux clients with OpenLDAP, but many of them are deprecated or contain errors. In the footer I’ve added some links to tutorials I followed myself as a reference. Since OpenLDAP 2.3 a configuration backend stored inside LDAP instead of in a file. All tutorials based on older versions sometimes are more specific on how to reach the same goals as I had, but where useless at the start of my LDAP-journey, since they used the old configuration method and my lack of knowledge of LDAP wasn’t enough to convert this to the new way.

As the time passed and as I was getting more frustrated of reinstalling LDAP over and over again I started to get to know LDAP better and by now I think I can say I understand LDAP quite well. Now the problem shifted to how to get Mac OS X to bind to LDAP and to get Workgroup Manager to edit and add users. I particularly wanted Workgroup Manager to work since it can be used to set some special settings on Mac clients based on the machines physical location, type, current user and group.

Schemas

The initial installation of OpenLDAP is nothing more than a single command

apt-get install slapd

slapd being the OpenLDAP daemon. But this is of course not enough to get things working. First you need to add the guidelines to how LDAP may store data. With LDAP this is actually completely up to you but when trying to get a program to bind to your database the makers of these programs actually made some guidelines themselves. They are called scheme’s and are located in /etc/ldap/schema but they need to be converted first. Schemas define what kind of sub nodes and attributes nodes in the directory can, need to or may have. Services like Samba and Apple’s Open Directory have there own schemas that can be found on every Mac since OS X in /etc/openldap/schema/apple.schema and /etc/openldap/schema/samba.schema.

The apple.schema heavily depends on samba.schema and samba.schema depends on other schemas as well. For my working setup only the following schemas were needed:

/etc/ldap/schema/cosine.schema
/etc/ldap/schema/inetorgperson
/etc/ldap/schema/nis.schema
/etc/ldap/schema/misc.schema
/etc/ldap/schema/samba.schema
/etc/ldap/schema/apple.schema

In the OpenLDAP distributions before version 2.3 you only needed to add an include to these .schema files. Since 2.3 you need to add them as LDAP data. Ldif files are the files in which modifications to the directory are stored. So the .schema files need to be converted to .ldif files. This is perfectly well explained by the guys from Ubuntu (search for schema_convert.conf) and I just included the final ldifs for a empty install in my install scripts, so you don’t need to make them yourself.

Adding these ldifs is easy and doesn’t require complicated commands.

ldapadd -Y EXTERNAL -H ldapi:/// -f cosine.ldif

This command needs to be called for every ldif of the schemas. The –Y tells the LDAP client which authentication protocol should be used and –H tells it which server should be used.

ALC

Now that LDAP knows to which guidelines it should test its requests to add data it’s time to define to where data will be written and which users can do this. I suggest that you work through the following code yourself if you want to or just read on since it is getting really interesting only after this is done. The following code is added to an empty ldif file and is added the same way as the schemas above. Inside the code are variables ($var) since I’ve taken the code straight from my one-minute-install script. $dn is the root bind path (e.g. dc=example,dc=com) and $rootdn is the path to the root user (e.g. uid=diradmin,ou=users,dc=example,dc=com).

# Load dynamic backend modules
dn: cn=module{0},cn=config
objectClass: olcModuleList
cn: module{0}
olcModulePath: /usr/lib/ldap
olcModuleLoad: {0}back_hdb

# Create directory database
dn: olcDatabase={1}hdb,cn=config
objectClass: olcDatabaseConfig
objectClass: olcHdbConfig
olcDatabase: {1}hdb
olcDbDirectory: /var/lib/ldap
olcSuffix: $dn
olcRootDN: cn=$usernm,$dn
olcRootPW: $passwd
olcAccess: {0}to attrs=userPassword,shadowLastChange by dn="cn=$usernm,$dn" write by dn="$rootdn" write by anonymous auth by self write by * none
olcAccess: {1}to dn.base="" by * read
olcAccess: {2}to * by dn="cn=$usernm,$dn" write by dn="$rootdn" write by * read
olcLastMod: TRUE
olcDbCheckpoint: 512 30
olcDbConfig: {0}set_cachesize 0 2097152 0
olcDbConfig: {1}set_lk_max_objects 1500
olcDbConfig: {2}set_lk_max_locks 1500
olcDbConfig: {3}set_lk_max_lockers 1500
olcDbIndex: uid,gidNumber,sambasid,uidNumber pres,eq
olcDbIndex: cn,sn,mail,givenName,memberUid pres,eq,approx,sub
olcDbIndex: objectClass eq
olcDbIndex: apple-group-realname,apple-realname pres,eq,approx,sub
olcDbIndex: apple-generateduid,apple-group-memberguid,apple-ownerguid pres,eq

dn: cn=config
changetype: modify
dn: olcDatabase={-1}frontend,cn=config
changetype: modify
delete: olcAccess

dn: olcDatabase={0}config,cn=config
changetype: modify
add: olcRootDN
olcRootDN: cn=$usernm,cn=config

dn: olcDatabase={0}config,cn=config
changetype: modify
add: olcRootPW
olcRootPW: $passwd

Population

Right now the directory is ready to be filled up with a default structure. Linux and Samba basically only need a group and user path but Mac OS X needs a complete tree for it’s own for it to bind so that will be added, as well as a root user. The ldif code for populating the directory can be found in install_ldap.sh by searching for “Mini DIT” but basically this structure is added

|- com
|- example
| - mounts
| - groups
| - users
|     | - diradmin
| - macosx
|     | - computers
|     | - computer_lists
|     | - config
|     | - <<and a lot more>>

All users are stored in com>example>users and groups are stored in com>example>groups. Apple needs a separate tree to store specific information and especially the config section in macosx is interesting.
Directory tree

Binding and authentication

When trying to bind a Open Directory server to Mac OS X you need Directory Utility, which is a very user friendly but time consuming tool to map attributes in LDAP to attributes of users and groups in the OS. These settings can also be fetched directly from LDAP and because of that I’ve added a macosxodconfig node, which contains all the binding info. When the install script is run this is added to the description attribute of this node and when you add the server to Directory Utility you should choose “Fetch from server” or something like this and specify ou=macosxodconfig,cn=config,ou=macosx,dc=example,dc=com when you asked for the location of the configuration. Most of the information about binding I got from a old tutorial from Sirius.

Adding LDAP server in Directory Utility: select Fetch from server

Set search base to ou=macosxodconfig,cn=config,ou=macosx,dc=example,dc=com

When the configuration is read from the server you’re actually ready to go. Which means you can login with accounts in LDAP and use Workgroup Manager. To check if things are working you should first look in the System Preferences > Accounts > Login options > Network account servers > Edit to see if the light is green. If it’s not, please check if you can ping your server, there is probably a connection issue.

If the light is green you should move to Terminal and try the command `id <username>` where username is a user that only exists in LDAP. You should get a response like:

uid=1000(diradmin) gid=80(admin) groups=80(admin),402(com.apple.sharepoint.group.1),62(netaccounts),12(everyone),404(com.apple.sharepoint.group.3),401(com.apple.access_screensharing),403(com.apple.sharepoint.group.2)

Then you should check if you can change the user to this user by typing `su <username>` and you should now see a new bash prompt. Congratulations, you just logged in to your new LDAP server from Mac OS X.

Using the script

The script is written for a freshly installed Ubuntu 10.04 LTS setup without slapd (since the script will take care of that) and needs to be executed as root or with sudo rights as it needs to use apt-get. So:

sudo ./install.bash

My script first asks for several variables that are needed for the setup and then executes another script that does the installing. First we want to now a username for the Directory Administrator that will be the person that can change passwords and add records, most often this username is “diradmin” and you should probably choose a very long and complicated password for this user.

For installing LDAP you also need a base domain name, a FQDN, Fully Qualified Domain Name, which should look like dc=example,dc=com but can also be longer or shorter, containing at least one dc. You should really think about this as you can’t change this later on and it will be omnipresent. The domain name doesn’t needs to be legit (e.g. end on dc=com or dc=co,dc=uk) but you should make sure nobody else can register the domain if it is legit.

After you agree to the information the server will be automatically setup. Only thing left to do is to add the server to the configuration of the clients using System Preferences > Account > Login options > Network account servers > Edit.

If you like my post, my script or have any comments or suggestions, feel free to leave a comment below.

Download

The scripts can be downloaded here. The zip contains 8 files and 1 folder:

install.bash
install_scripts
 - install_ldap.sh
 - apple.ldif
 - cosine.ldif
 - inetorgperson.ldif
 - misc.ldif
 - nis.ldif
 - samba.ldif

Resources

A great tutorial on adding Mac OS X support to OpenLDAP:
Sirius IT: OS X and taming the Leopard
An install script for LDAP without support for longer DN’s and no support for Mac OS X. Used as reference.
GHacks: Set up your LDAP server on ubuntu
Used this to find out which indexes to add on the directory for fast Workgroup Manager usage.
Netmojo: Integrating Leopard server with Unix

31 Comments.

  1. Does iCal server works in this configuration?? I mean… does it grant access to LDAP users?

    • Herman Banken

      Do you mean a iCal server configured on a Mac OS X server authentication to this Linux box? Since this ain’t a OS X server. It is just a Linux server for authentication and additional services can be installed later.

      Currently I’m working on an update for this post/script. The new version will add support for LDAPS (using StartTLS) and will configure Kerberos too.

      Maybe I will add a section about mail, nfs, afp, bonjour services and maybe a calendar server to since it’s my plan to implement these services at home. But currently i’m still working on Kerberos, which is a pain in the ****.

  2. Thanks for the tutorial! I installed slapd using the script , I can add the LDAP server with the Directory Utility. However, I can’t authenticate using Workgroup Manger. What version of the Max OS X Server Admin Tools are you using? Could it be that I have to unblock certain ports on the Ubuntu Server?
    Thanks!

    • Herman Banken

      Hey Daniel,

      Thanks for stopping by at my blog!
      I recently tried to use the script myself and had the exact same error, which I didn’t had when I installed it the first time. Right now I’m working on a second version of the script, which should install the following services: LDAP, Kerberos, Samba, NFS/AFP, SMB, Bonjour/Avahi.

      Currently I’m stuck at Kerberos, but I’m sure that combined with Samba this will be the hardest part. And when I get it to work the complete script wont be to much work. NFS/AFP, SMB and Avahi are peanuts compared to LDAP, Kerberos and Samba.

      Hopefully it won’t be a problem for you to wait a little while. If it is, you can always comment on this reaction. I suggest you try running the following commands and post their outputs:

      id [username of directory administrator]
      su [username of directory administrator]

      If these commands succeed authentication works and you can login accounts. You should be fine, just (temporaly) without the ease of Workgroup Manager. You could try Apache Directory Studio to edit the records. When I update my post I will pay attention if authenticating with WGM works.

  3. I would love to know how to get workgroup manager working with openldap… that’s the only real thing i can’t manage to do it seems… the voodoo that isn’t documented. can you post an ldif just for the admin user? does the user need to be a sudoer?
    thanks!

    • Herman Banken

      Hi Rob, as you can read in the previous comments, this still is a work in progress. Right now, I don’t know exactly what I did to get WGM working.

      From your comment I can’t determine if you got WGM to at least view the directory. Can you? My problems are related to authenticating WGM, since all the secure protocols are quite difficult to get working.. but I can see all users, groups, computers in the directory.

      Of course, the main purpose of WGM is to administer the per-user/computer/group preferences in the MCX records and when only being able to view users, you can’t edit MCX records. I know that and I want to fix it too.

      The fact WGM authenticates on a official OS X Server by submitting the username and not the DN of the user and it’s password means, I guess, authentication is happening via the ldapsearch and specifically via the -U flag.. But I never got that working either. Have you?

    • Herman Banken

      Hi Rob, here is the ldif for my admin. Please note that I’m currently working on this and my current ldif may be different from the one that would be outputted after running the downloadable script. When I exported the ldif just a minute ago I saw I was using a secure connection, so clearly I’ve fixed that.. I haven’t worked on this for a while since I’ve been sick and very busy before that..

      The LDIF:
      dn: uid=diradmin,ou=users,dc=example,dc=com
      objectClass: inetOrgPerson
      objectClass: posixAccount
      objectClass: shadowAccount
      objectClass: organizationalPerson
      objectClass: apple-user
      objectClass: extensibleObject
      objectClass: person
      objectClass: top
      cn: Directory Administrator
      gidNumber: 80
      homeDirectory: /home/diradmin
      sn: Administrator
      uid: diradmin
      uidNumber: 1000
      apple-generateduid: ##### Unique UID, see script for how to generate one ####
      authAuthority: ;basic;
      givenName: Directory
      loginShell: /bin/bash
      title: System Administrator
      userPassword:: ##### Base 64 encoded SSHA password #####

    • Herman Banken

      Ok. So when replying to your post, I got interested again. I just found out the criterium that was stopping WGM from authenticating me: olcAccess rights!

      The user inside the ou=users DN must have olcAccess rights to write. This can be configured by editing the install script or by editing the cn=config afterwards. To do so you have to authenticate to the “cn=config” DN as the user “cn=[user],cn=config” using the appropriate password. Make sure the entry olcDatabase={1}hdb,cn=config has a attribute olcAccess as follows:
      {[number]}to * by dn="uid=[adminuser],ou=users,dc=example,dc=com" write by * read

      Otherwise WGM can’t edit and it looks like it can check such things.. I don’t know the ldap commands to check rights, but WGM obviously does.

    • Herman Banken

      Right now, my WGM isn’t working either. I still didn’t find out what the problem is but at sometimes it works, sometimes it won’t..

      You could try to add LDAP fields from an original Mac Server admin, one by one. I have a Hackintosh server somewhere, but I don’t have access to that machine till Sunday since it isn’t wired to the Internet.

    • Hi!
      I also had problems connecting with Workgroup Manager to the OpenLDAP-directory.
      After a lot of fiddling I found a tip somewhere and managed to connect:

      When trying to connect Workgroup Manager (looking at the login window) choose ‘Server’ -> ‘View Directories’.
      You will now see a line telling you tou are viewing your LDAP-directory but you are not authenticated.
      Click on the Lock to unlock and you might be able to connect correctly. I use ‘admin’ as username.

      Cheers! Joost

  4. Sean DiZazzo

    Thanks for the incredible help! You nailed it.

    I took it one step further and incorporated Samba as a PDC to create a functioning Single-sign-on system! Windows, Mac and Linux

    Let me know if you are interested.

    ~Sean

    • I also have some sort of Domaincontroller for Win and Mac build on Linux.
      I am *very* interested in Sean’s setup.

    • Herman Banken

      Cool! Yes if you want, I can give you an account on this blog so you can write a sequential. I have a fellow student who can tweet about it and generate high traffic numbers.

      Do you want an account?

      • Sean DiZazzo

        Ok. I’ll write it up. I have gone through the process three times by now and have gotten some of the bugs worked out. It’s not perfect by any means, but clearly works for single sign-on. Permissions and user ids across platforms on NFS, samba, cvfs work perfect.

        I’m trying to convince my boss to let me deploy it so I can really dig in and do some more development.

        It’s basically just a combination of a few different walkthroughs (and a few things I figured out.)

        • Sean,

          sounds very much like my setup (I went the same path(s) ).
          Will follow your posts and comment where relevant.

          Welcome! Cheers, Joost

  5. I would love to know more about Sean’s setup. That Rocks!!

  6. Arjen Hiemstra

    Wow this is exactly what i’m looking for! Except… I would like to run this on my synology :) and of course this is nog working with the scripts supplied. I have edited the scripts to circumvent the missing base64 package for synology and some other things. Thought the rest would be easy but not I am already stuck on probably SASL config, I get the following error message when entering this command:
    ldapadd -Y EXTERNAL -H ldap:/// -f cosine.ldif

    error:
    SASL/EXTERNAL authentication started
    ldap_sasl_interactive_bind_s: Unknown authentication method (-6)
    additional info: SASL(-4): no mechanism available:

    (when using ldapi:/// i get: ldap_sasl_interactive_bind_s: Can’t contact LDAP server (-1))

    Would be wonderful if you could help or give a hint!

    • Richard Migneron

      Hi,

      I get the same error on a QNAP NAS. I managed to replace the -Y EXTERNAL and -U ldapj:///, but I’m not getting very far either. Try with : ldapadd -x -D cn=$usernm,$dn -w “$pwplain” $tmpdir…

      Furthermore, on the QNAP, the OpenLDAP files are scattered around, not at the same place as mentioned in the script AND to make things worse, the seem to be using HDB not BDB as a database. And I get plenty of errors too.

      This is very hard to setup on the QNAP, not sure I’ll succeed !

      Cheers,

      Richard

  7. Hey Herman did you ever figure out how to get the workgroup manager working consistently?

    • Herman Banken

      My current setup works with Workgroup manager in a way. The admin user must be in the people ou. Right now I don’t have time to work on this, but this tip might help already.

      Also, things get more difficult with Lion: to support TimeMachine etc, we need an updated Netatalk AFP which I could not get build..

  8. This is exactly what I am looking for! I am following your steps with Debian Linux but unfortunately it stops working at the beginning while converting all my schemes to ldif files (I cant use yours, couldnt I?) Every scheme I would like to convert seems to be broken. Error messages like /etc/ldap/schema/apple.schema: line 332 objectclass: AttributeType not found: “acctFlags” appear. It is so annoying, could you please help me converting my schemes into ldif?

    Greets from Berlin!

    • Hi Marius,

      I searched on Google for you and found that acctFlags is an attribute from samba.schema. Are you converting schema’s to ldifs with a convertfile? The ordering is also important as these schema’s depend on eachother.

      If you’re doing everything correctly it should also work on Debian since Ubuntu is Debian++. As a last resort you could also remove these attributes (those that give errors) from the schema. Be carefull however to don’t do too much deleting, you actually need some attributes :wink:. Take a look at http://linacs.gmxhome.de/wiki/OpenLDAPClientOnMacOSX.html and search for ‘uncomment’. They describe which attributes to uncomment in samba.schema. However, doing so won’t make apple.schema work any better, as it is using those attributes.

      Hope you’ll get it running, good luck!

  9. Trying to get the script form http://lauriumwebdesign.nl/wp-content/uploads/OpenLDAP.zip but end up with a 404. Could you reupload it?

  10. David Neudorfer

    I keep getting the error;


    SASL/EXTERNAL authentication started
    SASL username: gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth
    SASL SSF: 0
    adding new entry "cn=module{0},cn=config"
    ldap_add: Naming violation (64)

    I’ve tried both the script, the newer one on github, and doing it manually. Whenever I try to ldapadd the ALC ldif file this is the error I get. Any suggestions?

  11. I am trying to run your script now, but the section that wants the base DN I don’t think takes into account a domain name that has numbers. I am with a school district, and my domain name contains numbers. When I enter my root DN containing numbers, I receive the error:

    The root that you entered doesn’t match the regex ^(dc=[a-z]+,)*(dc=[a-z]+)$.
    Please enter your directory’s root (e.g. dc=example,dc=com):

    How can I modify the script to support numbers for the DN?

    • You should add 0-9 in the regex. So adjust [a-z]+ to resemble [a-z0-9]+ and you should be fine!

  12. I used your script and everything works fine, except that the password for diradmin is not recognised. When try to “su diradmin” in terminal and write the password I always get a message: “Sorry”. I already did several clean installs and have the same problem. Any clue? Thanks!

  13. Denzil Pinto

    Hi after run your script on debian squeeze , i try to connect ldap user (diradmin) cannot connect through mac mini (os 10.8) it gives the message

    # id diradmin

    id: diradmin: no such user

Trackbacks and Pingbacks: