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 D353A138334 for ; Sun, 9 Jun 2019 11:33:08 +0000 (UTC) Received: from pigeon.gentoo.org (localhost [127.0.0.1]) by pigeon.gentoo.org (Postfix) with SMTP id DBED1E0992; Sun, 9 Jun 2019 11:28:42 +0000 (UTC) Received: from smtp.gentoo.org (woodpecker.gentoo.org [IPv6:2001:470:ea4a:1:5054:ff:fec7:86e4]) (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 27D15E098E for ; Sun, 9 Jun 2019 11:28:41 +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 4748E345ACF; Sun, 9 Jun 2019 11:28:39 +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 v3 13/19] user.eclass: Introduce e{get,set}groups Date: Sun, 9 Jun 2019 13:28:08 +0200 Message-Id: <20190609112814.15907-14-mgorny@gentoo.org> X-Mailer: git-send-email 2.22.0.rc3 In-Reply-To: <20190609112814.15907-1-mgorny@gentoo.org> References: <20190609112814.15907-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-Transfer-Encoding: 8bit X-Archives-Salt: df54befb-417f-4df8-9c76-e673c5f72e5b X-Archives-Hash: a6f2cc71da320b5567fdd87371aa6e72 --- eclass/user.eclass | 88 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 88 insertions(+) diff --git a/eclass/user.eclass b/eclass/user.eclass index f4f6c75f3b71..23c3b953842f 100644 --- a/eclass/user.eclass +++ b/eclass/user.eclass @@ -438,6 +438,24 @@ egetcomment() { egetent passwd "$1" | cut -d: -f${pos} } +# @FUNCTION: egetgroups +# @USAGE: +# @DESCRIPTION: +# Gets all the groups user belongs to. The primary group is returned +# first, then all supplementary groups. Groups are ','-separated. +egetgroups() { + [[ $# -eq 1 ]] || die "usage: egetgroups " + + local egroups_arr + read -r -a egroups_arr < <(id -G -n "$1") + + local defgroup=${egroups_arr[0]} + # sort supplementary groups to make comparison possible + readarray -t exgroups_arr < <(printf '%s\n' "${egroups_arr[@]:1}" | sort) + local exgroups=${exgroups_arr[*]} + echo "${defgroup}${exgroups:+,${exgroups// /,}}" +} + # @FUNCTION: esethome # @USAGE: # @DESCRIPTION: @@ -627,4 +645,74 @@ esetcomment() { esac } +# @FUNCTION: esetgroups +# @USAGE: +# @DESCRIPTION: +# Update the group field in a platform-agnostic way. +# Required parameters is the username and the new list of groups, +# primary group first. +esetgroups() { + _assert_pkg_ebuild_phase ${FUNCNAME} + + [[ ${#} -eq 2 ]] || die "Usage: ${FUNCNAME} " + + # get the username + local euser=$1; shift + + # lets see if the username already exists + if [[ -z $(egetent passwd "${euser}") ]] ; then + ewarn "User does not exist, cannot set group -- skipping." + return 1 + fi + + # handle group + local egroups=$1; shift + + local g egroups_arr=() + IFS="," read -r -a egroups_arr <<<"${egroups}" + [[ ${#egroups_arr[@]} -gt 0 ]] || die "${FUNCNAME}: no groups specified" + + for g in "${egroups_arr[@]}" ; do + if [[ -z $(egetent group "${g}") ]] ; then + eerror "You must add group ${g} to the system first" + die "${g} is not a valid GID" + fi + done + + local defgroup=${egroups_arr[0]} exgroups_arr=() + # sort supplementary groups to make comparison possible + readarray -t exgroups_arr < <(printf '%s\n' "${egroups_arr[@]:1}" | sort) + local exgroups=${exgroups_arr[*]} + exgroups=${exgroups// /,} + egroups=${defgroup}${exgroups:+,${exgroups}} + + # exit with no message if group membership is up to date + if [[ $(egetgroups "${euser}") == ${egroups} ]]; then + return 0 + fi + + local opts=( -g "${defgroup}" -G "${exgroups}" ) + einfo "Updating groups for user '${euser}' ..." + einfo " - Groups: ${egroups}" + + # update the group + case ${CHOST} in + *-freebsd*|*-dragonfly*) + pw usermod "${euser}" "${opts[@]}" && return 0 + [[ $? == 8 ]] && eerror "${euser} is in use, cannot update groups" + eerror "There was an error when attempting to update the groups for ${euser}" + eerror "Please update it manually on your system:" + eerror "\t pw usermod \"${euser}\" ${opts[*]}" + ;; + + *) + usermod "${opts[@]}" "${euser}" && return 0 + [[ $? == 8 ]] && eerror "${euser} is in use, cannot update groups" + eerror "There was an error when attempting to update the groups for ${euser}" + eerror "Please update it manually on your system (as root):" + eerror "\t usermod ${opts[*]} \"${euser}\"" + ;; + esac +} + fi -- 2.22.0.rc3