I was recently discussing Mac OS X / Active Directory integration with a friend, and one of the things I mentioned was the local static / variable mappings feature of the Mac OS X LDAPv3 plugin. After some fairly extensive internet searching, it appears that the only reason I know about that feature is because I learned about it in Apple’s official training courses about Mac OS X Server and Directory Services several years ago; in other words, there appears to be no public documentation of this, except for the Peachpit 10.5 Directory Services book (and probably the 10.6 version that is unpublished as of this writing). Until now.
This is all in the context of configuring LDAP mappings using Directory Utility, one of the many topics covered in this PDF from Apple. The following content would fit in around page 149.
In addition to configuring custom mappings by referring to existing attributes by name (e.g. repurposing an unused attribute), you can also create local mappings that are either static or dynamic. A static mapping for an attribute means that a specified text string will be returned when the attribute is queried, instead of checking the actual record on the directory server. A local variable mapping allows you to compose the value from a mixture of supplied text strings and also references to other attribute values.
Background: LDAP Mappings
First, let us visualize what a mapping is. To really see this work on your own machine, you’ll need to be connected to some real LDAP service. Check out these steps if you’re unsure how to get at the LDAP mapping configuration in Directory Utility. In general, the process of ‘mapping’ is used to express relationships between the schema of different directory systems. There is a ‘standard’ name space that is used by Mac OS X to describe things that it needs to talk about (e.g. the name of the attribute that holds the user id). This standard name space is so-called because it is agnostic of any specific directory data storage backend. There are also ‘native’ name spaces for each backend that are used to refer to the things in that directory store.
Let’s say I have a user account in an LDAP directory, and I want to look up the unix ID and the value in the ‘comment’ field. The ‘standard’ names for these attributes are UniqueID and Comment. You can find the full definition of Apple’s ‘standard’ name space on page 273 of the aforementioned PDF.
{28} andre@donk [~] % dscl /Search read /Users/dre UniqueID Comment
Comment:
just this guy, you know...
UniqueID: 42
If we add the -raw option, we see the name space that is associated with the attributes:
{29} andre@donk [~] % dscl -raw /Search read /Users/dre UniqueID Comment
dsAttrTypeStandard:Comment:
just this guy, you know...
dsAttrTypeStandard:UniqueID: 42
dsAttrTypeStandard is the prefix for ‘standard’ attributes. Now let’s look in the LDAP mapping configuration to observe how these standard attributes are mapped to native attributes on the LDAP server:
For this LDAP configuration, whenever we get a query for the Comment attribute of a user record, we will look up the ‘native’ attribute named ‘description’. Using dscl, we can ask for things using either the native or standard name.
{30} andre@donk [~] % dscl -raw /Search read /Users/dre \
UniqueID Comment description UidNumber
dsAttrTypeNative:description:
just this guy, you know...
dsAttrTypeNative:UidNumber: 42
dsAttrTypeStandard:Comment:
just this guy, you know...
dsAttrTypeStandard:UniqueID: 42
To change the mapping, simply add or remove items from the right-side list. One common use case for a customized mapping is when the Mac OS X client is connecting to a directory service that doesn’t have a defined attribute for storing a piece of data that is required by Mac OS X. You might choose to instead re-purpose an existing but unused attribute to store this data. To pull that off, you simply add the mapping for the appropriate ‘standard’ attribute, using the native name of the re-purposed attribute.
Local Static Mappings
Suppose that you want all clients to use the same specific value for a given attribute. In this case, a local static mapping will do the trick. Let’s say for this example that I want to create a local static mapping for the “Street” attribute. I currently have no value for that attribute in my user record:
{32} andre@donk [~] % dscl -raw /Search read /Users/dre Street
No such key: Street
Let’s add one. Click “Add…” under the right-side list. Normally this is where you’d type the name of some attribute. To treat the supplied text as a literal value instead of an attribute name to look up, prefix with a hash sign (#).
Now when we do the same query as before:
{37} andre@donk [~] % dscl -raw /Search read /Users/dre Street
dsAttrTypeStandard:Street:
Shakedown Street
This also demonstrates that you’re allowed to have multiple mapped values, although the results aren’t that interesting yet… read on.
Local Variable Mappings
Local variable mappings are just a twist on the above. A good example is using a variable that represents the user’s short name to compose a home directory path. Click “Add…” and enter the text #/road/to/$uid$. Next, drag the entry you just created above the existing homeDirectory entry. The order in this list determines the order that results are returned. For attributes that are supposed to be single-value (like this one), that means that the requestor will only get the first result.
{40} andre@donk [~] % dscl -raw /Search read /Users/dre NFSHomeDirectory
dsAttrTypeStandard:NFSHomeDirectory: /road/to/dre
/Network/Servers/host.orange.com/Volumes/yowza/dre
At the Open Directory layer, we see that there are actually two values returned – our local variable mapping, and also another (obfuscated) result that came from the LDAP server. What happens if we actually request this data using a ‘real’ directory services client?
{2} andre@donk [~] % cd ~dre
cd: no such file or directory: /road/to/dre
We see that ‘cd’ only gets one result – the first one in the list. Of course it’s a dead end, because this is just an example!
Don’t forget…
Everything you’ve seen here is 100% client-side, and only applies to the computer you used to configure the custom mappings. If you find yourself running around configuring custom mappings on a bunch of computers, you are probably doing it wrong – in this case, please check out the handy “Write to Server…” button. This publishes the custom mappings to the LDAP server where they will be automatically downloaded by other Mac OS X Clients – provided that the LDAP server has the required support for hosting this data; it wants to put this data in a record under Config called macosxodconfig, in an attribute called ‘description’. Here’s a nice techworld article that provides an example of all this from start to finish.