rename user account with script at loginwindow

L3nny5
New Contributor III

Hello jamfnation,

I have a question. I try to rename some user accounts to match the company pattern. We want to do this process as smooth as possible for the user and admins. Therefore I've written a script which checks values and asks the user several questions which in the end creates a plist with some variables. After that the script reboots the computer and uses Rich Troutons "First Boot Package Install" (script almost completely rewritten) to show a log to the user what is happening. At that window the script, which is started by a LaunchDaemon, uses dscl to change the homefolder, uses mv to move the homefolder and again uses dscl to change the username.

Now my problem:
In order for dscl or mv to be able to change the homefolder it needs access to it (PPPC). My script is signed and stays signed, and a PPPCP is in place to allow for my script to access Admin Files and/or All Files. I also tried the unsecure way and allowed /bin/bash access to AdminFiles/AllFiles.
However it is not working.
When I inspect the logs of com.apple.TCC I see this entry:

Refusing TCCAccessRequest for service kTCCServiceSystemPolicySysAdminFiles from client /bin/bash in background

If I try the same script manually from terminal (not via LaunchDaemon) I get this at com.apple.TCC, which I know how to allow:

Prompting for access to kTCCServiceSystemPolicySysAdminFiles from /System/Applications/Utilities/Terminal.app/Contents/MacOS/Terminal on behalf of /usr/bin/dscl

and this prompting
e2f2cc96ed1045a8abd33961f0d69e4e

Now my question:
What am I missing?

Is it somehow not possible for a script, started via LaunchDaemon at loginwindow (without any user logged in), to leverage PPPCP to be able to access local user homes?

Any ideas how to get around it?

I hope you can help me!

Thanks

Lenny

6 REPLIES 6

Chris_Hafner
Valued Contributor II

I'll be watching this closely. How are you dealing with FV2 login?

mm2270
Legendary Contributor III

I'm going to revive this thread, because I'm facing a similar issue. In the org I work in, contractors have specific usernames that start with a different character (followed by 6 numbers) than full time employees. Once someone gets converted from contract to full time, we will have to migrate their existing user account from the old to the new, which means renaming their account. Everyone has to log into their computers using their official domain account name/password.

I'm trying to figure out an effective way to accomplish this. On top of the expected complexities, there is FV2 at play as well, which will make things... interesting.

Has anyone tackled this yet and come up with a smooth way to do it that doesn't involve physically touching the machine, since this won't always be possible with far flung remote workers?

jhuls
Contributor III

@mm2270 I don't have a reason to implement anything like this but I typically find that if you're asking how to do something, I'll probably run into a similar issue in a year or two or three...ok, four. lol

Mauricio
Contributor III

@mm2270 We have developed and application for similar purpose.

The Groupe acquires agencies and we need to integrate the devices into our Jamf and one of the tasks is to convert either the AD account (old domain/and unbind it) or a non-standard named one to the the official account in our AD system.
This app converts the logged account to the official account (local) and we use Enterprise Connect to sync the passwords to AD.

The app is run by the end users so little IT intervention is required (all we ask is for the users to read the BIG print - always backup your data!) and FileVault is updated to reflect that too.

In terms of PPPC we had to allow loads of commands as SIP prevents/restricts any scripting touching the user's home directory.
There is a Configuration Profile in Jamf for this job and the app scopes the device in and out of that profile.

We are having a high success rate but on a world of IT it is never smooth and we have some issues.
Having said that, this enables us to get the job done anywhere as far they can reach the Jamf!

The image below shows what we did for the app's configuration profile.

002c7f6a3e944e4b9d7be97bfc5582ca

Chris_Hafner
Valued Contributor II

I'd be happy to help revisit some things I was working on a few years back to do just this. Specifically, I was migrating accounts on the fly. (local to local) by, essentially deleting the DSCL record, renaming the users home directory (While snagging credentials from the Enterprise Connect keychain entry as we're non-bound) and then creating a new user with that directory. The issue at hand just comes down to the fact that the new user account needs to be created by an account that already has a secure token. Not that this is news to you of course, and I highly doubt that any info in the cobbled together script will help, but aside from the FV2 issues, it did work well enough though if I were to revisit this, I would really change how I am gaining access to the keychain. But the need was quick so I just borrowed something JAMF put together for transitioning old Mobile accounts to Local accounts and stuck several forks in it at odd angles until it was functional.

#!/bin/sh
####################################################################################################
#
# ABOUT
#
#   Convert Mobile Account to Local Account
#   Based on: https://jamfnation.jamfsoftware.com/discussion.html?id=12462#responseChild73117
#
#   This script is designed to remove a mobile user account and re-create
#   a local account with the same username and the password from user-input.
#   It will also give read/write permissions to the user's home folder.
#
####################################################################################################
#
# HISTORY
#
#   Version 1.0, 28-Apr-2016, Dan K. Snelson
#   Version 1.1, 02-May-2016, Dan K. Snelson
#       Removed code and verbiage about the user's keychain
#   Version 1.2, 03-May-2016, Dan K. Snelson
#       Fixed error when no users with 5nn UID existed
#   Version 1.2 Brewster Edition 27-July-2018, Chris Hafner
#       Modified to allow account conversion from personal local, to EC User local account.
#

####################################################################################################
# Import general functions
source /Users/Shared/Client-Side-Functions.sh
####################################################################################################

ScriptLog "###############################################"
ScriptLog "### Convert Personal Local Account to Brewsterized Local Account ###"
ScriptLog "###############################################"

### Variables
loggedInUser=`python -c 'from SystemConfiguration import SCDynamicStoreCopyConsoleUser; import sys; username = (SCDynamicStoreCopyConsoleUser(None, None, None) or [None])[0]; username = [username,""][username in [u"loginwindow", None, u""]]; sys.stdout.write(username + "
");'`
UserUID=`/usr/bin/dscl . read /Users/"${loggedInUser}" UniqueID | grep UniqueID: | cut -c 11-`
userRealName=`/usr/bin/dscl . -read /Users/"${loggedInUser}" | /usr/bin/grep RealName: | cut -c11-`
user_home_location=`/usr/bin/dscl . -read /Users/"${loggedInUser}" NFSHomeDirectory 2>/dev/null | /usr/bin/sed 's/^[^/]*//g'`

# Echo variables
ScriptLog "Variables ..."
ScriptLog "* loggedInUser=${loggedInUser}"
ScriptLog "* UserUID=${UserUID}"
ScriptLog "* userRealName=${userRealName}"
ScriptLog "* adminStatus=${userIsAdmin}"
ScriptLog "* ec_user=${ec_user}"

#This will set the "admiStatus" to nothing in all circumstances. I've just left the line here in case I change my mind later. Proper adminStatus would be -admin for a non-standard user.
if [[ $(/usr/bin/dsmemberutil checkmembership -U "${loggedInUser}" -G admin) != *not* ]]; then
    adminStatus=""
    userIsAdmin="Yes"
else
    adminStatus=""
    userIsAdmin="No"
fi

if [[ -d "/Applications/Enterprise Connect.app" ]]; then
    /usr/bin/security find-generic-password -l "Enterprise Connect" "${user_home_location}"/Library/Keychains/login.keychain > /dev/null 2>&1
    if [[ $? -eq 0 ]]; then
        ec_user=`/usr/bin/security find-generic-password -l "Enterprise Connect" | grep "acct" | awk -F "=" '{print $2}' | tr -d """`
        ec_userPW=`/usr/bin/security find-generic-password -l "Enterprise Connect" -w`
    fi
fi

#Rename home directory
ScriptLog "* Moving Home Directory ..."
mv $user_home_location /Users/$ec_user

# Delete the currently logged-in user account
ScriptLog "* Deleting ${loggedInUser} account from client-side directory ..."
sysadminctl -deleteUser "$loggedInUser" -keepHome

Gets the current highest user UID
ScriptLog "* Discovering the highest available UID ..."
maxid=$(dscl . -list /Users UniqueID | awk '{print $2}' | sort -ug | tail -1)

        if [ -z ${maxid} ]; then
            newid=501
        else
            newid=$((maxid+1))
        fi

# Create local user account ...
ScriptLog "* Create ${loggedInUser} local account in client-side directory ..."
/usr/sbin/sysadminctl -addUser "${ec_user}" -fullName "${ec_user}" -UID "${newid}" -password "${ec_userPW}" -home "/Users/${ec_user}" "${adminStatus}"

# Reset ownership on home directory and append location
ScriptLog "* Correct permissions for ${loggedInUser} ..."
/usr/sbin/chown -R "${ec_user}":staff /Users/"${ec_user}"

#This would delete the user's keychain folder if uncommented
#ScriptLog "* Delete ${loggedInUser} keychain ..."
#/bin/rm -Rf /Users/"${ec_user}"/Library/Keychains/*

#Sleep for five seconds ..."
ScriptLog "* Sleep for five seconds ..."
/bin/sleep 5

# Force logout
ScriptLog "* Force logout ..."
/bin/ps -Ajc | /usr/bin/grep loginwindow | /usr/bin/awk '{print $2}' | /usr/bin/xargs /bin/kill -9

ScriptLog "---"
ScriptLog "- $loggedInUser account converted from personal to stu###"
ScriptLog "---"


exit 0

Generally, my plan was to separate the process from the initial onboarding, where I would eventually get an account with the proper credentials... but we decided it wasn't worth the continued development time. In your case, you should have secure token on a management account yes?

gabester
Contributor III

Thought I'd post some thoughts related to this here. 

Regardless of your scenario where you want to rename or replace an existing account's name, this seems to be a deliverable gap currently. Apple Support no doubt would just ask why https://support.apple.com/en-us/HT201548 isn't good enough? While dated, this script https://community.spiceworks.com/scripts/show/4409-mac-account-rename-script-username-home-directory... seemed promising but hits error -14120 (eDSPermissionError) on attempting to change the NFSHomeDirectory. 

I suspect the "rightApple way" to do this now is with sysadminctl -deleteUser -keepHome followed by sysadminctl -addUser -home but we all know that's fraught with Secure Token and user auth prompt troubles such that we've all shied away from actually just trying and getting it done.