Skip to content

Instantly share code, notes, and snippets.

@ixs
Created May 19, 2020 13:11
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ixs/137899c50f5f1012882fabb90361d003 to your computer and use it in GitHub Desktop.
Save ixs/137899c50f5f1012882fabb90361d003 to your computer and use it in GitHub Desktop.
#!/bin/sh
set -euo pipefail
MAX_SYS_UID=499
MAX_SYS_GID=499
ORIG_MAX_SYS_UID=999
ORIG_MAX_SYS_GID=999
# For debugging, set to echo
CMD_PREFIX=""
if [ "${1:-}" = "--debug" ]; then
CMD_PREFIX="echo"
fi
# Sanity checks
if grep -q '^UID_MIN[ ]+'"$((MAX_SYS_UID + 1))"'$' /etc/login.defs && \
grep -q '^SYS_UID_MAX[ ]+'"$MAX_SYS_UID"'$' /etc/login.defs && \
grep -q '^GID_MIN[ ]+'"$((MAX_SYS_GID + 1))"'$' /etc/logins.defs && \
grep -q '^SYS_GID_MAX[ ]+'"$MAX_SYS_GID"'$' /etc/login.defs; then
echo "UIDs already correct, nothing to do."
exit 0
fi
# Rewrite login defs
$CMD_PREFIX sed -i -e 's/^\(UID_MIN[ ]*\)[0-9]*/\1'"$(printf %04s $((MAX_SYS_UID + 1)))"'/' /etc/login.defs
$CMD_PREFIX sed -i -e 's/^\(SYS_UID_MAX[ ]*\)[0-9]*/\1'"$(printf %03s $MAX_SYS_UID)"'/' /etc/login.defs
$CMD_PREFIX sed -i -e 's/^\(GID_MIN[ ]*\)[0-9]*/\1'"$(printf %04s $((MAX_SYS_GID + 1)))"'/' /etc/login.defs
$CMD_PREFIX sed -i -e 's/^\(SYS_GID_MAX[ ]*\)[0-9]*/\1'"$(printf %03s $MAX_SYS_GID)"'/' /etc/login.defs
_USERS=$(awk -F : '{ if (($3 > '$MAX_SYS_UID') || ($4 > '$MAX_SYS_GID')) print $1; }' < /etc/passwd)
for USER in $_USERS; do
U_UID=$(awk -F : '{ if ($1 == "'"$USER"'") print $3; }' < /etc/passwd)
U_GID=$(awk -F : '{ if ($1 == "'"$USER"'") print $4; }' < /etc/passwd)
U_GROUP=$(awk -F : '{ if ($3 == "'"$U_GID"'") print $1; }' < /etc/group)
if [ -z "$U_UID" ] || [ -z "$U_GID" ] || [ -z "$U_GROUP" ]; then
echo Expected Variable empty, exiting.
exit 1
fi
U_UID_OFFSET=$((ORIG_MAX_SYS_UID - U_UID))
NEW_UID=$((MAX_SYS_UID - U_UID_OFFSET))
U_GID_OFFSET=$((ORIG_MAX_SYS_GID - U_GID))
NEW_GID=$((MAX_SYS_GID - U_GID_OFFSET))
echo "Searching for processes owned by $USER/$U_UID"
UNITS=""
for PID in $(ps -axo uid,pid | awk "/^[ ]*$U_UID / {print \$2}"); do
# Retrieve systemd unit for PID
UNITS="$UNITS $(systemctl status "$PID" | sed -n '1p' | cut -d ' ' -f 2)"
done
for UNIT in $UNITS; do
$CMD_PREFIX systemctl stop "$UNIT"
done
echo "Moving group $U_GROUP from $U_GID to $NEW_GID"
$CMD_PREFIX groupmod -g "$NEW_GID" "$U_GROUP"
echo "Moving user $USER from $U_UID to $NEW_UID"
$CMD_PREFIX usermod -u "$NEW_UID" "$USER"
echo "Searching for files owned by $USER/$U_UID"
find / -path /proc -prune -o -uid "$U_UID" -exec $CMD_PREFIX chown "$NEW_UID" '{}' \; 2> /dev/null
echo "Searching for files group owned by $USER/$U_GID"
find / -path /proc -prune -o -gid "$U_GID" -exec $CMD_PREFIX chgrp "$NEW_GID" '{}' \; 2> /dev/null
for UNIT in $UNITS; do
$CMD_PREFIX systemctl start "$UNIT"
done
done
_GROUPS=$(awk -F : '{ if ($3 > '$MAX_SYS_GID') print $1; }' < /etc/group)
for GROUP in $_GROUPS; do
G_GID=$(awk -F : '{ if ($1 == "'"$GROUP"'") print $3; }' < /etc/group)
if [ -z "$G_GID" ]; then
echo "Expected Variable empty, exiting."
exit 1
fi
G_GID_OFFSET=$((ORIG_MAX_SYS_GID - G_GID))
NEW_GID=$((MAX_SYS_GID - G_GID_OFFSET))
echo "Moving group $GROUP from $G_GID to $NEW_GID"
$CMD_PREFIX groupmod -g "$NEW_GID" "$GROUP"
echo "Searching for files group owned by $GROUP/$G_GID"
find / -path /proc -prune -o -gid "$G_GID" -exec $CMD_PREFIX chgrp "$NEW_GID" '{}' \; 2> /dev/null
done
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment