Mavericks & Preference Caching

Standard

Preference Caching is something that has been within OSX for some time, in Mountain Lion it was quite prominent with plists such as the Dock plist.

When Dockutil 1.1.4 was released it’s major change as noted in the release notes was to restart  this preference caching service called: cfprefsd, without which the settings written to the com.apple.dock.plist would later be overwritten.

So why am I mumbling along about this?

Well, recently i’ve been involved in discussions on this & wanted to post something to give others the heads up in case anyone else struggles with it.

Writing To plists

For example, with the more recent releases of Safari, Apple added a Managed Plugin Policy. This would manifest itself when accessing a site which requires loading of a non-sandboxed Safari plugin, such as shown below for the SharePoint Plugin;

This update happened just before we launched a SharePoint based intranet portal.

The trust settings for plugins are held within the ~/Library/Preferences/com.apple.Safari.plist in a array titled “ManagedPluginPolicies.” The contents of which look something like the below for each plugin;

I wanted to stop the prompt & manage this plist, so reaching for my old friend PlistBuddy I knocked up the below:

This populated the array correctly, but the GUI wouldn’t show the Plug-in as being allowed & shortly afterwards the plist would seemingly reset itself removing the changes I made to the array.

Around the same time, on the MacEnterprise Mailing List there was a thread detailing this same issue. (You can see my confused posts in that thread too).

As the other contributors advised, PlistBuddy is still valid for direct plist manipulation IF the plist isn’t cached (such as on a non-booted volume), but as it’s not CFPreferences aware.. any cached plists it writes to will be overwritten with the cached version.

I hope this is starting to make some sense.

So in order to make the changes above, you could employ  a Python script like the below;

As the above Python script is leveraging CFPreferences, the plist is updated correctly.. (including the cached copy).

With Mavericks, it appears more & more plists are being cached. Steve Wood mentioned me on Twitter asking if i’d seen Microsoft Remote Desktop 8 “remember” connections (as he has been using the script here to create the bookmarks).

Managed Preferences

In this JAMFNation thread, the question was asked how to delete “what is under /Library/Managed Preferences/ for our admin account also doesn’t do anything to temporally reset settings for support staff to troubleshoot things we “manage” for end users.”

Prior to Mavericks you could delete an MCX plist in /Library/Managed Preferences/ (such as the System Preferences plist), & then relaunch the app that the MCX applied to & the app would work without it’s MCX settings.

Again, in Mavericks it appears the these MCX settings can also be cached & therefore another step is needed, once a MCX plist is deleted run the below & THEN relaunch the app that the MCX applied to.

killall cfprefsd

So err.. what to use now?

I hope you can appreciate this post, as  really this caching mechanism is kind of a big deal. TBH, we’ve been on borrowed time with PlistBuddy & “live” plists as it’s never really been an Apple approved method to edit those.

So what to use & when?

defaults

The defaults command is still as valid as ever, it’s CFPreferences savvy.. but still fails when it comes to writing to nested keys & arrays (it can write an array, it can add to one, but not easily edit an existing one). But for single line changes such as the below, it should still function as per pre-Mavericks;

defaults write com.apple.Safari ExtensionsEnabled -bool YES

PlistBuddy

PlistBuddy’s usage is still valid when writing to plists on a non-booted volume, when writing to user templates & when creating plists to pre-configure non-Apple applications before their initial launch (such as in my  Microsoft Remote Desktop 8 post).

Python

The Python methods outlined above I’d employ when you need to edit a plist beyond the constraints of the defaults command (as per the Safari Managed Plugin Polices example above).

I am far from comfortable with Python, but am hoping to write a tutorial like post on using Python for plist manipulation. (Giving examples of the “old” PlistBuddy method & then the “new” Python method).

Conclusion

I hope this has been somewhat helpful, insightful & correct! I may well amend this post overtime to clarify & correct.

ACKNOWLEDGEMENTS: Other than those people mentioned in this post or whom contributed to the threads i’ve linked, there is one other person whom tried to advise me on this: Andrew Seago.

The day after JNUC2013 Andrew & his wife Stephanie took me under their wing & took me around the Mall Of America. After being bewildered by a shop with an accessory line dedicated to sugar coated marshmallows,  we have a few beers before my flight back to good ol’ blighty.

During which Andrew mentioned preference caching to me, but having not seen it.. I thought little of it, I should’ve listened more! Thanks again Andrew & Stephanie.

9 thoughts on “Mavericks & Preference Caching

  1. Ben Goodstein

    Just a heads up that the python script has a syntax error. The second comma should be a close brace.

  2. nick kalister

    it’s weird, I know defaults write commands should be safe with cfprefs, but I’ve definitely had it revert those changes on me, too . . . Screensaver preferences for the HDS mavericks upgrade were one example. I either had to kill cfprefs, or write to the plist before the user logged in.

  3. TIm Kimpton

    so it was

    #!/usr/bin/python
    import CoreFoundation

    ManagedPlugInPolicies = {

    # Always Allow Sharepoint plugin
    “com.microsoft.sharepoint.browserplugin”: {
    “PlugInFirstVisitPolicy”: “PlugInPolicyAllowNoSecurityRestrictions”,
    },
    }

    CoreFoundation.CFPreferencesSetAppValue(“ManagedPlugInPolicies”, ManagedPlugInPolicies, “com.apple.Safari”)
    CoreFoundation.CFPreferencesAppSynchronize(“com.apple.Safari”)

  4. Riley

    #!/bin/sh

    loggedInUser= /bin/ls -l /dev/console | /usr/bin/awk ‘{ print $3 }’

    /usr/libexec/plistbuddy -c delete “managedPlugInPolicies:com.RangerLib.RangerPlugin” /Users/loggedInUser/Library/Preferences/com.apple.Safari.plist

    ####### this code gives me an error when executing through terminal ######
    # File Doesn’t Exist, Will Create; ManagedPlugInPolicies:com.RangerLib.RangerPlugin Invalid Arguments

    ####### What am i doing wrong? I check the plist and that exact Dictionary is located under ManagedPlugInPolicies –> com.ap

    ####### Yes loggedInUser = returns my username in Terminal
    ####### Side Note – What code would i type to update the cache after deleting that plugin Dictionary

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.