Migrate Mac from Centrify to Jamf Pro

LewisLebentz
New Contributor II

I need to migrate around 100 Centrify machines to Jamf Pro. Most of the devices already have Jamf Pro installed, but also have Centrify.

My aim is to remove Centrify, and keep the users data. However when running the Centrify uninstaller it unbinds the device from Active Directory breaking our Jamf Pro bind too. If I resolve that issue, the users permissions are still incorrect. I can manually resolve this by running the chown command, but that seems to break some Applications that need the wheel permission group.

I would like to be able to automate this process, and do it all remotely if possible. How could I achieve this?

7 REPLIES 7

roiegat
Contributor III

Not to familiar with Centrify but I'm assuming you can push a package to all your machines using it right? If so I would create a package based on the JAMF Pro quick installer package (you can create one using Casper Recon). Then add a post-install script that does the following:

1) Save user data to alternative location (like network share)
2) Run Centrify uninstaller
3) Run Jamf Pro binary to enroll machine. I usually use the following command:
sudo jamf createConf -url 'https://jss.company.com:8443/' -k;sudo jamf startSSH;sudo jamf enroll -invitation 166222421695850711274991501866187933345
4) Use JAMF Pro to rebind computer to AD
5) Have the script correct the permissions
6) Grab the user data from the network location

Good luck!

franton
Valued Contributor III

Ok Centrify is it's own AD bind, and doesn't store things in the dscl db the same way as the Apple plugin. It doesn't even use the same kind of record keeping! So yes, when you remove the Centrify bind you'll be left with a bunch of home folders and no internal records to reference them to anything.

The good news is that the home folders should have the same names as if you were using the Apple AD plugin. As a result, the process goes something like this: (Obviously testing is required!)

1) Remove Centrify from machine.
2) Rebind to AD using the Apple AD plugin.
3) Fix the home folder permissions.

That should allow the existing user to login and their locally cached data should remain intact.

Git is blocked at work so I can't currently link directly but pieces of the above are scattered all over my GitHub at http://www.github.com/franton

JPDyson
Valued Contributor

What @franton posted is true, and I would only add that it's beneficial to maybe manage these devices with Casper and then use Casper workflows to remove Centrify as he described. As a Centrify admin, I have some color commentary to add:

  • Whether or not Centrify was used to install additional Root CAs, de-binding and uninstalling it may remove them. Watch out if your company needs additional CAs installed (for example, internal CAs for your internal web servers).
  • If the above is a factor for you, you'll lose connectivity to your endpoints during the swap (assuming your JSS ends up signed by the same CA). You should design a Casper policy that works around this, for example by caching a package that installs and trusts your CA, then running a script like the one below. Your user should be logged out, obviously...

(this is a sketch - not a polished and tested script)

#!/bin/sh

# Leave the domain and force non-interactive uninstall Centrify
/usr/local/share/centrifydc/bin/adleave -f
/usr/local/share/centrifydc/bin/uninstall.sh -n -e

# install cached RootCA
/usr/local/bin/jamf installAllCached

# fix permissions
for USER_HOME in /Users/*
do
  USER_UID=`basename "${USER_HOME}"`
  chown "${USER_UID}" "${USER_HOME}"
done

# bind
/usr/local/bin/jamf policy -trigger adswap
# This would be another policy that performs your non-Centrify AD bind

# Exiting; should probably reboot now...
exit 0

Gordo_L
New Contributor

We just moved from Centrify to Apple AD plugin this past summer.

Post from Franton contained the basics of the procedure we also used for our migration.

A couple of the items we encountered were.
Shared devices. Something to keep in mind if you have labs etc... as your end users of those could encounter issues and fixing all of their home directory permissions on those devices as the users all log in on those previously used machines... If you have a 1 to 1 deployment fixing home folder issues for the most part wasn't a problem for those devices / users. Wished we had a script to handing the repairs at login but it worked out.

We un-bound before un-installing the client. In many cases we have left our AD centrify agent installed "just in-case" and will be un-installing the client on the next round of imaging...

If you are mapping any file shares via centrify / ad you might consider a good script to handle the mapping via Jamf.

Printer Shares and security were running from group policies which also needed to be redirected over to Jamf. Just takes a while to get everything migrated and tweaked...

Good Luck!

LewisLebentz
New Contributor II

Thanks for the responses. This is what I have achieved so far:

#!/bin/sh

#Echo on
set -x
#Add localadmin user
sysadminctl -addUser localadmin -fullName "localadmin" -UID 499 -password "pass" -home /Users/localadmin/ -admin

#Leave AD
adleave -r --user casper --password pass

#Sleep
sleep 15

#Uninstall Centrify
/bin/sh /usr/local/share/centrifydc/bin/uninstall.sh -n

#Change directory and download QuickAdd
cd /Users/Shared && curl -L -o QuickAdd.pkg https://goo.gl/something

#Install QuickAdd
installer -pkg QuickAdd.pkg -target /

#Remove QuickAdd installer
rm QuickAdd.pkg

#Bind to Active Directory
jamf policy -event Bind2

#Sleep
sleep 15

#Fix user permissions
for USER_HOME in /Users/*
do
  USER_UID=`basename "${USER_HOME}"`
  chown -R "${USER_UID}":"DOMAINDomain Users" "${USER_HOME}"
done

chown -R admin":"staff" /Users/admin

#Download 802.1x Certificate
jamf policy -event 802

#Prompt User for a new Hostname
hostname=$(/usr/bin/osascript <<-'__EOF__'
tell application "System Events"
  activate
  set input to display dialog "Enter New Computer Name: " default answer "" buttons {"OK"} default button 1
  return text returned of input as string
end tell
__EOF__
)

#Set hostname to value entered above
scutil --set ComputerName "$hostname"
scutil --set LocalHostName "$hostname"
scutil --set HostName "$hostname"

#Sleep
sleep 5

#Send FileVault key to Jamf
jamf policy -event NewFVKey

#Sleep
sleep 5

#Convert Mobile Account to Local Account
jamf policy -event MobileLocal

#Update inventory
jamf recon

The issue I am now having, is at some point after the unbind/permissions fix, it breaks the account, so that the 802.1x profile cannot be installed. I cannot open System Preferences, until the Mac is restarted.

I need to run the 802.1x command as the user, as we use user certificates. So I cannot run this under the admin account.

Can I restart through the script, then resume it after a reboot?

znilsson
Contributor II

Here's a script from macmule. All glory to macmule.

#!/bin/sh
####################################################################################################
#
# More information: http://macmule.com/2013/02/18/correct-ad-users-home-mobile-home-folder-permissions/
#
# GitRepo: https://github.com/macmule/CorrectADUsersHomeFolderPermissions
#
# License: http://macmule.com/license/
#
####################################################################################################

###
# Get the Active Directory Node Name
###
adNodeName=`dscl /Search read /Groups/Domain Users | awk '/^AppleMetaNodeLocation:/,/^AppleMetaRecordName:/' | head -2 | tail -1 | cut -c 2-`

###
# Get the Domain Users groups Numeric ID
###
domainUsersPrimaryGroupID=`dscl /Search read /Groups/Domain Users | grep PrimaryGroupID | awk '{ print $2}'`

###
# Gets the unique ID of the Users account locally, if that fails performs a lookup
###
  uniqueID () 
{       
        # Attempt to query the local directory for the users UniqueID
        accountUniqueID=`dscl . -read /Users/$1 2>/dev/null | grep UniqueID | cut -c 11-`

        # If no value recived for the Users account, attempt a lookup on the domain
        if [ -z "$accountUniqueID" ]; then
                    echo "Account is not on this mac..."
                    accountUniqueID=`dscl "$adNodeName" -read /Users/$1 2>/dev/null | grep UniqueID | awk '{ print $2}'`
        fi
}

###
# Sets IFS to newline
###
IFS=$'
'

###
# Returns a list of all folders found under /Users
###
for userFolders in `ls -d -1 /Users/* | cut -c 8- | sed -e 's/ /\ /g' | grep -v "Shared"`

do
    # Return folder name found in /Users/
    echo "$userFolders..."
    # Check to see if folders contain a /Desktop folder, if they do assume it's a Home Folder
    if [ -d /Users/"$userFolders"/Desktop ]; then

        # Pass $userFolders to function uniqueID
        uniqueID "$userFolders"
        echo "User $userFolders's UniqueID = $accountUniqueID..."

        ### The below is well echoed so should be explanatory ###

        if [ -z "$accountUniqueID" ]; then

            echo "Account is not local & cannot be found on $adNodeName... "
            echo "Removing all ACL's from /Users/$userFolders/ Account..."   
            sudo chmod -R -N /Users/$userFolders

            echo "Clearing locks on any locked files/folder found in /Users/$userFolders/..."
            sudo chflags -R nouchg /Users/$userFolders

            echo "Making /Users/$userFolders/ fully accessible to all..."
            sudo chmod -R 777 /Users/$userFolders

        else

            echo "Removing all ACL's from /Users/$userFolders/ Account..."   
            sudo chmod -R -N /Users/$userFolders

            echo "Clearing locks on any locked files/folder found in /Users/$userFolders/..."
            sudo chflags -R nouchg /Users/$userFolders

                if [ 1000 -gt "$accountUniqueID" ]; then
                    echo "$accountUniqueID is a local account..."
                    echo "As local account, setting Owners to $accountUniqueID:staff..."
                    sudo chown -R $accountUniqueID:staff /Users/$userFolders/
                else
                    echo "User $userFolders is a Domain account..."
                    echo "$domainUsersPrimaryGroupID is the ID for the Domain Users group..."
                    echo "As domain account, setting Owners to $accountUniqueID:$domainUsersPrimaryGroupID..."
                    sudo chown -R $accountUniqueID:$domainUsersPrimaryGroupID /Users/$userFolders
                fi

            echo "Setting rwxr--r-- permission for Owner, Read for Everyone for everything under /Users/$userFolders..."
            sudo chmod -R 755 /Users/$userFolders/

            if [ -d /Users/$userFolders/Desktop/ ]; then
                echo "Setting rwx permission for Owner, None for Everyone for /Users/$userFolders/Desktop..."
                sudo chmod 700 /Users/$userFolders/Desktop/
            fi

            if [ -d /Users/$userFolders/Documents/ ]; then
                echo "Setting rwx permission for Owner, None for Everyone for /Users/$userFolders/Documents..."
                sudo chmod 700 /Users/$userFolders/Documents/
            fi

            if [ -d /Users/$userFolders/Downloads/ ]; then
                echo "Setting rwx permission for Owner, None for Everyone for /Users/$userFolders/Downloads..."
                sudo chmod 700 /Users/$userFolders/Downloads/
            fi

            if [ -d /Users/$userFolders/Library/ ]; then
                echo "Setting rwx permission for Owner, None for Everyone for /Users/$userFolders/Library..."
                sudo chmod 700 /Users/$userFolders/Library/
            fi

            if [ -d /Users/$userFolders/Movies/ ]; then
                echo "Setting rwx permission for Owner, None for Everyone for /Users/$userFolders/Movies..."
                sudo chmod 700 /Users/$userFolders/Movies/
            fi

            if [ -d /Users/$userFolders/Music/ ]; then
                echo "Setting rwx permission for Owner, None for Everyone for /Users/$userFolders/Music..."
                sudo chmod 700 /Users/$userFolders/Music/
            fi

            if [ -d /Users/$userFolders/Pictures/ ]; then
                echo "Setting rwx permission for Owner, None for Everyone for /Users/$userFolders/Pictures..."
                sudo chmod 700 /Users/$userFolders/Pictures/
            fi

                # If the Public folder exists in /Users/$userFolders/, give it it's special permissions
                if [ -d /Users/$userFolders/Public/ ]; then
                    echo "Setting Read only access for Everyone to /Users/$userFolders/Public/..."
                    sudo chmod -R 755 /Users/$userFolders/Public
                        # If the Drop Box folder exists in /Users/$userFolders/, give it it's special permissions
                        if [ -d /Users/$userFolders/Public/Drop Box/ ]; then
                            echo "Drop Box folder found, setting Write only access for Everyone to /Users/$userFolders/Public/Drop Box/..."
                            sudo chmod -R 733 /Users/$userFolders/Public/Drop Box/
                        fi
                else
                # Notify if not found
                    echo "Public folder not found @ /Users/$userFolders/Public/..."
                fi

                # If the Sites folder exists in /Users/$userFolders/, give it it's special permissions
                if [ -d /Users/$userFolders/Sites/ ]; then
                    echo "Setting Read only access for Everyone to /Users/$userFolders/Public/..."
                    sudo chmod -R 755 /Users/$userFolders/Public
                else
                # Notify if not found
                    echo "Sites folder not found @ /Users/$userFolders/Sites/..."
                fi
            fi
            #Creates a new line in the output, making it more readable
            echo ""
    else
        echo "No Desktop folder in /Users/$userFolders/.. Setting rwx for all to /Users/$userFolders/..."
        sudo chmod -R 777 /Users/$userFolders/
    fi

done

###
# Resets IFS
###
unset IFS

LewisLebentz
New Contributor II

Thanks!

Will give that a try.

If I am repairing permissions mid way through the migration, will that cause any issues with the rest of the script running?

As I think that might be why the 802.1x mobile config profile isn't installing. As I wasn't able to access System Prefs after making the changes in the script above. A restart resolves it though, but I can't do that in the middle of running the script.