Using Managed Preferences in the DSLocal domain

So this has recently been discussed on the MacEnteprise list, but we thought we'd try and collate these ideas into a real world example.
Most of you should be aware of how you can use MCX to manage preferences for your directory service. Generally these days this is done by either running Open Directory, extending the schema for Active Directory or a standard OpenLDAP installation, or running a "magic triangle" setup where your client machines are bound to both an Open Directory setup and an Active Directory/OpenLDAP setup.
You might think that apart from these scenarios that you don't have any options for MCX management, but that's not true at all. We do have another option. Put MCX controls into the local directory service.
Read on for some practical examples....
Let's think of a real world example. Let's imagine that you have a remote directory service that hasn't had the schema extended, and you don't have an OS X Server box providing a magic triangle setup, but you would like to manage a few simple preferences such as the loginwindow, perhaps disabling automatic login, and disabling password hints.
We could do this simply by pushing out appropriate preferences, or writing to the given preference files, but doing this with MCX gives you some major advantages.
Firstly, you'll find that some of Apple's preference panes will respect an MCX setting and actually disable the GUI controls for a given preference. For example, if you enforce FileVault with MCX, you'll see that users can't actually click on "Turn Off FileVault" in the Security preference pane.
Secondly, even when GUI controls don't disable themselves for MCX, you don't have to worry about the relevant setting being overwritten by a user and you scripting it to be automatically reset. MCX will sort this all out at login.
So to get started.... We're going to create a Computer record in the DSLocal domain (where all your local users and groups are stored) that sets the appropriate preferences. To get started, download the Server Admin Tools from Apple, and open up Workgroup Manager.
We have two ways of creating a "localhost" Computer record.
First, the command line way, which is probably what you'll use if you want to script this for all your machines, perhaps as a launchd item, or perhaps as a post-script for your imaging process.
sudo dscl . -create /Computers/localhost
sudo dscl . -create /Computers/localhost RealName localhost
sudo dscl . -create /Computers/localhost GeneratedUUID $(uuidgen)
sudo dscl . -create /Computers/localhost ENetAddress $(ifconfig en0 |grep ether | awk '{print $2}')
sudo dscl . -create /Computers/localhost IPAddress 127.0.0.1
Secondly, the Workgroup Manager way.
- Open up Workgroup Manager
- Don't login to a server, but go up to the Server menu and choose "View Directories"
- Make sure you've selected the DSLocal domain "/Local/Default" in the node bar, just below the toolbar in Workgroup Manager
- Click on the padlock icon to authenticate as an admin
- Select the Computers pane, the third icon from the left, the single square icon
- Click onthe "New Computer" toolbar icon.
- Under the "General" tab, set the Name and Short Name to "localhost"
- Under the "Network" tab, set the Ethernet ID to that of the local ethernet interface ("ifconfig en0" or "networksetup -getmacaddress en0") and the IP Address to "127.0.0.1"
Now we have a localhost computer record, and you can start managing preferences for it. Most of you should be aware of the kinds of things you can do here, but we're going to run through a quick example.
- Open up Workgroup Manager, select the localhost Computer record, select "Preferences" in the toolbar, and choose the "Login" group
- Select the "Options" tab and click on "Always"
- Uncheck "Show password hint..." and "Enable automatic login"
As of 10.5, Apple have given us some excellent new tools for examining MCX data. Firstly we have some new commands for dscl, and we're going to use "mcxread" to view the settings we just created.
$ dscl . -mcxread /Computers/localhost
App domain: .GlobalPreferences
Key: com.apple.autologout.AutoLogOutDelay
State: always
Value: 0
App domain: .GlobalPreferences
Key: MultipleSessionEnabled
State: always
Value: 0
App domain: com.apple.loginwindow
Key: RetriesUntilHint
State: always
Value: 0
App domain: com.apple.loginwindow
Key: AdminMayDisableMCX
State: always
Value: 0
App domain: com.apple.loginwindow
Key: com.apple.login.mcx.DisableAutoLoginClient
State: always
Value: 1
App domain: com.apple.loginwindow
Key: DisableConsoleAccess
State: always
Value: 0
App domain: com.apple.loginwindow
Key: UseComputerNameForComputerRecordName
State: always
Value: 0
App domain: com.apple.loginwindow
Key: EnableExternalAccounts
State: always
Value: 1
App domain: com.apple.systempreferences
Key: com.apple.preferences.users
State: always
Value: (
MultipleSessionEnabled
)
App domain: com.apple.MCX
Key: DisableGuestAccount
State: always
Value: 1
We also have "mcxset", "mcxedit", "mcxdelete", "mcxexport", "mcximport" and "mcxhelp" which should all be reasonably self-explanatory.
If you're reading the whole article first before actually running through the steps (which is probably a good idea... :) ), here is an alternative way of disabling password hints and automatic login using "mcxset". If you have set things up in Workgroup Manager already, you can go back and turn the preferences off if you want to try setting them from the command line.
sudo dscl . -mcxset /Computers/localhost com.apple.loginwindow RetriesUntilHint always 0
sudo dscl . -mcxset /Computers/localhost com.apple.loginwindow com.apple.login.mcx.DisableAutoLoginClient always 1
Pretty easy really huh?
As noted above, the advantage of doing things this way rather than by writing to the preference file directly is that OS X is smart enough to "know" that this is a managed preference and will disable the relevant GUI control. You'll see once the above settings are applied that the checkbox for "Show password hints" and the dropdown for "Automatic Login" in the Accounts preference pane are now disabled, and users can no longer enable them.
One thing to note is that we have this excellent new tool "mcxquery" which allows us to view the composited MCX settings for a given user, group and computer combination like:
mcxquery -user donbradman -group legends -computer staff1
but unfortunately there seems to be a bug with mcxquery not actually reporting results from the DSLocal domain, so you can't use it to examine these settings.
So what are the implications of this? Well remember that as of 10.5, the horrible, monolithic, mysterious NetInfo database is gone, and we now have a nice new shiny DSLocal setup that uses standard plists instead.
This means that all of these settings we've been running through are stored in a single file on the client machine, namely:
/var/db/dslocal/nodes/Default/computers/localhost.plist
The only machine specific data in this file is the ethernet address of the local machine. This means these settings are really easily integrated into an existing imaging setup such as Radmind or NetRestore, and a simple startup script can replace the ethernet address of the localhost.plist file with the correct one for the current host.
A few of us who have been using Puppet for systems management are looking into writing a new MCX management type for it that should make this stuff even easier. Look for a follow up article later on this.
Even if you don't have any kind of imaging infrastructure in place, you could use svn/cvs or even curl to grab the relevant plist from a central location on startup.
All we need now is a nice snappy name for this to compete with "Magic Triangle" and "Cylinder of Destiny".... We're looking for suggestions in the comments... :)
