Newer posts on the same subject:
Recently on the MacEnterprise mailing list, several of us were discussing putting MCX records into the local directory service. This is an appealing idea to me, because we don’t use Open Directory, and I’ve never wanted to spend the political capital to get our LDAP schema extended to support MCX, especially since I didn’t really know if ManagedClient/MCX would actually do what we wanted.
MCX in the local directory service seemed to me a way to experiment without having to convince our LDAP admins to make schema changes.
The idea of putting MCX records in the local directory service is not new. Karl Kuehn documented a method to inject MCX settings into the local NetInfo database here. Karl’s method is a little complicated due to the complexities of working with the NetInfo database.
With the arrival of Leopard, what was an opaque database file has been transformed into simple plist files arranged in an easy-to-understand directory structure. This makes working with the local directory service much easier – in many cases, to make a directory service modification, you can just drop a file into a directory!
Additionally, Leopard’s directory service has replaced ComputerLists with ComputerGroups, which have a great new feature: computers can belong to multiple ComputerGroups. We’ll use that new feature later.
When designing my implementation – I wanted some key features:
1) Use Workgroup Manager to create ComputerGroups and set managed preferences.
2) Capture the changes quickly and easily.
3) Make the managed preferences modular, so I could mix and match sets of managed preferences on any given machine.
4) Have different sets of managed preferences apply to laptops versus desktops, and have the correct set apply to the right class of machines without having to manually associate laptop preferences to laptops, and desktop preferences to desktops.
You’ll need Workgroup Manager, which is part of Apple’s Server Admin Tools 10.5. Download those here, get them from your Leopard Server install media, or search Apple’s website for “Server Admin Tools”.
To work with the local directory service, launch Workgroup Manager on a OS X client machine. When presented with the dialog to connect to a server, type “localhost” as the server name, and enter the name and password of a local admin for the local machine.
You’ll see a warning that you are working in a directory node that is not visible to the network. Check “Do not show this warning again” if you wish, and click OK to dismiss the panel.
Get started by selecting the Computer tab in the left pane. Click “New Computer” in the toolbar to create a new computer object. Name it “local_desktop”. Don’t add any other info to the record other than the name and short name, which should be “local_desktop” as well. Repeat the process, creating another computer object named “local_laptop”.
Next, move to the Computer Groups tab in the left pane. This is where it gets interesting. Create Computer Groups for each group of preferences you want to manage. I grouped them logically: the LoginWindow group contains the managed preferences for the loginwindow; NetworkProxies contains the managed settings for the network proxies, etc.
For each group, add local_desktop, local_laptop, or both as members; depending on whether you want the managed preferences to apply to desktop machines, laptops, or both. For example, you might want Mobility settings to apply only to laptops, so you would add only the local_laptop to the group that contained the managed preferences for Mobility.
Once you’ve created a group and added the appropriate local machines, you can then configure the preferences you wish to manage. See Apple’s documentation on User Management for more on managing preferences.
You now have MCX data in your local directory service. Next, we need to get that data to all our managed machines.
With Leopard, you are interested in two directories:
There should be two files in
/private/var/db/dslocal/nodes/Default/computergroups/ you should find one plist file for each Computer Group you created.
To replicate your MCX records across all your machines, you’ll need to copy the files from those directories to the same directories on all your other machines. I use radmind, which is perfectly suited for this task. You could also use FileWave, ARD, or puppet, to mention a few possibilities. Another possibility that seems pretty interesting would be to copy these files to a web server, and have a local script on each machine periodically curl them down and copy them into place.
Once you get these files to another test machine, check to see that DirectoryServices sees them:
dscl . list /Computers
dscl . list /ComputerGroups
If you don’t see them listed and you’re certain they are there, try
killall DirectoryService to restart DirectoryService and check again with
There’s one more thing you must do on the local machine, though, before these files will actually do anything useful on each client.
You’ll recall that when we created the local_desktop and local_laptop computer objects, we only named them – we did not enter the Ethernet ID information. In order to actually work, the appropriate object (local_desktop or local_laptop) must have its ENetAddress field set to the MAC layer address of the en0 interface of the local machine. To do this, I run a script at startup (I’ve added a bunch of line breaks [\] to make the text fit inside WordPress’s textwidth):
#!/bin/sh changedMCX=false macAddress=`/sbin/ifconfig en0 | \ /usr/bin/grep 'ether' | \ /usr/bin/sed \ "s/^[[:space:]]ether //" | \ cut -f1 -d " "` IS_LAPTOP=`/usr/sbin/system_profiler \ SPHardwareDataType | \ grep "Model Identifier" | grep "Book"` if [ "$IS_LAPTOP" != "" ]; then computerRecordName=local_laptop otherRecordName=local_desktop else computerRecordName=local_desktop otherRecordName=local_laptop fi storedMacAddress=`/usr/bin/dscl . -read \ /Computers/$computerRecordName \ ENetAddress | cut -f2 -d " "` if [ "$storedMacAddress" != "$macAddress" ] ; then echo "Updating MAC address \ for /Computers/$computerRecordName..." echo "was: $storedMacAddress" echo "now: $macAddress" /usr/bin/dscl . -create \ /Computers/$computerRecordName \ ENetAddress $macAddress /usr/bin/dscl . -delete \ /Computers/$otherRecordName \ ENetAddress changedMCX=true fi if [ "$changedMCX" = "true" ] ; then currentuser=`/usr/bin/who | \ grep console` if [ "$currentuser" = "" ]; then echo "Restarting loginwindow..." `/usr/bin/killall loginwindow` fi fi
This script uses system_profiler to tell if the machine is a laptop. If it is, it adds its en0 MAC layer address to local_laptop, otherwise it adds it to local_desktop.
Once local_laptop or local_desktop point to the local machine by way of the MAC layer address, all the policies you’ve defined in the various ComputerGroup objects will now apply.
You can deliver all the ComputerGroup objects to each client, or if you have a client with special settings, you can deliver only some of the ComputerGroup objects, or deliver different ComputerGroup objects.
The local_laptop and local_desktop Computer objects allow you to specify that some policies apply only to laptops, only to desktops, or both, and the local machine automatically places itself in the correct Computer object. This could be extended to have a machine place itself in some other Computer object, but it’s important to note that a machine’s MAC layer address can be in only ONE Computer object. The Computer object can be in multiple ComputerGroups.
In my implementation, local_laptop is in all the ComputerGroups, but local_desktop is not in the MobileAccounts, ScreenSaver, or SecureVM groups as we don’t enforce those settings on desktop machines. No-one has to remember to add the laptop-only policies to the right machines, or remember to add the laptops to the correct ComputerGroups – the machines do this themselves.
Fully implemented, we now have a solution that allows us to use Apple’s tools (Workgroup Manager, ManagedClient.app, MCX preference manifests, etc) to manage client preferences without having to extend the LDAP schema or build a “Magic Triangle” solution. This might serve as a test platform, or a learning environment to allow Mac admins to experiment with Client Management, or as an actual deployed method of managing OS X clients in your environment.
Nigel Kersten has also written on this topic. His article on afp548.com has a lot of command line examples, including examples of the new MCX support in dscl in Leopard.