Change UID/GID Script?

mbezzo
Contributor III

Hi All,
I've gotten a few requests recently where I need to change a UID to match the AD account, does anybody have any scripts already written (and are willing to share!) to do the permissions cleanup after the change? Did a quick search but didn't find much. :)

Thanks!

6 REPLIES 6

davidacland
Honored Contributor II

Nothing specific to hand, but the basic code for permissions fixing would be:

#!/bin/sh

chown -R adusername /Users/adusername

exit 0

Do you mean you want to set a local user account to have the same UID as a corresponding AD account, or to switch to an AD account completely from local user accounts?

mbezzo
Contributor III

Hi David,
Yeah, so we bind and use AD accounts, but we don't sync UIDs, so for a few users working with Linux this causes problem. Hoping to get a nice simple process setup for this going forward. I found this command - does this basically cover it? (This is after changing the UID of course). Our users are admins (yay!) so have to cover anything they may have created outside of their home dir. too.

#!/bin/sh

find -xP / -user oldUID -print0 |xargs -0 chown -h newUID

hkabik
Valued Contributor

I've used the following:

dscl . -change /Users/username UniqueID oldUID newUID

Didn't really leave anything needing to be cleaned up afterwards. Not sure if that is at all helpful, but worked for me.

davidacland
Honored Contributor II

@mbezzo

The first part looks ok. I don't recognise -h on the chown command, it doesn't seem to be in the man page. Normally if you use chown username that will correct any ownership issues.

mbezzo
Contributor III

Thanks all! I believe the -h flag enables chown to set the owner on symbolic links correctly. Without it, the original linked file isn't changed.

mbezzo
Contributor III

Okay, so in case this is helpful to others, here's what I've come up with. As always, TEST extensively for your environment! :) Make sure you update the Active Directory path to match your domain (in hindsight I suppose this should have been a variable... oh well!)

Thanks,
Matt

#!/bin/sh
#####################################################################################################
#
# NAME
#   changeUID.sh
#
# SYNOPSIS
#   Prompts for a user name, grabs the uidNumber from AD using dscl, sets the new UID and finally 
#   updates all permissions with the old UID to the new one.    
#
####################################################################################################
#
# HISTORY
#
#   Version: 1.0
#
#   - Matt Bezzo, 27.04.2016
#
####################################################################################################

########################################
############## Variables ###############
########################################

# Get the currently logged in user
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 + "
");'`


#Set the variables to blank
activedirectoryUID=""
localUID=""


########################################
############## Functions ###############
########################################

log(){
NOW="$(date +"%Y-%m-%d %H:%M:%S")"
echo "$NOW": "$1"
}

usernamePrompt(){
    # $1 = window title
    # $2 = prompt text
    # $3 = default answer
    su - "${loggedInUser}" -c osascript <<EOT
        tell application "System Events"
            with timeout of 8947848 seconds
                text returned of (display dialog "$2" default answer "$3" buttons {"OK"} default button 1 with title "$1" with icon caution)
            end timeout
        end tell
EOT
}


########################################
########## Begin Main Program ##########
########################################

# Logging for troubleshooting - view the log at /var/log/changeUID.log
touch /var/log/changeUID.log
exec 2>&1>/var/log/changeUID.log

# Prompt for username
log "Prompting for username"
username="$(usernamePrompt 'Enter Username' 'Please enter the username you would like to modfy.

Make sure the username is correct - this process will fail if it is not!' 'enter username')"
log "username entered: $username"

# Verify that the entered user actually exists on this computer
log "Verifying $username exists on this computer"
if [[ ! -d /Users/$username ]]; then
    log "Entered user does not exist.  User must exist on this computer for UID change."
    exit 1
fi
log "$username exists"

# Set the AD uidNumber for user
activedirectoryUID=$(dscl /Active Directory/YOURDOMAIN/All Domains -read /Users/$username | grep uidNumber | cut -c 29-)
log "AD UID is $activedirectoryUID"

# Set the local UID for user
localUID=$(dscl . -read /Users/$username | grep UniqueID | cut -c 11-)
log "local UID is $localUID"

# Check to make sure we actually have values for activedirectoryUID and localUID
if [[ $activedirectoryUID != "" ]] && [[ $localUID != "" ]]; then
        log "Stored UID values exist, changing UID for $username"
        dscl . -change /Users/$username UniqueID $localUID $activedirectoryUID
        log "Starting to change owner permissions for /"
        find -xP / -user $localUID -print0 |xargs -0 chown -h $activedirectoryUID
        log "Permissions changes complete"

elif [[ $activedirectoryUID == "" ]] || [[ $localUID == "" ]]; then
        log "UID's not valid - please verify username and/or Active Directory bind and try again."
fi

exit 0