Skip to content

Instantly share code, notes, and snippets.

@smbambling
Created February 11, 2016 12:48
Show Gist options
  • Save smbambling/6d0ae281b1818831590c to your computer and use it in GitHub Desktop.
Save smbambling/6d0ae281b1818831590c to your computer and use it in GitHub Desktop.
Change User/Primary Group UID and GID
#!/usr/bin/env bash
usage() {
cat <<-EOF
usage: ${0} -l <login> -u <new uid> [-g <new gid>]
-h this help screen
-l login account login account name
-p primary group for account login
-u uid new UID to assign to account
-g new GID to assign to account group
returns status code of 0 for success, otherwise, failure
EOF
exit -2
}
# Reference Commands
cmd_list='usermod groupmod find chgrp getent id awk tr wc'
# Function to check if referenced command exists
cmd_exists() {
if [ $# -eq 0 ]; then
echo 'WARNING: No command argument was passed to verify exists'
fi
cmd=${1}
hash "${cmd}" >&/dev/null # portable 'which'
rc=$?
if [ "${rc}" != "0" ]; then
echo "${cmd} command not found"
exit 1
#else
# echo "Found: ${cmd} at ${cmd_fullpath}"
fi
}
# Verify that referenced commands exist on the system
for cmd in ${cmd_list}; do
cmd_exists "$cmd"/
done
#Parse command line flags
#If an option should be followed by an argument, it should be followed by a ":".
#Notice there is no ":" after "h". The leading ":" suppresses error messages from
#getopts.
while getopts ":l:u:g:p:h" opt; do
case $opt in
g)
newgid="$OPTARG"
;;
h)
usage
;;
l)
login="$OPTARG"
;;
p)
prigroup="$OPTARG"
;;
u)
newuid="$OPTARG"
;;
\?)
echo "Invalid option: -$OPTARG" >&2
usage
;;
esac
done
if [ -z "${login}" ]; then
echo -e "Error: You must specify a login\n"
usage
elif [ -z "${prigroup}" ]; then
#verify that login and primary
echo -e "Info: Setting the primaray group to ${login}\n"
prigroup="${login}"
membercount=$(getent group "${prigroup}" | awk -F: '{ print $4 }' | tr -cd , | wc -c)
if [ "${membercount}" != "0" ]; then
echo -e "Warning: The primary group for account ${login} contains other accounts\n"
echo -e "Would you like to continue to update the GID for ${prigroup} ? [Y/n] " input
if [[ ! $input =~ ^[Yy]$ ]]; then
echo -e "\nWarning: Aborting on user prompt"
exit 2
fi
fi
fi
if [ -z "${newuid}" ]; then
echo -e "Error: You must specify a new UID\n"
usage
elif [ -z "${newgid}" ]; then
echo -e "Warning: Setting the new GID to ${newuid}\n"
read -r -n 1 -p " Would you like to continue with these settings ? [Y/n] " input
if [[ ! $input =~ ^[Yy]$ ]]; then
echo -e "\nWarning: Aborting on user prompt"
exit 2
fi
newgid="${newuid}"
fi
# Capture old UID and GID
olduid=$(getent passwd "${login}" | awk -F: '{ print $3 }')
oldgid=$(getent group "${login}" | awk -F: '{ print $3 }')
if [ -z "${olduid}" ]; then
echo -e "Error: Couldn't determine current UID for ${login}\n"
exit 1
elif [ -z "${oldgid}" ]; then
echo -e "Error: Couldn't determine current GID for ${login}\n"
exit 1
fi
check_uid() {
check_uid=$1
local status
status=$(getent passwd "${check_uid}" | awk -F: '{ print $1 }')
rc=$?
if [ "${rc}" -ne "0" ]; then
echo "Error: ${check_uid} is already assigned to login [ ${status} ]"
exit 1
fi
}
check_gid() {
check_gid=$1
local status
status=$(getent group "${check_gid}" | awk -F: '{ print $1 }')
rc=$?
if [ "${rc}" -ne "0" ]; then
echo "Error: ${check_gid} is already assigned to group [ ${status} ]"
exit 1
fi
}
check_uid "${newuid}"
check_gid "${newgid}"
echo -e "\n Updating User UID and Primary Group GID\n"
sudo usermod -u "${newuid}" "${login}"
sudo groupmod -g "${newgid}" "${prigroup}"
sudo find / -path /sys -prune -o -path /proc -prune -o \
-user "${olduid}" -exec chown -h "${newuid}" {} \;
sudo find / -path /sys -prune -o -path /proc -prune -o \
-group "${oldgid}" -exec chgrp -h "${newgid}" {} \;
sudo usermod -g "${newgid}" "${login}"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment