Enable additional FileVault 2 users via script

maiksanftenberg
Contributor II

Hi all.

We are having a Institutional Key infrastructure for our 10.9 clients. At the moment we are in the middle of a project to enable AD binding and logon.

Some of this machines has a local account that is the same as there AD account is.
During the process of binding we are deleting the local account and change permissions for the User folder.

A problem we face is that we, after the first login, want to allow this users to enable themselves as FileVault 2 enabled Users (not all are admins).
What is the best way to do this?

Thanks for suggestions.

13 REPLIES 13

nkalister
Valued Contributor

if the mac is already encrypted you'll need to do some work before deleting the existing local account. You'd want to create a temporary account, enable that temp account for FV2 using the existing local account, then delete the existing local account, then cache the user's AD account, then use the temp account to enable the AD account, and finally delete the temp account.
FUN!!!!
but it does work, we use that workflow in production to convert local users over to AD when FV2 is already enabled.

pblake
Contributor III

Perhaps instead of deleting the local account, you can change the password. That way you have a fallback plan if any machines fail to grant access to the new AD user.

nkalister
Valued Contributor

we do both-our script backs up the existing home directory and dumps the local account from DSCL before deleting it. If the AD caching fails for any reason, we recreate the account from the DSCL dump and move the home dir back into place. I didn't want to have 2 accounts with the same name on the system at the same time, too much potential for confusion.

maiksanftenberg
Contributor II

@nkalister are you maybe able to share some of your scripts/workflows?
At the moment I'm a little bit stuck...

Thanks

teknikal35
New Contributor III

Hi Not sure if you have tried this, but I have a policy either self service or policy trigger at logout , when the userslogs out the for the first time they will be asked for their password, then encryption will begin,
All the user will need to do once is enter their usier account password

requirements, caspers 8.73/ 9.3 10.8.5 and 10.9 osx

thoule
Valued Contributor II

I've been working on this project for the last week. Nobody here uses AD binding and I want to roll it out. Some machines are using a local account with the same ID as their network name and others are not.

Currently I have two processes
1) on Unencrypted machines, I have a bind process that runs. It also installs an app I wrote (https://github.com/tmhoule/MigrateProfile) which moves the /Users/local to /Users/networkid and changes permissions. It also deletes the local account and gives admin rights to the user. Then the user logs in with AD creds, and gets their familiar desktop, etc.

2) on Encrypted machines, the local account is renamed to end with ".x". The machine is bound, home directory migrated as above, and rebooted. The user logs in with 'oldid.x', to get past FileVault. Then logs out, logs in with AD creds, and enables their account for FileVault and deletes the old local account. A very ugly situation.

I'm trying to get Security to approve turning off FileVault while the machine is bound, but that needs a review process. Sadly, I found that I can't reenable fileVault until it is fully decrypted and rebooted.

KyleEricson
Valued Contributor II

I have tried this on Mac OS X 10.13.3 and it error out with this:

Script result: spawn /usr/bin/fdesetup add -usertoadd <br/><br/>Error: Unrecognized option argument.<br/><br/>send: spawn id exp87 not open<br/> while executing<br/>"send -- Mypassword "<br/><br/>usage: grep [-abcDEFGHhIiJLlmnOoqRSsUVvwxZ] [-A num] [-B num] [-C[num]]<br/> [-e pattern] [-f file] [--binary-files=value] [--color=when]<br/> [--context[=num]] [--directories=action] [--label] [--line-buffered]<br/> [--null] [pattern] [file ...]<br/>Failed :(<br/>

https://github.com/UoE-macOS/jss/blob/master/coreconfig-filevault-add-mgmt-acct.sh

Read My Blog: https://www.ericsontech.com

nkalister
Valued Contributor

you should probably edit that post, @kerickson - looks like you posted a password there.
For 10.13 the prompts have changed and the expect section needs to send the user name first, then the password.

if [[ $OS -ge 9  ]] &&  [[ $OS -lt 13 ]]; then
    ## This "expect" block will populate answers for the fdesetup prompts that normally occur while hiding them from output
    expect -c "
    log_user 0
    spawn fdesetup changerecovery -personal
    expect "Enter a password for '/', or the recovery key:"
    send "{${userPass}}"
    send 
    log_user 1
    expect eof
    "
elif [[ $OS -ge 13 ]]; then
    expect -c "
    log_user 0
    spawn fdesetup changerecovery -personal
    expect "Enter the user name:"
    send {${userName}}
    send 
    expect "Enter a password for '/', or the recovery key:"
    send {${userPass}}
    send 
    log_user 1
    expect eof
    "
else
    echo "OS version not 10.9+ or OS version unrecognized"
    echo "$(/usr/bin/sw_vers -productVersion)"
    exit 5
fi

nkalister
Valued Contributor

oops, I tagged the wrong user!
@kericson : you probably should remove the PW from your post

KyleEricson
Valued Contributor II

@nkalister thanks I’ll try that.

Read My Blog: https://www.ericsontech.com

KyleEricson
Valued Contributor II

@nkalister I tired what you posted and said my os 10.13.3 was no recognized. I modified the script like you said and it failed too.

#!/bin/sh

get_password() {
  logger "$0: Asking for password"
  pwd="$(sudo -u ${current_user} osascript << EOF
  repeat while application "Finder" is not running
    delay 1
  end repeat
  tell application "Finder"
      activate
      with timeout of 36000 seconds
        set the_result to (display dialog "The Mac Supported Desktop requires access to the FileVault encryption on this computer to back up its encryption key.

Enter the password of an account which can unlock FileVault on this computer (this may be your own logon password).

Our use of this password is secure, and used only to safely gather the Filevault key. The password you type is not stored in any way. If you are unsure how to proceed, or want more information, contact the IS Helpline on 0131 6515151 advising that you are receiving this message."¬
          buttons {"Accept"} default button 1 with title "University of Edinburgh Mac Supported Desktop" default answer "" with hidden answer)
        set the_answer to text returned of the_result
      end timeout
  end tell
  return the_answer
  EOF
     )"
  if [ -z "${pwd}" ]
  then
    false
  else
    echo "${pwd}"
  fi
}
user_pwd="$(get_password)"
# Try enabling filevault
/usr/bin/expect -f- << EOT
  spawn /usr/bin/fdesetup add -usertoadd "${mgmt_user}"; 
  expect "Enter the username for the added user '${mgmt_user}':*" 
  send -- $(printf '%q' "${mgmt_pass}") 
  send -- "
"
  expect "Enter a password for '/', or the recovery key:*"
  send -- $(printf '%q' "${user_pwd}")  
  send -- "
"
  expect eof;
EOT
# Did we succeed?
if fdesetup list | grep -q ${mgmt_user}
then
  echo "Successs!"
  # Report our new-found success to the JSS
  /usr/local/bin/jamf recon
  exit 0
else
  echo "Failed :("
  exit 255
fi
Read My Blog: https://www.ericsontech.com

nkalister
Valued Contributor

@kericson the code i posted requires the script to determine the OS that's running on the mac- I don't see anything in what you posted that gets the OS version (is that your whole script?). If you're always getting os unrecognized it's because the if statement at the top of that snippet doesn't have the OS variable's populated.
for this script, the OS variable gets populated by

OS=`/usr/bin/sw_vers -productVersion | awk -F. {'print $2'}`

The script I use is a little different than what you're doing- since I have my management account enabled for FV, I know the username and password that need to be used so I don't have to prompt the user for anything. Hopefully it's still helpful to see all this in context. I replaced any sensitive info in the script with <removed>.

#!/bin/bash

####################################################################################################
#
# Copyright (c) 2013, JAMF Software, LLC.  All rights reserved.
#
#       Redistribution and use in source and binary forms, with or without
#       modification, are permitted provided that the following conditions are met:
#               * Redistributions of source code must retain the above copyright
#                 notice, this list of conditions and the following disclaimer.
#               * Redistributions in binary form must reproduce the above copyright
#                 notice, this list of conditions and the following disclaimer in the
#                 documentation and/or other materials provided with the distribution.
#               * Neither the name of the JAMF Software, LLC nor the
#                 names of its contributors may be used to endorse or promote products
#                 derived from this software without specific prior written permission.
#
#       THIS SOFTWARE IS PROVIDED BY JAMF SOFTWARE, LLC "AS IS" AND ANY
#       EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
#       WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
#       DISCLAIMED. IN NO EVENT SHALL JAMF SOFTWARE, LLC BE LIABLE FOR ANY
#       DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
#       (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
#       LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
#       ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
#       (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
#       SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
####################################################################################################
#
# Description
#
#   The purpose of this script is to allow a new individual recovery key to be issued
#   if the current key is invalid and the management account is not enabled for FV2,
#   or if the machine was encrypted outside of the JSS.
#
#   First put a configuration profile for FV2 recovery key redirection in place.
#   Ensure keys are being redirected to your JSS.
#
#   
#
####################################################################################################
# 
# HISTORY
#
#   -Created by Sam Fortuna on Sept. 5, 2014
#   -Updated by Sam Fortuna on Nov. 18, 2014
#       -Added support for 10.10
#       -Updated by Sam Fortuna on June 23, 2015
#           -Properly escapes special characters in user passwords
#      -Updated by Nick Kalister on Feb 2, 2018
#              -Added support for 10.13, encrypted string for pw and made script run silently.
#
####################################################################################################
#
## Get the logged in user's name
userName=<removed>

## Get the OS version
OS=`/usr/bin/sw_vers -productVersion | awk -F. {'print $2'}`

## This first sanity check makes sure the management account is already authorized for FileVault 2
userCheck=`fdesetup list | awk -v usrN="$userName" -F, 'index($0, usrN) {print $1}'`
if [ "${userCheck}" != "${userName}" ]; then
    echo "<removed> is not a FileVault 2 enabled user."
    exit 3
fi

## 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

## Get the authorized account's password via encrypted JSS parameter
SALT=<removed>
K=<removed>
userPass="$(echo "${4}" | /usr/bin/openssl enc -aes256 -d -a -A -S "$SALT" -k "$K")"
#sanity check the decrypted string
if [[ "$userPass" == "" ]]; then
    echo "userpass did not successfully decrypt, exiting"
    exit 1
else
    echo "Issuing new recovery key"
fi

if [[ $OS -ge 9  ]] &&  [[ $OS -lt 13 ]]; then
    ## This "expect" block will populate answers for the fdesetup prompts that normally occur while hiding them from output
    expect -c "
    log_user 0
    spawn fdesetup changerecovery -personal
    expect "Enter a password for '/', or the recovery key:"
    send "{${userPass}}"
    send 
    log_user 1
    expect eof
    "
elif [[ $OS -ge 13 ]]; then
    expect -c "
    log_user 0
    spawn fdesetup changerecovery -personal
    expect "Enter the user name:"
    send {${userName}}
    send 
    expect "Enter a password for '/', or the recovery key:"
    send {${userPass}}
    send 
    log_user 1
    expect eof
    "
else
    echo "OS version not 10.9+ or OS version unrecognized"
    echo "$(/usr/bin/sw_vers -productVersion)"
    exit 5
fi

exit 0

KyleEricson
Valued Contributor II

I got this to work.
This is for Mac OS 10.13

#!/bin/bash

###################################################################
#
# If this script is running, filevault is
# enabled but we neither have a valid recovery
# key nor is our management account able to 
# unlock the disk - we don't want to be in this 
# situation so we try to persuade the user to give
# us credentials that will allow us to add the 
# management user to filevault.
#
# Date: "Mon Sep 04 16:26:38 2016 +0100"
# Version: 0.1.4
# Origin: https://github.com/UoE-macOS/jss.git
# Released by JSS User: dsavage
#
##################################################################

current_user="${3}"
mgmt_user="${4}"
mgmt_pass="${5}"

get_password() {
  logger "$0: Asking for password"
  pwd="$(sudo -u ${current_user} osascript << EOF
  repeat while application "Finder" is not running
    delay 1
  end repeat
  tell application "Finder"
      activate
      with timeout of 36000 seconds
        set the_result to (display dialog "The True IT Dept. requires access to the FileVault encryption on this computer to back up its encryption key.

Enter your own logon password.

Our use of this password is secure, and used only to safely gather the Filevault key. The password you type is not stored in any way. If you are unsure how to proceed, or want more information, contact the IT HelpDesk at 555-555-555 advise them that you are receiving this message."¬
          buttons {"Accept"} default button 1 with title "IT Dept." default answer "" with hidden answer)
        set the_answer to text returned of the_result
      end timeout
  end tell
  return the_answer
  EOF
     )"
  if [ -z "${pwd}" ]
  then
    false
  else
    echo "${pwd}"
  fi
}
user_pwd="$(get_password)"
# Try enabling filevault
/usr/bin/expect -f- << EOT
  spawn /usr/bin/fdesetup add -usertoadd "${mgmt_user}"; 
  expect "Enter the username '${current_user}':*" 
  send -- $(printf '%q' "${current_user}") 
  send -- "
"
  expect "Enter the password '${user_pwd}':*" 
  send -- $(printf '%q' "${user_pwd}") 
  send -- "
"
  expect "Enter a password for '/', or the recovery key:*"
  send -- $(printf '%q' "${mgmt_pass}")  
  send -- "
"
  expect eof;
EOT
# Did we succeed?
if fdesetup list | grep -q ${mgmt_user}
then
  echo "Successs!"
  # Report our new-found success to the JSS
  /usr/local/bin/jamf recon
  exit 0
else
  echo "Failed :("
  exit 255
fi
Read My Blog: https://www.ericsontech.com