Creating a signed Java Deployment Rule Set with Windows Server CA

Introduction

With the release of Oracle’s Java 7 Update 51 came heightened security measures that affect unsigned and self-signed Java applets. At its standard “High” security setting the Java web plugin and standalone JVM will refuse to run unsigned or self-signed applets unless they have been explicitly added to a user-level whitelist which is a newly added security feature in Java 7 Update 51.
To allow large organizations to better manage security for their users Oracle previously introduced the Deployment Rule Set feature in Java 7 Update 40. The Deployment Rule Set consists of a single signed JAR file named “DeploymentRuleSet.jar” deployed in the Java system path “/Library/Application Support/Oracle/Java/Deployment”. Given the new security measures in Java 7 Update 51 it is a good time to start using a Deployment Rule Set since it provides:

  • The ability to use wildcard exception rules, unlike the user exception site list (https://mydomain.myorg.com/*)
  • No Java security warnings when accessing a whitelisted Java applet, unlike the user exception site list
  • Easy system-wide installation and updating of the ruleset

This post deals with a common scenario for Mac admins: you’re in an established Windows Server Active Directory environment that offers Certificate Authority services. Clients may already have your domain’s CA in their trusted cert store so extending this to sign a Java Deployment Rule Set JAR may make sense. The process of deploying the DeploymentRuleSet.jar file is outside the scope of this article although I did include a postinstall script as an addendum to assist with the installation of the signed certificate chain that this article will help you create. With that said, let’s get underway.

The process

Generate a new keystore and key

To perform the various key requests and code signing operations, a way to keep it simple is to create a fresh Java keystore file using the same password as the Java default JKS password. You’re free to play around with the -keyalg and -keysize settings as needed.

$ keytool -genkey -alias mykey -keyalg RSA -keysize 2048 -keystore keystore.jks -storepass changeit

Generate a Certificate Signing Request

In order to verify and sign the code signing certificate the Windows CA is going to need a certificate signing request (CSR) to process. This command creates one based on the key we generated in the previous step.

$ keytool -certreq -alias mykey -file csr.csr -keystore keystore.jks -storepass changeit

Extract the private key from the keystore

To submit a signing request, we’ll need the private key as well as the public one. The easiest way to get the private key out of an existing keystore is to import the keystore into a newly-created keystore, selecting only the key we are interested in and storing it as PKCS#12. The Windows tool we’ll use later can process PKCS#12 keys so we don’t need to do any further conversion.

$ keytool -v -importkeystore -srckeystore keystore.jks -srcalias mykey -destkeystore myp12file.p12 -deststoretype PKCS12

Rename private key file

Windows Server likes certain things to be a certain way and dealing with certificates is no different, so we must rename our PKCS#12 file to have a .pfx extension to allow certreq.exe to play nice.

$ mv myp12file.p12 myp12file.pfx

Sign the CSR using Windows Server

The files you will need to process the signing request are “mykey.csr”, “mykey.cer” and “myp12file.pfx”. Sign your generated signing request using a user account that has Read and Enroll rights to a template configured for code signing on the Windows Server CA. In the example here we’re using a template named “MyCodeSigningTemplate”. See here for more info on how to create a code signing Certificate Template with Windows Server: http://technet.microsoft.com/en-us/library/cc730826(v=ws.10).aspx

Allow certreq.exe to overwrite mykey.cer and mykey.csr when prompted by the “certreq” command.

C:\Windows\system32>certreq -submit -attrib "CertificateTemplate:MyCodeSigningTemplate" mykey.csr mykey.cer myp12file.pfx

Import signed key and CA into keystore

We need to add the signed key and signing CA (and any intermediate CA certs) back into our keystore so we can use it for code signing.

$ keytool -importcert -keystore keystore.jks -file ca-certificate.pem -alias CARoot -storepass changeit
...
Certificate was added to keystore
$ keytool –importcert –keystore keystore.jks –file mykey.cer –alias mykey -storepass changeit -trustcacerts
...
Certificate reply was installed in keystore

Create DeploymentRuleSet.jar and sign it with the newly signed key

Now we can get down to the business of creating a .jar file and signing it with our shiny new key. We stash ruleset.xml into a JAR using the “jar” command. Next, we use “jarsigner” to sign “DeploymentRuleSet.jar” with our key which is retrieved from our Java keystore using the “mykey” alias.

$ jar -cvf DeploymentRuleSet.jar ruleset.xml
added manifest
adding: ruleset.xml(in = 266) (out= 225)(deflated 15%)
$ jarsigner -keystore keystore.jks -storepass changeit DeploymentRuleSet.jar mykey

Combine signing key and associated root CA certificates

In order to easily distribute our public signing cert as well as those of our CA and any intermediate CAs they should be concatenated into one single file. The order to concatenate them in is CA -> Intermediate -> (Optional intermediates) -> mykey.pem.

$ cat rootCA.pem (intermediateCert1.pem, intermediateCert2.pem) mykey.pem > mychain.pem

Import mychain.pem into Java keystore on client(s)

In order for the Java browser plugin to accept our Deployment Rule Set without complaining, we need to add its code signing key public key certificate to the Java keystore.
The Java home path for the browser plugin is different from system Java so we need to import our certificate chain into the browser plugin-specific keystore located at “/Library/Internet Plug-Ins/Contents/Home/lib/security/cacerts”. To make the certificate chain available to standalone Java applications as well it must be imported into the system Java keystore at “/Library/Java/Home/lib/security/cacerts”.

Both keystores use the same default password: “changeit”. For enhanced security, it may be a good idea to change the password for the individual keystores to a new one after importing the certificate chain. This is optional, but a security note worth mentioning.

$ keytool -importcert -keystore /Library/Internet\ Plug-Ins/Contents/Home/lib/security/cacerts -storepass changeit -alias mykey -file mychain.pem -noprompt
$ keytool -importcert -keystore /Library/Java/Home/lib/security/cacerts -storepass changeit -alias mykey -file mychain.pem -noprompt

Testing the Deployment Rule Set

Excelsior! We should now be able to place our DeploymentRuleSet.jar file into its designated path and load a web page we whitelisted in the ruleset.xml file. If all went well the Java application on the web page will load without any warnings from the JVM about the DRS using an untrusted self-signed certificate or the application being blocked because of its unsigned or self-signed status. You can verify the presence of an active Deployment Rule Set by navigating to the “Java” preference pane in System Preferences and clicking the “Security” tab. If active, the tab will contain a line of blue text that says “View the active Deployment Rule Set”. The blue text can be clicked to view the current rule set in a new window. The Deployment Rule Set will also allows inspection of the signing certificate and its associated root certificates. These should match the code signing key’s certificate and any root and intermediary CA certificates used in our previous steps.

java7u51_security_high

Java 7u51 Security tab


java7u51_security_DRS

Java 7u51 Deployment Rule Set


Java 7u51 DRS Certificates

Java 7u51 DRS Certificates

Conclusion

Hopefully this will help a few Mac admins with deploying a self-signed DeploymentRuleSet.jar file using their organization’s local CA. If you have questions or comments leave them at the end of this post, find me on Twitter or on Freenode IRC in ##osx-server.

Addendum: Package postflight

To make distribution of the signing certificate chain a little easier I’ve included a postinstall script that can be added to an installer package. The postinstall script will check the browser plugin and system keystores for the presence of the “my_chain” alias and if it is not found in either one of the keystores it adds the certificate chain. The script expects the installer to drop “my_chain.pem” into /tmp and it securely removes the file after completion of the script. You are free to change file names and aliases as needed.

#!/bin/bash

# Check Java Plugin and System keystores for existence of the signing cert.
#   If found, we skip installation and report success. If not found, tag the
#   keystore as needing installation and proceed with installation. Check result
#   of installation afterwards and log the result for reporting later.

# Executable and keystore file statics
KEYTOOL_LIST="/usr/bin/keytool -list -storepass changeit -keystore "
KEYTOOL_IMPORT="/usr/bin/keytool -importcert -storepass changeit -trustcacerts -file /tmp/my_chain.pem -alias my_chain -noprompt -keystore "
JAVA_PLUGIN="/Library/Internet Plug-Ins/JavaAppletPlugin.plugin/Contents/Home/lib/security/cacerts"
JAVA_SYSTEM="/Library/Java/Home/lib/security/cacerts"
LOGGER="/usr/bin/logger -t JAVADRSINSTALL"
REMOVE_PEM="/usr/bin/srm /tmp/my_chain.pem 2>&1 >/dev/null"

# Initialize reporting variables. I like string comparisons, deal with it.
keystore_plugin='0'
keystore_system='0'

# Check whether the signing cert is installed in the Java plugin keystore
if ! `${KEYTOOL_LIST} "${JAVA_PLUGIN}" | grep my_chain 2>&1 >/dev/null`; then
    ${LOGGER} "Cert chain for Java DRS must be installed in Java Plugin."
    keystore_plugin='1'
fi
# Check whether the signing cert is installed in the System Java keystore
if ! `${KEYTOOL_LIST} "${JAVA_SYSTEM}" | grep my_chain 2>&1 >/dev/null`; then
    ${LOGGER} "Cert chain for Java DRS must be installed in System Java Home."
    keystore_system='1'
fi

# If we didn't find the signing key in the keystores we need to install them.

# Install into Java plugin keystore
if [[ $keystore_plugin == '1' ]]; then
    echo $keystore_status
    ${LOGGER} "Installing cert chain for Java DRS into JavaAppletPlugin"
    ${KEYTOOL_IMPORT} "${JAVA_PLUGIN}" 2>&1 >/dev/null

    # Check whether our signing key is now in the keystore
    if `${KEYTOOL_LIST} "${JAVA_PLUGIN}" | grep my_chain 2>&1 >/dev/null`; then
        keystore_plugin='2'
    fi
fi

# Install into System Java keystore
if [[ $keystore_system == '1' ]]; then
    ${LOGGER} "Installing cert chain for Java DRS into System Java Home"
    ${KEYTOOL_IMPORT} "${JAVA_SYSTEM}" 2>&1 >/dev/null

    # Check whether our signing key is now in the keystore
    if `${KEYTOOL_LIST} "${JAVA_SYSTEM}"  | grep my_chain 2>&1 >/dev/null`; then
        keystore_system='2'
    fi
fi

# Report on status of installs, log any failures and securely remove our key

# No installation needed for either keystore, report it
if [[ ($keystore_plugin == '0') && ($keystore_system == '0') ]]; then
    ${LOGGER} "Java DRS cert chain install not needed."
    ${REMOVE_PEM}

# Both checks came back as failed, report it
elif [[ ($keystore_plugin == '1') && ($keystore_system == '1') ]]; then
    ${LOGGER} "Java DRS cert chain install into all keystores failed."
    ${REMOVE_PEM}

# Both checks came back correctly, report success for all keystores
elif [[ ($keystore_plugin == '2') && ($keystore_system == '2') ]]; then
    ${LOGGER} "Java DRS cert chain install into all keystores complete."
    ${REMOVE_PEM}

# Java Plugin installation not needed, System Java keystore succeeded.
elif [[ ($keystore_plugin == '0') && ($keystore_system == '2') ]]; then
    ${LOGGER} "Java DRS cert chain install into Java Plugin keystore not needed."
    ${LOGGER} "Java DRS cert chain install into System Java keystore successful."
    ${REMOVE_PEM}

# Java Plugin installation succeeded, System Java keystore not needed.
elif [[ ($keystore_plugin == '2') && ($keystore_system == '0') ]]; then
    ${LOGGER} "Java DRS cert chain install into Java Plugin keystore successful."
    ${LOGGER} "Java DRS cert chain install into System Java keystore not needed."
    ${REMOVE_PEM}

# Java Plugin installation not needed, System Java keystore failed.
elif [[ ($keystore_plugin == '0') && ($keystore_system == '1') ]]; then
    ${LOGGER} "Java DRS cert chain install into Java Plugin keystore not needed."
    ${LOGGER} "Java DRS cert chain install into System Java keystore failed."
    ${REMOVE_PEM}

# Java Plugin installation failed, System Java keystore not needed.
elif [[ ($keystore_plugin == '1') && ($keystore_system == '0') ]]; then
    ${LOGGER} "Java DRS cert chain install into Java Plugin keystore failed."
    ${LOGGER} "Java DRS cert chain install into System Java keystore not needed."
    ${REMOVE_PEM}

# Java Plugin installation failed, System Java keystore succeeded.
elif [[ ($keystore_plugin == '1') && ($keystore_system == '2') ]]; then
    ${LOGGER} "Java DRS cert chain install into Java Plugin keystore failed."
    ${LOGGER} "Java DRS cert chain install into System Java keystore successful."
    ${REMOVE_PEM}

# Java Plugin installation succeeded, System Java keystore failed.
elif [[ ($keystore_plugin == '2') && ($keystore_system == '1') ]]; then
    ${LOGGER} "Java DRS cert chain install into Java Plugin keystore successful."
    ${LOGGER} "Java DRS cert chain install into System Java keystore failed."
    ${REMOVE_PEM}
fi

exit 0

Auto-this and Auto-that

Inspired by recent Auto-events I decided I was tired of having to manually roll hardware-specific NetBoot images, such as we’ve had to do recently for both Mountain Lion and Mavericks releases. It took me a while to spelunk into the innards of System Image Utility and its related frameworks and tools but I feel that I was able to write up something half-decent for it.

With that said, please take a look at AutoNBI.py, the latest member of the Auto-family. There’s no fancy GUI, but that’s the point here – integration into your workflow. There’s some first version caveats such as the NBI modification method being pretty basic in that it currently will replace or add only one folder since that is what I needed to be able to do for my needs. I have some additional code in the works that will let AutoNBI ingest a plist file with more complex add and remove configurations, but for now this’ll have to do.

Try it out, let me know what you think. Link to the Bitbucket project page is here and the Readme follows below:

AutoNBI.py

A tool to automate (or not) the building and customization of Apple NetBoot NBI bundles.

Requirements:

  • OS X 10.9 Mavericks – This tool relies on parts of the SIUFoundation Framework which is part of System Image Utility, found in/System/Library/CoreServices in Mavericks.
  • Munki tools installed at /usr/local/munki – needed for FoundationPlist.

Thanks to:

  • Greg Neagle for overall inspiration and code snippets (COSXIP)
  • Per Olofsson for the awesome AutoDMG which inspired this tool
  • Tim Sutton for further encouragement and feedback on early versions

This tool aids in the creation of Apple NetBoot Image (NBI) bundles. It can run either in interactive mode by passing it a folder, installer application or DMG or automatically, integrated into a larger workflow.

Command line options:

  • [--source][-s] The valid path to a source of one of the following types:
  • A folder (such as /Applications) which will be searched for one or more valid install sources
  • An OS X installer application (e.g. “Install OS X Mavericks.app”)
  • An InstallESD.dmg file
  • [--destination][-d] The valid path to a dedicated build root folder:

The build root is where the resulting NBI bundle and temporary build files are written. If the optional –folder arguments is given an identically named folder must be placed in the build root:

./AutoNBI <arguments> -d /Users/admin/BuildRoot –folder Packages -> Causes AutoNBI to look for /Users/admin/BuildRoot/Packages

  • [--name][-n] The name of the NBI bundle, without .nbi extension
  • [--folder] Optional – The name of a folder to be copied onto NetInstall.dmg. If the folder already exists, it will be overwritten. This allows for the customization of a standard NetInstall image by providing a custom rc.imaging and other required files, such as a custom Runtime executable. For reference, see the DeployStudio Runtime NBI.
  • [--auto][-a] Optional – Enable automated run. The user will not be prompted for input and the application will attempt to create a valid NBI. If the input source path results in more than one possible installer source the application will stop. If more than one possible installer source is found in interactive mode the user will be presented with a list of possible InstallerESD.dmg choices and asked to pick one.

Examples:

To invoke AutoNBI in interactive mode: sudo ./AutoNBI -s /Applications -d /Users/admin/BuildRoot -n Mavericks

To invoke AutoNBI in automatic mode: sudo ./AutoNBI -s ~/InstallESD.dmg -d /Users/admin/BuildRoot -n Mavericks -a

To replace “Packages” on the NBI boot volume with a custom version: sudo ./AutoNBI -s ~/InstallESD.dmg -d ~/BuildRoot -n Mavericks -f Packages -a

Workaround for Konica Minolta (and other) PDEs in Mavericks

Is your organization using those really shiny and fancy Konica Minolta multifunction printers? Did your users start upgrading to Mavericks only to find that none of the custom functionality menus (courtesy of KM PDEs) were available in the Print window? Try this workaround to make them show up again in the print dialogs of sandboxed apps (Preview, TextEdit). Note that the script can easily be modified to provide the same workaround for other vendors’ incompatible PDEs as well. And make sure to use sudo, of course.

Update: To make applying this workaround a little easier I have created a ‘nopkg’ Munki pkginfo that will apply it to any PDEs found in a user’s /Library/Printers folder that are missing the required key in their Info.plist. It is up to the Mac admin to insert the names of the appropriate printer driver install items for which this patch should be an update. Get the pkginfo item right here.

Update 2: For those having trouble figuring out how to apply this workaround or those who don’t use Munki for their patch management I have put up a standalone version of the script. Simply unzip the file and run with sudo:

sudo ./mavericks_pde_fix.py

Changes will only be made to PDEs that are missing a key in their Info.plist required for Mavericks compatibility.

Mavericks tool time – SIU and imagetool

Recently I’ve had to rebuild our customized NBI NetBoot images a number of times due to special OS builds (yay) and needing to test Mavericks DPs. In that process it became obvious that it’s easy to make a mistake adding certain resources, deleting others and making sure that the resulting DMG is resized afterwards. I don’t know about you, but if I have to repeatedly and manually run a bunch of error-prone steps my mind quickly turns towards automating the heck out of it to regain sanity and remove error.

Wanting to cut my teeth on some more Python I figured I would seize this particular itch to do that. Having been generally happy with System Image Utility (SIU) my first approach was to create an SIU workflow and then figure out a way to execute it from Python. This, I surmised, required tapping the power of the Automator framework with PyObjc through things like AMWorkflow.runWorkflowAtURL_withInput_error_(). Not the easiest for a first PyObjc project, admittedly. After some scary times wandering in the PyObjc desert kicking the Automator Framework around and not making a lot of headway I decided to see if perhaps System Image Utility had a CLI mode I could subvert for my needs. Thus I stumbled upon ‘/System/Library/CoreServices/System Image Utility.app/Contents/MacOS/imagetool‘ which I didn’t remember seeing before and indeed appears to be new in Mavericks.

Long story short: imagetool is a CLI tool that can generate NetBoot/Install/Restore NBI bundles ready for deployment as well as regular bootable installer media. Since we already have the “createinstallmedia” tool contained in the Install OS X Mavericks.app bundle (written up so very nicely by Rusty Meyers) I will not go into the –createmedia (-c) function here as it does the same thing.

The usage info for imagetool is as follows:

/System/Library/CoreServices/System\ Image\ Utility.app/Contents/MacOS/imagetool

Usage: imagetool <options>
  where <options> are:
   -c | --createmedia -s <path_to_install_app> -d <path_to_volume>
  or:
   -p | --plist <path> path to a property list containing the build specifications
 and/or:
   [--netboot | --netinstall | --netrestore] image kind (required)
   -d | --destination <path> path to save the image (required)
   -s | --source <mountpoint> mountpoint of source volume or path to Install Mac OS X
        application (required)
   -n | --name <string> name of image (required)
   -i | --index <integer> image index (0-65535) (required)

   -h | --help this help

The help text goes on to say:

To create a property list, create a custom workflow in System Image Utility.
Add any customized steps you wish the workflow to perform.
Hold down the option key when clicking the run button in the workflow.
This will save the workflow detail to the specified location instead of executing it.

While it would be perfectly fine to feed imagetool some CLI parameters the –plist option intrigued me. I tested the “option-click Run to save” (so intuitive, Apple) in SIU and it does indeed save a plist file, different in structure from the usual .wflow document.

SIU_custom
SIU_saveplist
Upon opening the file we see a pretty straightforward set of configuration items:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>imageDescription</key>
	<string>NetInstall of OS X 10.9 (13A603) Install (7.14 GB)</string>
	<key>imageIndex</key>
	<integer>1621</integer>
	<key>imageName</key>
	<string>NetInstall of Install OS X Mavericks</string>
	<key>installType</key>
	<string>netinstall</string>
	<key>nbiLocation</key>
	<string>/Path/To/NetInstall of Install OS X Mavericks</string>
	<key>sourcesList</key>
	<array>
		<dict>
			<key>dmgPath</key>
			<string>/Path/To/InstallESD.dmg</string>
			<key>isInstallMedia</key>
			<true/>
			<key>kindOfSource</key>
			<integer>1</integer>
			<key>sourceType</key>
			<string>ESDApplication</string>
			<key>volumePath</key>
			<string>/Path/To//Install OS X Mavericks.app</string>
		</dict>
	</array>
	----SNIP----

These are all as one would expect to see – image description, name, index as well as the location it will be written out to and source(s) of the InstallESD.dmg to use. If the “Add Packages and Post-Install Scripts” workflow item is included its settings are recorded as follows:

	<key>packageList</key>
	<array>
		<string>/Users/admin/munkitools-0.9.0.1803.0.mpkg</string>
		<string>/Users/admin/CleanImage-1.0.pkg</string>
	</array>
	<key>scriptList</key>
	<array/>

In addition to the above options the .plist contains a lengthy “userConfigurationOptions” dict containing a “groupID” and “userID” key which are set to that of the user running SIU. A third key named “siuPrefs” (containing a dict of other strings, integers, arrays and dicts) appears to contain a few SIU-specific keys but also many settings originating from the user creating the NetBoot image. In my testing these keys contained ColorSync profile settings, Text Replacement configs and even configurations for third party applications.

The SIU-related keys are:

<key>addlNetBootMbytes</key>
<integer>400</integer>
<key>asr_blockCopyVolume</key>
<true/>
<key>asr_displayCountdown</key>
<false/>
<key>asr_dontReorderForMulticast</key>
<false/>
<key>asr_retainOriginalVolumeName</key>
<true/>
<key>consumeSuppliedImage</key>
<false/>
<key>createEnabledImages</key>
<true/>
<key>createSparseImages</key>
<false/>
<key>enableInternalLogging</key>
<false/>
<key>installToImageDiskFormat</key>
<string>HFS+J</string>
<key>kSIUWorkflowDirectoryKey</key>
<string>/Users/admin/Documents</string>
<key>lastImageLocation</key>
<string>/Users/admin/Desktop</string>
<key>liveUpdateInstallerSearch</key>
<true/>
<key>restoreImageFormat</key>
<string>UDZO</string>

Since I didn’t want to retain most of the user settings I removed the entire “userConfigurationOptions” dict as a test and subsequent images built and booted without a problem. Taking all of the above into account it is therefore fairly straightforward to put together one or more .plist files that can be fed to imagetool with an invocation like this:

sudo '/System/Library/CoreServices/System Image Utility.app/Contents/MacOS/imagetool' --plist '/Users/admin/Documents/NetRestore Template.plist' --index 3000

This will tell imagetool to use the configuration in “NetRestore Template.plist”, overriding the “imageIndex” key in the plist and substituting it with “3000”. Note that while my example uses Mavericks as an installer source I have been able to verify that substituting a Mountain Lion (10.8) or Lion (10.7) installer app and InstallESD.dmg also works without a hitch and the resulting NBIs were all bootable.

As you can see, some interesting things are possible with this entirely CLI-driven process. I will be posting a tool written in Python in the next few days that leverages imagetool to automate the creation and processing of plists to generate and modify NetBoot images for use in mass deployments of OS X.

AFP548 Episode 2 up now

I recently casted pod for the fine folks at AFP548 and had the privilege of talking to the esteemed Charles Edge for an hour and change. Go check it out here.

Thanks to Charles and Allister for their direct involvement and the AFP548 purveyors at large for having me. It was a blast!

Edit: if iTunes seems wonky, this is the direct link to the episode on SoundCloud.

PSU Mac Admins Conference 2013 slides are up

First of all I want to thank all those brave souls who stuck around until this year’s conference’s bitter end to come to listen to me talk about Munki, Munkiserver, Puppet and the combination of the three. The video of mine and other speaker’s sessions can be found on the PSU Mac Admins YouTube page somewhere in the latter part of June.

After some minor modifications (thanks @Allister) I have posted my slide deck as a PDF. The PSU folks will also be sending out links to attendees of the slides of all the other speakers.

However if you did not attend the conference you can find my slides right here.

Many thanks to the PSU Mac Admins team for organizing a well-oiled conference, it was a blast!

Adobe Creative Cloud for Teams

Update: since the details that we received did not line up with Creative Cloud Enterprise features I asked for verification from our vendor whether we were given details about the CC  Enterprise product and whether it was given by an Adobe rep. Neither were the case, so I am modifying my post to instead outline the details of the Creative Cloud for Teams program for those SMB admins who are considering it for their users.

I apologize for any confusion the initial post created, it was by no means my intention to do so. A big thanks to Jody Rogers for alerting me about the misinformation. As always he is on top of things.

Adobe Creative Cloud for Teams highlights:

  • For those with security policies that forbid Cloud storage use, Creative Cloud storage must be blocked through firewall port filtering at the customer’s site.
  • Creative Cloud Packager currently does not have a “kill switch” for the CC storage functionality, as it has for EULA suppression, update notifications, etc.
  • Laptop users who use the CC apps at home or anywhere else that is not at their employer’s location will have full access to CC storage.
  • CC Teams admins have the ability to see which users are using CC storage and must police this usage themselves.
  • The ability to retrieve any CC-stored content for users who have been removed from the company’s CC account is in the works.
  • Upon first time deployment of one or more CC apps the end user must register an Adobe ID to then validate the app(s) they were given access to. CC Teams admins must generate email notifications for each new user (and likely also for each new app assigned to an existing user).
  • A user’s computer must make contact with the Adobe CC servers at least once every 30 days or the installed CC app(s) will revert to trial mode.
  • As far as I could understand there’s still the dual-license ability where a user can use the same applications they are licensed for on a desktop and a laptop computer. No clear word on whether this means simultaneously or not.
  • For those of us who need to test deployment, security or end-user functionality Adobe can decide to make short-term (think 3-4 weeks) licenses available.

These are all the points I got out of our 45 minute call. Anyone out there who has more solid details that either confirm or contradict any of the information presented here is encouraged to respond in the comments, email or Twitter.

Link – Booting multiple NBIs using ISC DHCPD

Brandon Penglase wrote up a very helpful wiki article on his site outlining how to configure ISC’s DHCP server to serve multiple NetBoot images as opposed to the single image, methods for which have been available for a number of years now. Noted caveats are that Startup Disk will not be able to display the available NBIs as it uses a custom port to receive the list of images back and the inability to use thin NetBoot images that require server-side storage for the client.

Go read it now.

Office 2011 SP2 VL media ditches Communicator for Lync

After an earlier Twitter exchange with @golby today I realized that as of the SP2 VL version of Office 2011 Microsoft has removed Communicator 13.x (also known as Communicator 2011 for Enterprise) in favor of their current Lync for Mac 2011 application, version 14.0.2. This is an important change for those on both sides of the Lync-coin: if you didn’t upgrade to Lync from OCS yet, you will now need to remove the Lync client during pre- or post-install and install the separately available Communicator 2011 PKG from the VL site. Since Communicator 2011 is not available outside of the VL site you will need to have yourself granted access to the site, or ask someone with access to download it. Those who are using Lync Server (Standard or Enterprise) and Lync for Mac 2011 will need to adjust their installation recipes since up to this point one would have had to install Lync for Mac 2011 separately, and remove the Communicator 2011 application either in pre- or post-install. In my case I am installing Office 2011 and Lync for Mac 2011 using Munki and since all users get the Lync client I have it requiring the Office 2011 installer. That will now have to be changed to just install Office 2011 SP2 while separately maintaining updates for Lync beyond the included 14.0.2 version.

Fixing Microsoft Office 2011 SP2 deployment for Munki

With the release of the recent Microsoft Office for Mac 2011 SP2 update  a new and unwelcome feature was introduced to Mac admins deploying Microsoft Office 2011 updates with patch management solutions such as Munki, Casper or Absolute Manage: zombie mode. For reasons not entirely clear to anyone (including the Microsoft MBU folks themselves) the PKG install of SP2 causes Munki’s Managed Software Update to hang at the final stage while displaying “Finishing the Installation..” This appears to be due to a hamfisted clean up attempt by the embedded clean_path script which causes MSU to appear frozen in the finishing stage. One can go in and manually kill off the sleep-cycling process or wait for the 2 hour timeout that Munki uses for running processes launched by the Munki supervisor to expire. Neither is elegant nor time-effective so in an effort to remove this one misbehaving script from the equation I edited the PKG’s distribution.dist script and changed the following entry (line 251):

function volumeHasUpdatableVersionTest()
{
var result = false;
try {
//system.log("volumeHasUpdatableVersionTest: running volume_updatable " + my.target.mountpoint + " " + GetTempDirectory());
result = (system.runOnce('volume_updatable', my.target.mountpoint, GetTempDirectory()) == 0);
} catch (e) {system.log("volumeHasUpdatableVersionTest: mount: "+my.target.mountpoint+" exception: "+e);}
return result;
}

To simply read:

function volumeHasUpdatableVersionTest()
{
return true;
}

Since all that the code is doing is to compare the sys.exit() return code from volume_updatable to “0” and set result to “true” if it is, I decided to short-circuit the function and have it return “true” at all times. We’ll assume that Munki has already determined that an upgradable version of Office 2011 was found based on entries in the pkginfo, so simply passing over the test for an updatable version was acceptable for my environment.

For completeness sake, skipping over volumeHasUpdatableVersionTest() will bypass the following Microsoft-provided scripts:

find_office
office_updatable
clean_path

I welcome feedback on whether this is successful for others as well. I’m sure it’s possible to make a more targeted edit to prevent execution of just the clean_path script but I will leave that up to the adventurous Mac admins to determine.

Update: On 4/25/12 Microsoft released a patched SP2 updater, version 14.2.1. This appears to have fixed the issue with the Outlook database corruption but still experiences the same issue as described in this post, even though the release notes state that too was corrected. I have verified that the post-install code is still the same and will hang up at the same script. Microsoft has suggested neutering clean_path by going into the script and changing it there but my fix as descibed above still works.

%d bloggers like this: