Add local admin to FileVault via script?

znilsson
Contributor II

Because we set up Casper in an environment with established Macs already and we needed to active FileVault on all of them, our policy uses a FileVault setup that is set for current/next user. And that works fine for our end users, but Casper also installs a local admin account on their Macs (separate from the JSS management account), and the problem ends up being that after the end user's Mac is encrypted and they're added to FileVault, the local admin account does not show up on the FileVault login screen after a reboot, because the local admin account was never added to FileVault.

So I'm trying to find a way to just set a policy to remotely add the local admin account ("administrator" in this example) to FileVault on all our Macs, to ensure that we can log into them as the admin user from a reboot or cold boot. I haven't had much experience with fdesetup, and the man page says a password will be needed, but none of the fdesetup options includes the option to add a password, so I'm not sure how that's supposed to work.

The local admin account and its password are the same on every Mac, so I can enter them as static values into a script. So given the example below, A) will that work? and B) how do I embed the password into that command to let FileVault enable that user?

fdesetup add -usertoadd administrator
11 REPLIES 11

easyedc
Valued Contributor II

Try something like this.

fdesetup add -usertoadd $userid -p -keychain $password

Digging through the recesses of my brain, I think that's how I did it a while back.

rtrouton
Release Candidate Programs Tester

I have a post on how to do this with fdesetup add, available via the link below:

https://derflounder.wordpress.com/2015/12/20/managing-el-capitans-filevault-2-with-fdesetup/ (see the Adding Additional Users After Filevault 2 Has Been Enabled section.)

znilsson
Contributor II

@easyedc @rtrouton Thanks. Rich, your link in that section shows how to use the -usertoadd, but then it looks like it asks for a password. I was asking how to embed the password directly into the command, to bypass the user interaction part of it. I just want it to add the user to FileVault with one command and no user interaction. Hopefully without having to create or modify a .plist file.

But if creating a .plist file is the only way to do it, I'm not clear on your example in the link you posted, as in:

<?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>Username</key>
<string>username</string>
<key>Password</key>
<string>password</string>
<key>AdditionalUsers</key>
<array>
    <dict>
        <key>Username</key>
        <string>username</string>
        <key>Password</key>
        <string>password</string>
    </dict>
    <dict>
        <key>Username</key>
        <string>username</string>
        <key>Password</key>
        <string>password</string>
    </dict>
</array>
</dict>
</plist>

So you have the same block of info three times there, are all three of them referring to the account you want to enable for filevault, or only one of them? Do you need both dict blocks in that array, or is that just for example's sake? And is the first block for the account you are trying to enable, or a different account?

Sorry for the stupid questions, but I don't really understand how it's supposed to work. We just have one local admin account on each Mac that we want to enable for filevault, called "administrator" with "password" (not actual name and password, of course) So I mean should it look like this?

<?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>Username</key>
<string>administrator</string>
<key>Password</key>
<string>password</string>
<key>AdditionalUsers</key>
<array>
    <dict>
        <key>Username</key>
        <string>administrator</string>
        <key>Password</key>
        <string>password</string>
    </dict>
    <dict>
        <key>Username</key>
        <string>administrator</string>
        <key>Password</key>
        <string>password</string>
    </dict>
</array>
</dict>
</plist>

mm2270
Legendary Contributor III

The first section

<key>Username</key>
<string>administrator</string>
<key>Password</key>
<string>password</string>

Needs to have an account name and password that is already enabled for FileVault. This part of the plist allows for fdesetup to authenticate the changes its about to make.

The section labeled as AdditionalUsers with the array below it is where you need to put in account names and passwords that you are trying to ADD to FileVault.

If you only have one to add, then the additional dict section isn't needed. It can just look like

<key>AdditionalUsers</key>
<array>
    <dict>
        <key>Username</key>
        <string>administrator</string>
        <key>Password</key>
        <string>password</string>
    </dict>
</array>

So the short answer is, these 2 sections can't, by definition, be the same. If they were, it would mean either the account you're trying to add isn't enabled already for FileVault, and therefore trying to add itself in will fail, or, if it is enabled, then the whole thing is moot since, why add it in again?

znilsson
Contributor II

@mm2270 Thanks. So we can't really use this method then, because in the cases where our admin account isn't enabled, the only account that is enabled is the end user, which of course is different on every Mac and we don't have their passwords either.

stevewood
Honored Contributor II
Honored Contributor II

@znilsson If you're not adverse to getting the end user involved, you can still do this. I used a this method to move computers from one AD domain to a new domain, and utilized cocoaDialog to ask the end user for their current password to do so. You can read about that here.

The script I used is posted here: Move AD Domain

Basically, this is the piece you'd want:

if [[ "$ENCRYPTIONEXTENTS" = "Yes" ]]; then

    # now we need to add the new UID to FV2
    # Use cocoaDialog to get the current user's password
    userPassword=`$CD standard-inputbox --informative-text "Please enter your $newAD password:" --float`
    userPassword=`echo $userPassword | awk '{ print $2 }'`

    # create the plist file:
    echo '<?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>Username</key>
    <string>'$4'</string>
    <key>Password</key>
    <string>'$5'</string>
    <key>AdditionalUsers</key>
    <array>
        <dict>
            <key>Username</key>
            <string>'$loggedInUser'</string>
            <key>Password</key>
            <string>'$userPassword'</string>
        </dict>
    </array>
    </dict>
    </plist>' > /tmp/fvenable.plist  ### you can place this file anywhere just adjust the fdesetup line below

    # now enable FileVault
    fdesetup add -i < /tmp/fvenable.plist

fi

You'd need to change up the blocks so that they look like this:

if [[ "$ENCRYPTIONEXTENTS" = "Yes" ]]; then

    # now we need to add the new UID to FV2
    # Use cocoaDialog to get the current user's password
    userPassword=`$CD standard-inputbox --informative-text "Please enter your $newAD password:" --float`
    userPassword=`echo $userPassword | awk '{ print $2 }'`

    # create the plist file:
    echo '<?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>Username</key>
    <string>'$loggedInUser'</string>
    <key>Password</key>
    <string>'$userPassword'</string>
    <key>AdditionalUsers</key>
    <array>
        <dict>
            <key>Username</key>
            <string>'$4'</string>
            <key>Password</key>
            <string>'$5'</string>
        </dict>
    </array>
    </dict>
    </plist>' > /tmp/fvenable.plist  ### you can place this file anywhere just adjust the fdesetup line below

    # now enable FileVault
    fdesetup add -i < /tmp/fvenable.plist

fi

You can then use the $4 and $5 parameters in the JSS to pass the admin user info to add to FV.

Olivier
New Contributor II

I agree with mm2270, and we hit same problem since Apple added some restrictions in 10.9.x : to add our own special admin account to FV user list after FV has been enabled for the user, you must involve either the user to ask for his password, or know the individual recovery key that is uploaded to JSS.

As extracting recovery keys from JSS from the client machine using a shell script, just for the purpose of adding a user to FV user list, is not really "secure"( = if you are smart, you could access all keys for all machines), so we went with 1st solution with a simple CocoaDialog popup.

Maybe forcing a rotation of the local recovery key, would give you the necessary key to run later with fdesetup add and the plist file. Unfortunately, I haven't yet digged much on how Jamf client is suppose to guess that recovery key suddenly changed, in order to re-upload the most recent one to JSS...

glee_edin
New Contributor

Hi there,

I have a script which does, I think, what you are looking for. In our case, the script kicks in if the JSS detects that the management account is not FV-enabled and that the JSS doesn't have a valid recovery key to use to enable it. It asks the user for their password, and then uses it to add the JSS management account (of which we know the username and password) to filevault.

I took the route of passing the password to fdesetup on STDIN rather than creating a plist file, as this seems more secure (the password is passed through a pipe rather than sitting in a file on disk at any point) though there are doubtless ways it can be hijacked by someone with control of the box.

YMMV but if it's useful you can find it on GitHub

The script is scoped to a Smart Group which contains only machines where we have no valid FV key and the management account is not FV enabled.

HTH!

-geoff

edit: According to this heredocuments do in fact create temporary files, so I'm not sure that my 'expect' method has anything over creating a plist. In fact, if you 'shred' the plist afterwards that might be better.

felix_fx2
New Contributor

Hi geoff,

Can your script be run on it's own without JSS ?
I've got to add my IT user to unlock FileVault enabled endpoints and sourcing for solutions... big headache :(

KyleEricson
Valued Contributor II

@glee_edin I've been trying to get your script to work with Mac OS 10.13.2. It keep failing I have even tried to just run it without JAMF but it still fails. I can run the command manually and it works but running the .sh fails to add my users.

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

glee_edin
New Contributor

Hi - sorry, I don't think it works in 10.13 because of the stuff involving secure tokens. I suspect it can be fixed bu haven't had a chance to take a look yet.

I've replied in more detail to your issue on github - thanks!

https://github.com/UoE-macOS/jss/issues/16