From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from lists.gentoo.org (pigeon.gentoo.org [208.92.234.80]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by finch.gentoo.org (Postfix) with ESMTPS id 8F0C1138334 for ; Tue, 11 Jun 2019 16:29:30 +0000 (UTC) Received: from pigeon.gentoo.org (localhost [127.0.0.1]) by pigeon.gentoo.org (Postfix) with SMTP id 7D9C8E09EC; Tue, 11 Jun 2019 16:24:15 +0000 (UTC) Received: from smtp.gentoo.org (smtp.gentoo.org [140.211.166.183]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by pigeon.gentoo.org (Postfix) with ESMTPS id 1B29CE09E8 for ; Tue, 11 Jun 2019 16:24:15 +0000 (UTC) Received: from localhost.localdomain (d202-252.icpnet.pl [109.173.202.252]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) (Authenticated sender: mgorny) by smtp.gentoo.org (Postfix) with ESMTPSA id 865BE345E94; Tue, 11 Jun 2019 16:24:13 +0000 (UTC) From: =?UTF-8?q?Micha=C5=82=20G=C3=B3rny?= To: gentoo-dev@lists.gentoo.org Cc: =?UTF-8?q?Micha=C5=82=20G=C3=B3rny?= Subject: [gentoo-dev] [PATCH v4 16/19] acct-user.eclass: Supporting locking & unlocking accounts Date: Tue, 11 Jun 2019 18:23:44 +0200 Message-Id: <20190611162347.2989-17-mgorny@gentoo.org> X-Mailer: git-send-email 2.22.0 In-Reply-To: <20190611162347.2989-1-mgorny@gentoo.org> References: <20190611162347.2989-1-mgorny@gentoo.org> Precedence: bulk List-Post: List-Help: List-Unsubscribe: List-Subscribe: List-Id: Gentoo Linux mail X-BeenThere: gentoo-dev@lists.gentoo.org Reply-to: gentoo-dev@lists.gentoo.org X-Auto-Response-Suppress: DR, RN, NRN, OOF, AutoReply MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-Archives-Salt: c3b1cbed-3814-41fa-b9b7-e4287ba6d22e X-Archives-Hash: ac45ba527760c1e03a3ed662832c01d5 Signed-off-by: Michał Górny --- eclass/acct-user.eclass | 127 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 127 insertions(+) diff --git a/eclass/acct-user.eclass b/eclass/acct-user.eclass index 4a37bf3e1d95..1b8a0bf94a62 100644 --- a/eclass/acct-user.eclass +++ b/eclass/acct-user.eclass @@ -136,6 +136,131 @@ acct-user_add_deps() { } +# << Helper functions >> + +# @FUNCTION: eislocked +# @INTERNAL +# @USAGE: +# @DESCRIPTION: +# Check whether the specified user account is currently locked. +# Returns 0 if it is locked, 1 if it is not, 2 if the platform +# does not support determining it. +eislocked() { + [[ $# -eq 1 ]] || die "usage: ${FUNCNAME} " + + if [[ ${EUID} != 0 ]] ; then + einfo "Insufficient privileges to execute ${FUNCNAME[0]}" + return 0 + fi + + case ${CHOST} in + *-freebsd*|*-dragonfly*|*-netbsd*) + [[ $(egetent "$1" | cut -d: -f2) == '*LOCKED*'* ]] + ;; + + *-openbsd*) + return 2 + ;; + + *) + # NB: 'no password' and 'locked' are indistinguishable + # but we also expire the account which is more clear + [[ $(getent shadow ftp | cut -d: -f2) == '!'* ]] && + [[ $(getent shadow ftp | cut -d: -f8) == 1 ]] + ;; + esac +} + +# @FUNCTION: elockuser +# @INTERNAL +# @USAGE: +# @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} " + + if [[ ${EUID} != 0 ]] ; then + einfo "Insufficient privileges to execute ${FUNCNAME[0]}" + return 0 + fi + + eislocked "$1" + [[ $? -eq 0 ]] && return 0 + + case ${CHOST} in + *-freebsd*|*-dragonfly*) + pw lock "$1" || die "Locking account $1 failed" + pw user mod "$1" -e 1 || die "Expiring account $1 failed" + ;; + + *-netbsd*) + usermod -e 1 -C yes "$1" || die "Locking account $1 failed" + ;; + + *-openbsd*) + return 2 + ;; + + *) + usermod -e 1 -L "$1" || die "Locking account $1 failed" + ;; + esac + + elog "User account $1 locked" + return 0 +} + +# @FUNCTION: eunlockuser +# @INTERNAL +# @USAGE: +# @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} " + + if [[ ${EUID} != 0 ]] ; then + einfo "Insufficient privileges to execute ${FUNCNAME[0]}" + return 0 + fi + + eislocked "$1" + [[ $? -eq 1 ]] && return 0 + + case ${CHOST} in + *-freebsd*|*-dragonfly*) + pw user mod "$1" -e 0 || die "Unexpiring account $1 failed" + pw unlock "$1" || die "Unlocking account $1 failed" + ;; + + *-netbsd*) + usermod -e 0 -C no "$1" || die "Unlocking account $1 failed" + ;; + + *-openbsd*) + return 1 + ;; + + *) + # silence warning if account does not have a password + usermod -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 @@ -228,6 +353,7 @@ acct-user_pkg_postinst() { esetgroups "${ACCT_USER_NAME}" "${groups// /,}" # comment field can not contain colons esetcomment "${ACCT_USER_NAME}" "${DESCRIPTION//[:,=]/;}" + eunlockuser "${ACCT_USER_NAME}" } # @FUNCTION: acct-user_pkg_prerm @@ -240,6 +366,7 @@ acct-user_pkg_prerm() { esetshell "${ACCT_USER_NAME}" -1 esetcomment "${ACCT_USER_NAME}" \ "$(egetcomment "${ACCT_USER_NAME}"); user account removed @ $(date +%Y-%m-%d)" + elockuser "${ACCT_USER_NAME}" fi } -- 2.22.0