#!/bin/sh
#
# (Un)registers systems accounts (users/groups).
#
# Arguments:	$ACTION = [run/targets]
#		$TARGET = [post-install/pre-remove]
#		$PKGNAME
#		$VERSION
#		$UPDATE = [yes/no]
#
ACTION="$1"
TARGET="$2"
PKGNAME="$3"
VERSION="$4"
UPDATE="$5"

export PATH="usr/sbin:usr/bin:/usr/sbin:/usr/bin:/sbin:/bin"

# Determine whether useradd/groupadd/usermod need a prefix argument
if [ "$(readlink -f . 2>/dev/null || echo .)" != "/" ]; then
	prefix="-P ."
else
	prefix=
fi

# show_acct_details <username> <description> <homedir> <shell> [groups]
show_acct_details() {
	echo "   Account: $1"
	echo "   Description: '$2'"
	echo "   Homedir: '$3'"
	echo "   Shell: '$4'"
	[ -n "$5" ] && echo "   Additional groups: '$5'"
}

group_add() {
	local _pretty_grname _grname _gid _prefix

	if ! command -v groupadd >/dev/null 2>&1; then
		echo "WARNING: cannot create $1 system group (missing groupadd)"
		echo "The following group must be created manually: $1"
		return
	fi

	_grname="${1%:*}"
	_gid="${1##*:}"

	[ "${_grname}" = "${_gid}" ] && _gid=

	_pretty_grname="${_grname}${_gid:+ (gid: ${_gid})}"

	groupadd ${prefix} -r ${_grname} ${_gid:+-g ${_gid}} >/dev/null 2>&1

	case $? in
		0) echo "Created ${_pretty_grname} system group." ;;
		9) ;;
		*) echo "ERROR: failed to create system group ${_pretty_grname}!"; exit 1;;
	esac
}

case "$ACTION" in
targets)
	echo "post-install pre-remove"
	;;
run)
	[ -z "$system_accounts" -a -z "$system_groups" ] && exit 0

	if command -v useradd >/dev/null 2>&1; then
		USERADD="useradd ${prefix}"
	fi

	if command -v usermod >/dev/null 2>&1; then
		USERMOD="usermod ${prefix}"
	fi

	case "$TARGET" in
	post-install)
		# System groups required by a package.
		for grp in ${system_groups}; do
			group_add $grp
		done

		# System user/group required by a package.
		for acct in ${system_accounts}; do
			_uname="${acct%:*}"
			_uid="${acct##*:}"

			[ "${_uname}" = "${_uid}" ] && _uid=

			eval homedir="\$${_uname}_homedir"
			eval shell="\$${_uname}_shell"
			eval descr="\$${_uname}_descr"
			eval groups="\$${_uname}_groups"
			eval pgroup="\$${_uname}_pgroup"

			[ -z "$homedir" ] && homedir="/var/empty"
			[ -z "$shell" ] && shell="/sbin/nologin"
			[ -z "$descr" ] && descr="${_uname} unprivileged user"
			[ -n "$groups" ] && user_groups="-G $groups"

			if [ -n "${_uid}" ]; then
				use_id="-u ${_uid} -g ${pgroup:-${_uid}}"
				_pretty_uname="${_uname} (uid: ${_uid})"
			else
				use_id="-g ${pgroup:-${_uname}}"
				_pretty_uname="${_uname}"
			fi

			if [ -z "$USERADD" -o -z "$USERMOD" ]; then
				echo "WARNING: cannot create ${_uname} system account (missing useradd or usermod)"
				echo "The following system account must be created:"
				show_acct_details "${_pretty_uname}" "${descr}" "${homedir}" "${shell}" "${groups}"
				continue
			fi

			group_add ${pgroup:-${acct}}

			${USERADD} -c "${descr}" -d "${homedir}" \
				${use_id} ${pgroup:+-N} -s "${shell}" \
				${user_groups} -r ${_uname} >/dev/null 2>&1

			case $? in
				0)
					echo "Created ${_pretty_uname} system user."
					${USERMOD} -L ${_uname} >/dev/null 2>&1
					if [ $? -ne 0 ]; then
						echo "WARNING: unable to lock password for ${_uname} system account"
					fi
					;;
				9)
					${USERMOD} -c "${descr}" -d "${homedir}" \
						-s "${shell}" -g "${pgroup:-${_uname}}" \
						${user_groups} ${_uname} >/dev/null 2>&1
					if [ $? -eq 0 ]; then
						echo "Updated ${_uname} system user."
					else
						echo "WARNING: unable to modify ${_uname} system account"
						echo "Please verify that account is compatible with these settings:"
						show_acct_details "${_pretty_uname}" \
							"${descr}" "${homedir}" "${shell}" "${groups}"
						continue
					fi
					;;
				*)
					echo "ERROR: failed to create system user ${_pretty_uname}!"
					exit 1
					;;
			esac
		done
		;;
	pre-remove)
		if [ "$UPDATE" = "no" ]; then
			for acct in ${system_accounts}; do
				_uname="${acct%:*}"

				comment="$( (getent passwd "${_uname}" | cut -d: -f5 | head -n1) 2>/dev/null )"
				comment="${comment:-unprivileged user} - for uninstalled package ${PKGNAME}"

				if [ -z "$USERMOD" ]; then
					echo "WARNING: cannot disable ${_uname} system user (missing usermod)"
					continue
				fi

				${USERMOD} -L -d /var/empty -s /bin/false \
					-c "${comment}" ${_uname} >/dev/null 2>&1
				if [ $? -eq 0 ]; then
					echo "Disabled ${_uname} system user."
				fi
			done
		fi
		;;
	esac
	;;
*)
	exit 1
	;;
esac

exit 0
# end
