[Network Administration]: LDAP and OS X

I’ve gotten my LDAP directory up and running. It’s serving out the directory information, and I’ve been able to login on my Linux machine. Now, I want to get logins and home directories available on my OS X machines. This is some really good information out there on getting this working. Most of what is here is cobbled together from these sources among others:
Mac OS X Server Open Directory Adminstration for Snow Leopard
BackupCentral’s LDAPand Austofs for Ubuntu and Snow Leopard
Rajeev Karamchedu’s excellent writeup for integrating OS X and LDAP

At it’s most basic, the current LDAP entries will work with the following information (which is generated for the linux accounts setup by default on Ubuntu):

objectClass: inetOrgPerson
objectClass: posixAccount
objectClass: shadowAccount
uid:
cn:
uidNumber:
gidNumber:
homeDirectory:
password:

However, there is a number of extended attributes that apple uses that are included in the apple schema. I followed this writeup to get the additional apple attributes working.

I did have to make some changes to the apple.schema from my Snow Leopard schema file. First I uncommented the apple-user-homeDirectory attribute type. I also needed to add it the apple-user object class so that it could use it. Secondly, I needed to move the authAuthority attribute above the apple-user object class so that it could use it (this one is pointed out in some other blog posts). And lastly, I needed to comment out the automount attributes and object classes. These are already present in the rfc2307bis schema. Once I made the changes were made, I was able to convert them to LDIF files.

This perl script should be able to do the LDIF conversion. (Only checked it superficially. I had used slapcat to convert the schema to LDIF and did the rest by hand, but felt that was too roundabout.)

#!/usr/bin/perl

use strict;

open(FILE, $ARGV[0]);

my $schema = $ARGV[0];
$schema =~ s/.schema//;

print “dn: cn=${schema},cn=schema,cn=config\n”;
print “objectClass: olcSchemaConfig\n”;
print “cn: ${schema}\n”;

# turn blank lines into comments
while () {
if (/^#/) {
# Leave comments as is
print $_;
}
elsif (/^\n/) {
# Convert blank lines into comments
print “#\n”;
}
# Convert to olc naming
elsif (/\s*object[iI]dentifier(.*)/) {
print “olcObjectIdentifier: ${1}\n”;
} elsif (/\s*object[cC]lass(.*)/) {
print “olcObjectClasses: ${1}\n”;
} elsif (/\s*attribute[tT]ype(.*)/) {
print “olcAttributeTypes: ${1}\n”;
}
# Convert TAB to space
elsif (/\t*(.*)/) {
print ” ${1}\n”;
}
# Otherwise do nothing
else {
print $_;
}
}

One frustration that I did encounter was that all logins subsequent to the first login would fail with LDAP accounts.
From the /var/log/secure.log I got this:

Jan 7 15:45:57 mac SecurityAgent[8866]: Could not get the user record for user from DirectoryServices.
Jan 7 15:45:57 mac SecurityAgent[8866]: Will sleep 1 seconds and try again (retryCount = 4)
Jan 7 15:45:58 mac SecurityAgent[8866]: Could not get the user record for user from DirectoryServices.
Jan 7 15:45:58 mac SecurityAgent[8866]: Will sleep 2 seconds and try again (retryCount = 3)
Jan 7 15:46:00 mac SecurityAgent[8866]: Could not get the user record for user from DirectoryServices.
Jan 7 15:46:00 mac SecurityAgent[8866]: Will sleep 4 seconds and try again (retryCount = 2)
Jan 7 15:46:04 mac SecurityAgent[8866]: Could not get the user record for user from DirectoryServices.
Jan 7 15:46:04 mac SecurityAgent[8866]: Will sleep 8 seconds and try again (retryCount = 1)
Jan 7 15:46:12 mac SecurityAgent[8866]: User info context values set for user
Jan 7 15:46:12 mac SecurityAgent[8866]: unknown-user (user) login attempt PASSED for auditing

Anyway, it turned out that Airport was setup to turn-off on logout.
BTW, to enable debug of DirectoryServices, the following needs to be executed

sudo killall -USR1 DirectoryService

Advertisements

[Network Administration]: Automount maps in LDAP

I’ve got my LDAP server up and running based on the previous post. I’ve got my home directories that I’ve placed on the Synology NAS. What I would like to do is automount them when needed. I’m going to load these from the LDAP server so that I can have just one location for the automount maps.
I’m using the rfc2307bis schema for my LDAP server, so it’s already got all of the automount objectclasses already defined in there. I’m going to use those.
I’m going to be starting with the Ubuntu autofsLDAP doc with some changes for using the objectsclasses automountMap and automount in rfc2307bis. The class automountMap is essentially the map file that would reside on the machine (with automountMapName being the filename), and automount is the entry in the map (automountKey is the key from the map file, and automountInformation is remainder – options and location from the map). Couple of quick notes, the /home map is an indirect map since we’re going to be using wildcards, and in the LDAP entries, the wildcard for the key is “/” and not “*” like the filethe wildcard for the linux autofs can be either “/” or “*”. It appears to handle either character, whereas the OS X autofs supports just the “*” as the wildcard. Also, I’m going to be loading the OS specific home directory from the NAS. So for linux machines, I’m going to mount /Linux off the NAS, and for OS X, I’m going to mount /Darwin off of the NAS. This way the two don’t get overly cluttered with the OS files for both. This is determined using the ${OSNAME} variable in the last DN.
[Update: 1/25/2013]: You can mount the OS specific home directory if you want using the ${OSNAME} variable. I’m using a single directory for linux and OS X and am going to merge the desktops and the shell initialization scripts for both. Also, I’m going to convert to using the Sun names for the maps as auto_master instead of auto.master.
Here is my LDAP tree for the autofs:

## This is the branch for automounter
dn: ou=autofs,ou=daemon,dc=ldap,dc=server,dc=tld
ou: autofs
objectClass: top
objectClass: organizationalUnit

## This defines the auto_master
dn: automountMapName=auto_master,ou=autofs,ou=daemon,dc=ldap,dc=server,dc=tld
objectClass: top
objectClass: automountMap
automountMapName: auto_master
description: master table for automounter

## This is the entry in the master map (auto_master)
dn: automountKey=/home,automountMapName=auto+master,ou=autofs,ou=daemon,dc=ldap,dc=server,dc=tld
objectClass: top
objectClass: automount
automountKey: /home
automountInformation: auto_home
description: indirect map auto_home for account homes

## This defines auto_home
dn: automountMapName=auto_home,ou=autofs,ou=daemon,dc=ldap,dc=server,dc=tld
objectClass: top
objectClass: automountMap
automountMapName: auto_home
description: home directories table for automounter

dn: automountKey=*,automountMapName=auto_home,ou=autofs,ou=daemon,dc=ldap,dc=server,dc=tld
objectClass: top
objectClass: automount
automountKey: *
automountInformation: -fstype=nfs,rw,atime,sync filer-01:/volume1/accounts/&
description: mapping for nfs mount of home dirs

On one machine, I want to have access to all of the exports off of my synology NAS, so for the auto.master map table, I’m not going to use the LDAP entries for that. Also, I have some local mounts that I want to use autofs for. I’m going to be using the file in the filesystem for that instead of the directory map. I’ve modified the auto.master file from

+auto.master

to look like

# Don’t look for the table in the directory server
#+auto_master
#use the builtin map to load all the exports from the nfs hosts.
/net -hosts
#direct maps on local device
/- auto.direct
#indirect maps for home directories
/home auto.home

[Update: 2/16/2014]: You don’t actually have to do this. If the automounter is properly setup to be well behaved (for example in /etc/nsswitch we have the automount order as “files ldap”), then it will automatically look for a local /etc/auto_home file first, and then in the LDAP directory. In this case, since my auto_master map already has an entry that is “/home auto_home” in it, I don’t actually have to call out the /home indirect map in my /etc/auto_master file. I can just query the ldap entry, which will return “auto_home” as the location of the /home indirect map location, and the system will look in the local filesystem first. My local /etc/auto_home file still needs to make the call to lookup the auto_home map from the directory however.

This will load the local /etc/auto.home file for the home dirs. This is what I have for the auto.home

# Load from auto.home map in directory
+auto_home
# Local host directories mounted
* :/export/home/&

What this file does is first look in the ldap directory for the auto_home table,and then loads any local home mounts from /export/home. You have to enable ldap in /etc/nsswitch.conf

automount: files ldap

Note, the order. It first looks in the filesystem, and then in the directory. I want to read the local auto.master file instead of the directory server entry. The MASTER_MAP_NAME in the /etc/default/autofs file shouldn’t contain the DN of the auto_master table but rather point at the file

MASTER_MAP_NAME="/etc/auto.master"

The remainder of the LDAP variables in /etc/default/autofs should be configured properly with the server information, the search base, and the following to define the schema that we’re using

MAP_OBJECT_CLASS=”automountMap”
ENTRY_OBJECT_CLASS=”automount”
MAP_ATTRIBUTE=”automountMapName”
ENTRY_ATTRIBUTE=”automountKey”
VALUE_ATTRIBUTE=”automountInformation”