Mojave deployment: FV2 end user and IT admin account.

aalberty
New Contributor III

The end goal with our deployments is that the machine is encrypted, and that IT has access to the machine with or without the user present.

From my understanding this means that the end user needs to have a FV2 enabled account, and the IT account also needs to be FV2 enabled.

So far what we've been doing is enrolling machines through DEP, and using a config profile to enforce FV2 and escrow the key. Then we manually add the IT account as a FV2 user on the machine.

What I would like to do is find a way to script out adding the administrator account as a FV2 user, or at least a very smooth way to run this deployment with minimal IT interaction with the machine so that we can deploy smoothly to remote users as well. Anyone else in a similar situation here that has found a nice solution?

One thought that I had was maybe having a script that is passed the admin creds, and with the jamf dialog requests the user creds, then uses those to enable the admin account for FV2, however I'm not sure of a way to do this without storing creds in the clear somewhere. Any further thoughts here would be appreciated.

2 REPLIES 2

aalberty
New Contributor III

Update: Thought about trying to use Azure Key Storage to store the creds and finding a way to access them from the end user machine, however any automated way of doing this would involve passing along Azure secrets in the same manner we were looking to pass the username and password, so I opted out of this. I'm going to continue trying to tackle this problem, but in the meantime, I wrote a small script to check users daily, and notify me of any users that need the admin account FV2 enabled.

patgmac
Contributor III

Here's how I do it. Use $4 to pass the password for the local admin. Could benefit from some clean up (took bits from a different script I use for a similar purpose), but it works.

#!/bin/bash
###
#
#            Name:  secureTokenAdmin.sh
#     Description:  Grants a SecureToken to the localadmin account
#          Author:  Patrick Gallagher
#   Last Modified:  2019-02-19
#
###

## Set the target user's username, as well as the logged in user
adminUser=$(/usr/bin/stat -f%Su /dev/console)
userName="localadmin"
customtrigger="trigger_name"
## Text Display Variables
# Each time you call this, set jhTitle, jhHeading, and jhDescription, and optionally icon
windowType="hud"        #   [hud | utility | fs]
#windowPostion="ul"          #   [ul | ll | ur | lr]
jhTitle="Title"     #   "string"
jhHeading=""            #   "string"
jhDescription=""            #   "string"
icon="/Library/User Pictures/pic.png"               #   path
iconSize=128              #   pixels
countdown=3                 #   int
#timeout="$countdown"
alignDescription="left"     #   [right | left | center | justified | natural]
alignHeading="left"                 #   [right | left | center | justified | natural]
jamfhelper="/Library/Application Support/JAMF/bin/jamfHelper.app/Contents/MacOS/jamfhelper"

## OS Version check
osversionlong=$(sw_vers -productVersion)
osvers=$(echo "$osversionlong" | cut -d. -f2)

## Check to see if the encryption process is complete
encryptCheck="$(fdesetup status)"
statusCheck="$(echo "${encryptCheck}" | grep "FileVault is On.")"
expectedStatus="FileVault is On."
if [ "${statusCheck}" != "${expectedStatus}" ]; then
  echo "The encryption process has not completed."
  echo "${encryptCheck}"
  exit 4
fi

## Make sure account is not already enabled for FV2, exit if it is
fv2Check=$(/usr/bin/fdesetup list | grep "^$userName")
if [[ $fv2Check ]]; then
  echo "$userName already enabled for FileVault2. Exiting..."
  exit 0
fi

## This first user check sees if the logged in account is already authorized with FileVault 2. Notify if not.
adminCheck="$(/usr/bin/fdesetup list | grep "^$adminUser")"
if [[ ! "$adminCheck" ]]; then
  echo "$adminUser is not enable for FileVault"
  exit 3
else
  echo "$adminUser is enabled for FileVault 2... Proceeding"
fi

## Tell the user what we're doing
jhHeading=""
jhDescription="So that IT can provide proper support, we need to add an account for the desktop technicians."
windowType="utility"
"$jamfhelper" -windowType "$windowType" -title "$jhTitle" -button1 "Ok" -defaultButton 1 -heading "$jhHeading" -description "$jhDescription" -countdown "$countdown" -icon "$icon" -iconSize "$iconSize" -alignDescription "$alignDescription" -alignHeading "$alignHeading"

## Capture new team member password and test credentials, looping until correct or three incorrect attempts
wbPass="$4"

## Get the logged in user's password via a prompt
echo "Prompting $adminUser for their login password."
adminPass="$(/usr/bin/osascript -e 'Tell application "System Events" to display dialog "Please enter password for the current logged in user:" default answer "" with title "Login Password" with text buttons {"Ok"} default button 1 with hidden answer' -e 'text returned of result')"

## Check password against correct authentication authority - local for local users, AD for mobile accounts
authDomain=$(dscl . read /Users/"$adminUser" OriginalAuthenticationAuthority)
if [[ $authDomain ]]; then
  echo "$adminUser"
  testAdminUserCreds="$(/usr/bin/dscl /Active Directory/AMER/All Domains -authonly "$adminUser" "$adminPass")"
else
  testAdminUserCreds="$(/usr/bin/dscl /Local/Default -authonly "$adminUser" "$adminPass")"
fi

## Give user three chances to enter a correct password, hitting the correct auth authority, exit if user cancels
i=0
while [[ $testAdminUserCreds && $i -lt 3 ]]; do
  echo "Password incorrect for $adminUser..."
  adminPass="$(/usr/bin/osascript -e 'Tell application "System Events" to display dialog "Password is incorrect. Please enter your current login password" default answer "" with title "Login Password" with text buttons {"Ok"} default button "Ok" with hidden answer' -e 'text returned of result')"
  if [[ $authDomain ]]; then
    testAdminUserCreds="$(/usr/bin/dscl /Active Directory/AMER/All Domains -authonly "$adminUser" "$adminPass")"
  else
    testAdminUserCreds="$(/usr/bin/dscl /Local/Default -authonly "$adminUser" "$adminPass")"
  fi
  i=$((i + 1))
done

if [[ $i -eq 3 ]]; then
  echo "Three failed password attempts... exiting."
  # Set notification criteria and notify end user - leave newline and whitespace for jhHeading
  jhHeading="Incorrect Password"
  jhDescription="Your entered the password three times incorrectly.

  We'll try again later"
  "$jamfhelper" -windowType "$windowType" -title "$jhTitle" -heading "$jhHeading" -description "$jhDescription" -countdown "$countdown" -icon "$icon" -iconSize "$iconSize" -alignDescription "$alignDescription" -alignHeading "$alignHeading"
  exit 1
fi

# WhoHasSecureToken spot

function createUserSierra() {
  ## Create local account for new team member, if account doesn't exist - matches literal from beginning of line to end of line to exclude la-, ca-, etc. accounts
  userExist=$(/usr/bin/dscl . -list /Users | grep "^$userName$")
  if [[ ! $userExist ]]; then
    echo "User does not exist... creating local account for $userName"
    /usr/local/bin/jamf policy -event $customtrigger -forceNoRecon
  else
    echo "$userName already has an account..."
  fi
}

function createUserHighSierra() {
  userExist=$(/usr/bin/dscl . -list /Users | grep "^$userName$")
  if [[ ! $userExist ]]; then
    TestAdminToken=$( (sysadminctl -adminUser $adminUser -adminPassword $adminPass -secureTokenStatus $adminUser) 2>&1)
    if [[ "$TestAdminToken" == *"ENABLED"* ]]; then
      echo "Creating User account..."
      /usr/local/bin/jamf policy -event $customtrigger -forceNoRecon
      /usr/sbin/sysadminctl -adminUser "$adminUser" -adminPassword "$adminPass" 
      -secureTokenOn "$userName" -password "$wbPass" -admin
    else
      #WhoHasSecureToken
      jhTitle="Error"
      echo "Existing Admin is not enabled for SecureToken"
      jhHeading="Problem adding account"
      jhDescription="We are not able to add the local admin account because you don't have a SecureToken (long story).

      The following users are able to add others (if any): ${list[*]}"
      "$jamfhelper" -windowType "$windowType" -title "$jhTitle" -heading "$jhHeading" -description "$jhDescription" -countdown "$countdown" -icon "$icon" -iconSize "$iconSize" -alignDescription "$alignDescription" -alignHeading "$alignHeading" &
      exit 12
    fi
  else
    echo "$userName already has an account..."
    echo "Adding $userName to FileVault"
    /usr/sbin/sysadminctl -adminUser "$adminUser" -adminPassword "$adminPass" 
    -secureTokenOn "$userName" -password "$wbPass" -admin
  fi
}


# Create the new user account
if [ "$osvers" -lt 13 ]; then
    createUserSierra
else
  createUserHighSierra
fi

fv2Check=$(/usr/bin/fdesetup list | grep "^$userName")
if [[ $fv2Check ]]; then
  echo "$userName has been added to FileVault 2."
  jhTitle="Success"
  jhHeading="Admin Added."
  jhDescription="$userName has been added to this Mac. Thank you for your patience."
  "$jamfhelper" -windowType "$windowType" -title "$jhTitle" -heading -button1 "Ok" -defaultButton 1 "$jhHeading" -description "$jhDescription" -countdown "$countdown" -icon "$icon" -iconSize "$iconSize" -alignDescription "$alignDescription" -alignHeading "$alignHeading" &
else
  jhTitle="Error"
  echo "User has not been successfully added to FileVault 2."
  jhHeading="User has NOT been added."
  jhDescription="$userName has not been successfully added.

Please contact an administrator to check the logs to see what went wrong."
  "$jamfhelper" -windowType "$windowType" -title "$jhTitle" -heading "$jhHeading" -button1 "Ok" -defaultButton 1 -description "$jhDescription" -countdown "$countdown" -icon "$icon" -iconSize "$iconSize" -alignDescription "$alignDescription" -alignHeading "$alignHeading" &
  exit 1
fi