summaryrefslogtreecommitdiff
path: root/eclass/acct-user.eclass
diff options
context:
space:
mode:
authorV3n3RiX <venerix@koprulu.sector>2022-10-19 19:58:53 +0100
committerV3n3RiX <venerix@koprulu.sector>2022-10-19 19:58:53 +0100
commitadab5aeec61fe929e5a817ec8034d98caab9ddbe (patch)
treeb1edc4f239d68ba31ab2e5ba8def5091023c2691 /eclass/acct-user.eclass
parent12652841746da7ae2f03b8b0c571a9bd5033e15c (diff)
gentoo auto-resync : 19:10:2022 - 19:58:53
Diffstat (limited to 'eclass/acct-user.eclass')
-rw-r--r--eclass/acct-user.eclass269
1 files changed, 119 insertions, 150 deletions
diff --git a/eclass/acct-user.eclass b/eclass/acct-user.eclass
index c87b27f3ccaa..b15599c5dd6f 100644
--- a/eclass/acct-user.eclass
+++ b/eclass/acct-user.eclass
@@ -4,6 +4,7 @@
# @ECLASS: acct-user.eclass
# @MAINTAINER:
# Michał Górny <mgorny@gentoo.org>
+# Mike Gilbert <floppym@gentoo.org>
# @AUTHOR:
# Michael Orlitzky <mjo@gentoo.org>
# Michał Górny <mgorny@gentoo.org>
@@ -48,7 +49,7 @@ case ${EAPI:-0} in
*) die "EAPI=${EAPI:-0} not supported";;
esac
-inherit user
+inherit user-info
[[ ${CATEGORY} == acct-user ]] ||
die "Ebuild error: this eclass can be used only in acct-user category!"
@@ -74,11 +75,6 @@ readonly ACCT_USER_NAME
# Overlays should set this to -1 to dynamically allocate UID. Using -1
# in ::gentoo is prohibited by policy.
-# @ECLASS_VARIABLE: _ACCT_USER_ALREADY_EXISTS
-# @INTERNAL
-# @DESCRIPTION:
-# Status variable which indicates if user already exists.
-
# @ECLASS_VARIABLE: ACCT_USER_ENFORCE_ID
# @DESCRIPTION:
# If set to a non-null value, the eclass will require the user to have
@@ -93,12 +89,19 @@ readonly ACCT_USER_NAME
# to an already existing user.
: ${ACCT_USER_NO_MODIFY:=}
+# @ECLASS_VARIABLE: ACCT_USER_COMMENT
+# @DEFAULT_UNSET
+# @DESCRIPTION:
+# The comment to use for the user. If not specified, the package
+# DESCRIPTION will be used. This can be overridden in make.conf through
+# ACCT_USER_<UPPERCASE_USERNAME>_COMMENT variable.
+
# @ECLASS_VARIABLE: ACCT_USER_SHELL
# @DESCRIPTION:
# The shell to use for the user. If not specified, a 'nologin' variant
# for the system is used. This can be overriden in make.conf through
# ACCT_USER_<UPPERCASE_USERNAME>_SHELL variable.
-: ${ACCT_USER_SHELL:=-1}
+: ${ACCT_USER_SHELL:=/sbin/nologin}
# @ECLASS_VARIABLE: ACCT_USER_HOME
# @DESCRIPTION:
@@ -208,112 +211,6 @@ eislocked() {
esac
}
-# @FUNCTION: elockuser
-# @USAGE: <user>
-# @INTERNAL
-# @DESCRIPTION:
-# Lock the specified user account, using the available platform-specific
-# functions. This should prevent any login to the account.
-#
-# Established lock can be reverted using eunlockuser.
-#
-# This function returns 0 if locking succeeded, 2 if it is not supported
-# by the platform code or dies if it fails.
-elockuser() {
- [[ $# -eq 1 ]] || die "usage: ${FUNCNAME} <user>"
-
- if [[ ${EUID} -ne 0 ]]; then
- einfo "Insufficient privileges to execute ${FUNCNAME[0]}"
- return 0
- fi
-
- eislocked "$1"
- [[ $? -eq 0 ]] && return 0
-
- local opts
- [[ -n ${ROOT} ]] && opts=( --prefix "${ROOT}" )
-
- case ${CHOST} in
- *-freebsd*|*-dragonfly*)
- pw lock "${opts[@]}" "$1" || die "Locking account $1 failed"
- pw user mod "${opts[@]}" "$1" -e 1 || die "Expiring account $1 failed"
- ;;
-
- *-netbsd*)
- if [[ -n "${ROOT}" ]]; then
- ewarn "NetBSD's usermod does not support --prefix <dir> option."
- ewarn "Please use: usermod ${opts[@]} -e 1 -C yes \"$1\" in a chroot"
- else
- usermod "${opts[@]}" -e 1 -C yes "$1" || die "Locking account $1 failed"
- fi
- ;;
-
- *-openbsd*)
- return 2
- ;;
-
- *)
- usermod "${opts[@]}" -e 1 -L "$1" || die "Locking account $1 failed"
- ;;
- esac
-
- elog "User account $1 locked"
- return 0
-}
-
-# @FUNCTION: eunlockuser
-# @USAGE: <user>
-# @INTERNAL
-# @DESCRIPTION:
-# Unlock the specified user account, using the available platform-
-# specific functions.
-#
-# This function returns 0 if unlocking succeeded, 1 if it is not
-# supported by the platform code or dies if it fails.
-eunlockuser() {
- [[ $# -eq 1 ]] || die "usage: ${FUNCNAME} <user>"
-
- if [[ ${EUID} -ne 0 ]]; then
- einfo "Insufficient privileges to execute ${FUNCNAME[0]}"
- return 0
- fi
-
- eislocked "$1"
- [[ $? -eq 1 ]] && return 0
-
- local opts
- [[ -n ${ROOT} ]] && opts=( --prefix "${ROOT}" )
-
- case ${CHOST} in
- *-freebsd*|*-dragonfly*)
- pw user mod "${opts[@]}" "$1" -e 0 || die "Unexpiring account $1 failed"
- pw unlock "${opts[@]}" "$1" || die "Unlocking account $1 failed"
- ;;
-
- *-netbsd*)
- if [[ -n "${ROOT}" ]]; then
- ewarn "NetBSD's usermod does not support --prefix <dir> option."
- ewarn "Please use: \"usermod ${opts[@]} -e 0 -C no $1\" in a chroot"
- else
- usermod "${opts[@]}" -e 0 -C no "$1" || die "Unlocking account $1 failed"
- fi
- ;;
-
- *-openbsd*)
- return 1
- ;;
-
- *)
- # silence warning if account does not have a password
- usermod "${opts[@]}" -e "" -U "$1" 2>/dev/null || die "Unlocking account $1 failed"
- ;;
- esac
-
- ewarn "User account $1 unlocked after reinstating."
- return 0
-}
-
-
# << Phase functions >>
EXPORT_FUNCTIONS pkg_pretend src_install pkg_preinst pkg_postinst \
pkg_prerm
@@ -373,6 +270,9 @@ acct-user_pkg_pretend() {
acct-user_src_install() {
debug-print-function ${FUNCNAME} "${@}"
+ # Replace reserved characters in comment
+ : ${ACCT_USER_COMMENT:=${DESCRIPTION//[:,=]/;}}
+
# serialize for override support
local ACCT_USER_GROUPS=${ACCT_USER_GROUPS[*]}
@@ -380,7 +280,7 @@ acct-user_src_install() {
local override_name=${ACCT_USER_NAME^^}
override_name=${override_name//-/_}
local var
- for var in ACCT_USER_{ID,SHELL,HOME{,_OWNER,_PERMS},GROUPS}; do
+ for var in ACCT_USER_{ID,COMMENT,SHELL,HOME{,_OWNER,_PERMS},GROUPS}; do
local var_name=ACCT_USER_${override_name}_${var#ACCT_USER_}
if [[ -n ${!var_name} ]]; then
ewarn "${var_name}=${!var_name} override in effect, support will not be provided."
@@ -395,6 +295,10 @@ acct-user_src_install() {
_ACCT_USER_GROUPS+=" ${!var_name}"
fi
+ if [[ -n ${_ACCT_USER_COMMENT//[^:,=]} ]]; then
+ die "Invalid characters in user comment: '${_ACCT_USER_COMMENT//[^:,=]}'"
+ fi
+
# deserialize into an array
local groups=( ${_ACCT_USER_GROUPS} )
@@ -409,7 +313,7 @@ acct-user_src_install() {
printf "u\t%q\t%q\t%q\t%q\t%q\n" \
"${ACCT_USER_NAME}" \
"${_ACCT_USER_ID/#-*/-}:${groups[0]}" \
- "${DESCRIPTION//[:,=]/;}" \
+ "${_ACCT_USER_COMMENT}" \
"${_ACCT_USER_HOME}" \
"${_ACCT_USER_SHELL/#-*/-}"
if [[ ${#groups[@]} -gt 1 ]]; then
@@ -426,27 +330,54 @@ acct-user_src_install() {
acct-user_pkg_preinst() {
debug-print-function ${FUNCNAME} "${@}"
- # check if user already exists
- _ACCT_USER_ALREADY_EXISTS=
- if [[ -n $(egetent passwd "${ACCT_USER_NAME}") ]]; then
- _ACCT_USER_ALREADY_EXISTS=1
+ unset _ACCT_USER_ADDED
+
+ if [[ ${EUID} -ne 0 ]]; then
+ einfo "Insufficient privileges to execute ${FUNCNAME[0]}"
+ return
+ fi
+
+ if egetent passwd "${ACCT_USER_NAME}" >/dev/null; then
+ elog "User ${ACCT_USER_NAME} already exists"
+ return
+ fi
+
+ local groups=( ${_ACCT_USER_GROUPS} )
+ local aux_groups=${groups[*]:1}
+ local opts=(
+ --system
+ --no-create-home
+ --no-user-group
+ --comment "${_ACCT_USER_COMMENT}"
+ --home-dir "${_ACCT_USER_HOME}"
+ --shell "${_ACCT_USER_SHELL}"
+ --gid "${groups[0]}"
+ --groups "${aux_groups// /,}"
+ )
+
+ if [[ ${_ACCT_USER_ID} -ne -1 ]] &&
+ ! egetent passwd "${_ACCT_USER_ID}" >/dev/null
+ then
+ opts+=( --uid "${_ACCT_USER_ID}" )
+ fi
+
+ if [[ -n ${ROOT} ]]; then
+ opts+=( --prefix "${ROOT}" )
fi
- readonly _ACCT_USER_ALREADY_EXISTS
- enewuser ${ACCT_USER_ENFORCE_ID:+-F} -M "${ACCT_USER_NAME}" \
- "${_ACCT_USER_ID}" "${_ACCT_USER_SHELL}" "${_ACCT_USER_HOME}" \
- "${_ACCT_USER_GROUPS// /,}"
+ elog "Adding user ${ACCT_USER_NAME}"
+ useradd "${opts[@]}" "${ACCT_USER_NAME}" || die
+ _ACCT_USER_ADDED=1
if [[ ${_ACCT_USER_HOME} != /dev/null ]]; then
# default ownership to user:group
if [[ -z ${_ACCT_USER_HOME_OWNER} ]]; then
- local group_array=( ${_ACCT_USER_GROUPS} )
- if [[ -n "${ROOT}" ]]; then
+ if [[ -n ${ROOT} ]]; then
local euid=$(egetent passwd ${ACCT_USER_NAME} | cut -d: -f3)
local egid=$(egetent passwd ${ACCT_USER_NAME} | cut -d: -f4)
_ACCT_USER_HOME_OWNER=${euid}:${egid}
else
- _ACCT_USER_HOME_OWNER=${ACCT_USER_NAME}:${group_array[0]}
+ _ACCT_USER_HOME_OWNER=${ACCT_USER_NAME}:${groups[0]}
fi
fi
# Path might be missing due to INSTALL_MASK, etc.
@@ -469,26 +400,48 @@ acct-user_pkg_preinst() {
acct-user_pkg_postinst() {
debug-print-function ${FUNCNAME} "${@}"
+ if [[ -n ${_ACCT_USER_ADDED} ]]; then
+ # We just added the user; no need to update it
+ return
+ fi
+
if [[ ${EUID} -ne 0 ]]; then
einfo "Insufficient privileges to execute ${FUNCNAME[0]}"
- return 0
+ return
fi
- if [[ -n ${ACCT_USER_NO_MODIFY} && -n ${_ACCT_USER_ALREADY_EXISTS} ]]; then
- eunlockuser "${ACCT_USER_NAME}"
-
+ if [[ -n ${ACCT_USER_NO_MODIFY} ]]; then
ewarn "User ${ACCT_USER_NAME} already exists; Not touching existing user"
ewarn "due to set ACCT_USER_NO_MODIFY."
- return 0
+ return
fi
- # NB: eset* functions check current value
- esethome "${ACCT_USER_NAME}" "${_ACCT_USER_HOME}"
- esetshell "${ACCT_USER_NAME}" "${_ACCT_USER_SHELL}"
- esetgroups "${ACCT_USER_NAME}" "${_ACCT_USER_GROUPS// /,}"
- # comment field can not contain colons
- esetcomment "${ACCT_USER_NAME}" "${DESCRIPTION//[:,=]/;}"
- eunlockuser "${ACCT_USER_NAME}"
+ local groups=( ${_ACCT_USER_GROUPS} )
+ local aux_groups=${groups[*]:1}
+ local opts=(
+ --comment "${_ACCT_USER_COMMENT}"
+ --home "${_ACCT_USER_HOME}"
+ --shell "${_ACCT_USER_SHELL}"
+ --gid "${groups[0]}"
+ --groups "${aux_groups// /,}"
+ )
+
+ if eislocked "${ACCT_USER_NAME}"; then
+ opts+=( --expiredate "" --unlock )
+ fi
+
+ if [[ -n ${ROOT} ]]; then
+ opts+=( --prefix "${ROOT}" )
+ fi
+
+ elog "Updating user ${ACCT_USER_NAME}"
+ if ! usermod "${opts[@]}" "${ACCT_USER_NAME}" 2>"${T}/usermod-error.log"; then
+ # usermod outputs a warning if unlocking the account would result in an
+ # empty password. Hide stderr in a text file and display it if usermod
+ # fails.
+ cat "${T}/usermod-error.log" >&2
+ die "usermod failed"
+ fi
}
# @FUNCTION: acct-user_pkg_prerm
@@ -497,28 +450,44 @@ acct-user_pkg_postinst() {
acct-user_pkg_prerm() {
debug-print-function ${FUNCNAME} "${@}"
+ if [[ -n ${REPLACED_BY_VERSION} ]]; then
+ return
+ fi
+
if [[ ${EUID} -ne 0 ]]; then
einfo "Insufficient privileges to execute ${FUNCNAME[0]}"
- return 0
+ return
fi
if [[ ${ACCT_USER_ID} -eq 0 ]]; then
elog "Refusing to lock out the superuser (UID 0)"
- return 0
+ return
fi
- if [[ -z ${REPLACED_BY_VERSION} ]]; then
- if [[ -z $(egetent passwd "${ACCT_USER_NAME}") ]]; then
- ewarn "User account not found: ${ACCT_USER_NAME}"
- ewarn "Locking process will be skipped."
- return
- fi
+ if [[ -n ${ACCT_USER_NO_MODIFY} ]]; then
+ elog "Not locking user ${ACCT_USER_NAME} due to ACCT_USER_NO_MODIFY"
+ return
+ fi
+
+ if ! egetent passwd "${ACCT_USER_NAME}" >/dev/null; then
+ ewarn "User account not found: ${ACCT_USER_NAME}"
+ ewarn "Locking process will be skipped."
+ return
+ fi
- esetshell "${ACCT_USER_NAME}" -1
- esetcomment "${ACCT_USER_NAME}" \
- "$(egetcomment "${ACCT_USER_NAME}"); user account removed @ $(date +%Y-%m-%d)"
- elockuser "${ACCT_USER_NAME}"
+ local opts=(
+ --expiredate 1
+ --lock
+ --comment "$(egetcomment "${ACCT_USER_NAME}"); user account removed @ $(date +%Y-%m-%d)"
+ --shell /sbin/nologin
+ )
+
+ if [[ -n ${ROOT} ]]; then
+ opts+=( --prefix "${ROOT}" )
fi
+
+ elog "Locking user ${ACCT_USER_NAME}"
+ usermod "${opts[@]}" "${ACCT_USER_NAME}" || die
}
fi