#!/bin/bash overridesPath="/private/var/db/launchd.db/com.apple.launchd/overrides.plist"; overridesDir="/private/var/db/launchd.db/com.apple.launchd"; systemLaunchDaemonPath="/System/Library/LaunchDaemons/" apacheLaunchDaemonPlistFile="org.apache.httpd.plist" plistBuddy="/usr/libexec/PlistBuddy"; finalDstRoot="${DSTROOT}"; if [[ -n "$DEFERREDINSTALLROOT" ]]; then finalDstRoot="$DEFERREDINSTALLROOT"; fi # Compares two version strings with an arbitrary number of period-delimited # "minor" version numbers (e.g. 7.5.0.0.0). Takes two parameters: the version # to check and the target version (the minimum version required for success). # # Usage: # $version_to_check=`defaults read /path/to/bundle/Contents/version CFBundleShortVersionString` # $target_to_meet_or_exceed="7.5.0" # if [[ sui_compare_version_numbers ${version_to_check} ${target_to_meet_or_exceed} ]]; then # echo "Success. Checked version ($1) meets or exceeds target ($2)." # else # echo "Failure. Checked version ($1) is less than target ($2)." # fi # # Returns 0 on success (check version meets or exceeds target) # 1 if target ($2) is less than version ($1) # 2 if target ($2) is equal to version ($1) # Written by Ben Mitchell. function sui_compare_version_numbers() { # Split the versions on periods. IFS is a special variable in bash that # contains the word delimiter. Changing the delimiter allows declare to be # used to split a string on an arbitrary character. local IFS="."; declare -a sui_compare_check=($1); declare -a sui_compare_target=($2); # Get the length of each array. sui_compare_check_length=${#sui_compare_check[*]} sui_compare_target_length=${#sui_compare_target[*]} # Iterate and compare each token. for((i = 0; i < sui_compare_target_length; i++)); do check_token=${sui_compare_check[$i]} target_token=${sui_compare_target[$i]} # If we reach the end of the check array, presume subsequent tokens are 0. if [[ $i -ge $sui_compare_check_length ]]; then check_token="0" fi # Check for inequality between the two tokens. if [[ $target_token -gt $check_token ]]; then # The target version is greater. Fail. return 1 elif [[ $target_token -lt $check_token ]]; then # The version to check is greater. Succeed. return 0 fi # Tokens must be equal to one another. Continue to the next token. done return 2 } # Per 16634168 (and 16931797), remove launchd 2's "already migrated" flag. # Force launchd to upgrade from the overrides.plist data of launchd 1.0 if we're # upgrading from a source older than 10.10 (where launchd 2 was introduced). if sui_compare_version_numbers "10.10" "${SRCSYSTEMVERSION}"; then /bin/echo "Forcing launchd to migrate to newer launchd config"; /bin/rm -f "${DSTROOT}/private/var/db/com.apple.xpc.launchd/disabled.migrated" fi # Service list per 11065945, 11843741 obsoleteServices=( com.apple.AppleVNCServer com.apple.DeviceManagement.SCEPHelper com.apple.HeadlessStartup com.apple.IPAliases com.apple.Rooms com.apple.afctl com.apple.collabauthd com.apple.collabcored1 com.apple.collabcored2 com.apple.collabcored3 com.apple.collabcored4 com.apple.collabd com.apple.collabd.expire com.apple.collabd.notifications com.apple.collabd.quicklook com.apple.collabfeedd com.apple.collabsandboxd com.apple.devicemanager com.apple.diskspacemonitor com.apple.emailrules com.apple.emailrules.nightly com.apple.hwmond com.apple.learnjunkmail com.apple.mail_migration com.apple.natd com.apple.passwordreset com.apple.pcastserverd com.apple.ppp.l2tp com.apple.ppp.pptp com.apple.push_notify com.apple.salearn com.apple.serialnumberd com.apple.servermgrd com.apple.swupdate.host com.apple.swupdate.sync com.apple.updatesa com.apple.watchdogtimerd com.apple.wiki_sieve_manager com.apple.wikid com.apple.wikid.logcompressor com.apple.wikid.mailinglists com.apple.wikid.quicklook com.apple.xftpd com.apple.xgridd.pcastserver com.apple.xserve.serial-ports edu.cmu.andrew.cyrus.master org.addressbookserver.addressbookserver org.apache.htcacheclean org.apache.tomcat org.calendarserver.calendarserver org.clamav.clamd org.clamav.freshclam org.clamav.freshclam-init org.dovecot.dovecotd org.dovecot.fts.update org.jabber.jabberd org.jabber.jabberd_notification org.jabber.proxy65 org.list.mailmanctl org.mysql.mysqld org.postgresql.postgres org.amavis.amavisd org.amavis.amavisd_cleanup org.freeradius.radiusd org.isc.named ); function deleteObsoleteOverrides() { for obsoleteService in ${obsoleteServices[@]}; do /bin/echo removing override for ${obsoleteService}; ${plistBuddy} -c "delete :${obsoleteService}" "${finalDstRoot}/${overridesPath}" 2>/dev/null; done } # Updated per 10806436 serverExceptions=( org.apache.httpd org.net-snmp.snmpd ); function setDisabledKey() { local label="${1}"; local disabled="${2}"; ${plistBuddy} -c "add ${label} dict" "${finalDstRoot}/${overridesPath}" 2>/dev/null; ${plistBuddy} -c "delete :${label}:Disabled" "${finalDstRoot}/${overridesPath}" 2>/dev/null; ${plistBuddy} -c "add ${label}:Disabled bool ${disabled}" "${finalDstRoot}/${overridesPath}"; } function deleteReferenceToKey() { local label="${1}"; ${plistBuddy} -c "delete :${label}" "${finalDstRoot}/${overridesPath}" 2>/dev/null; } function applyCustomOverrides() { deleteReferenceToKey com.apple.mDNSResponder; deleteReferenceToKey com.apple.mDNSResponderHelper; deleteReferenceToKey com.apple.stackshot; setDisabledKey com.apple.hdiejectd 0; } function disableServerExceptions() { for exception in ${serverExceptions[@]}; do /bin/echo disabling ${exception}; setDisabledKey ${exception} 1; done } isServerMigration=0; # As of Mountain Lion, it's a server migration if the Source was a server. if [[ -e "${SRCROOT}/System/Library/CoreServices/ServerVersion.plist" ]]; then isServerMigration=1; fi if [[ ! -d "${finalDstRoot}/${overridesDir}" ]]; then /bin/mkdir -p "${finalDstRoot}/${overridesDir}"; fi # If we've copied over an overrides.plist, then let's just do some clean up if [[ -e "${DSTROOT}/${overridesPath}" ]]; then /bin/echo "Cleaning up contents of ${DSTROOT}/private/var/db/launchd.db"; disableServerExceptions; deleteObsoleteOverrides; for override in "${finalDstRoot}"/private/var/db/launchd.db/com.apple.launchd.peruser.*; do if [[ "${override}" =~ .*com.apple.launchd.peruser\.(.*) ]]; then chown -R "${BASH_REMATCH[1]}" "${override}"; fi done applyCustomOverrides; exit; fi # Otherwise, let's create an overrides.plist with the contents of the LaunchDaemon/LaunchAgent plist values /bin/echo "Migrating launchd states to overrides.plist"; /bin/rm -f "${finalDstRoot}/${overridesPath}"; for plist in "${SRCROOT}"/System/Library/LaunchDaemons/*.plist "${SRCROOT}"/System/Library/LaunchAgents/*.plist; do if [[ ${isServerMigration} == 1 ]]; then skip=0; for exception in ${serverExceptions[@]}; do if [[ ${plist} =~ ${exception} ]]; then /bin/echo skipping ${plist}; skip=1; break; fi done if [[ ${skip} == 1 ]]; then continue; fi fi disabled="`${plistBuddy} -c 'print Disabled' \"${plist}\" 2>&1`"; if [[ $? != "0" ]]; then disabled="0"; fi label="`${plistBuddy} -c 'print Label' \"${plist}\" 2>&1`"; if [[ $? != "0" ]]; then /bin/echo "Unable to get label for ${plist}; skipping..." continue; fi # 9724382 & 10516428 if [[ ${label} == "com.apple.stackshot" ]]; then continue; fi if [[ $? == "0" ]]; then setDisabledKey ${label} ${disabled}; /bin/chmod 600 "${finalDstRoot}/${overridesPath}"; fi done if [[ ${isServerMigration} == 1 ]]; then # Clean up override entries belonging to services which no longer exist deleteObsoleteOverrides; fi applyCustomOverrides;