commit:     f1885c714d2082bc29f7269b9342870e084b00ff
Author:     Mike Gilbert <floppym <AT> gentoo <DOT> org>
AuthorDate: Mon Oct 17 20:18:37 2022 +0000
Commit:     Mike Gilbert <floppym <AT> gentoo <DOT> org>
CommitDate: Wed Oct 19 16:47:30 2022 +0000
URL:        https://gitweb.gentoo.org/repo/gentoo.git/commit/?id=f1885c71

acct-user.eclass: inline useradd and usermod

Signed-off-by: Mike Gilbert <floppym <AT> gentoo.org>

 eclass/acct-user.eclass | 121 ++++++++++++++++++++++++++++++++++--------------
 1 file changed, 87 insertions(+), 34 deletions(-)

diff --git a/eclass/acct-user.eclass b/eclass/acct-user.eclass
index 91a262e2a7a8..32a0a340a07b 100644
--- a/eclass/acct-user.eclass
+++ b/eclass/acct-user.eclass
@@ -48,7 +48,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 +74,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
@@ -105,7 +100,7 @@ readonly ACCT_USER_NAME
 # 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:
@@ -440,27 +435,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
-       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// /,}"
+       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
+
+       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.
@@ -483,26 +505,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}" "${_ACCT_USER_COMMENT}"
-       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
@@ -536,10 +580,19 @@ acct-user_pkg_prerm() {
                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

Reply via email to