Gentoo Archives: gentoo-dev

From: "Michał Górny" <mgorny@g.o>
To: gentoo-dev@l.g.o
Cc: "Michał Górny" <mgorny@g.o>
Subject: [gentoo-dev] [PATCH v3 13/19] user.eclass: Introduce e{get,set}groups
Date: Sun, 09 Jun 2019 11:33:08
Message-Id: 20190609112814.15907-14-mgorny@gentoo.org
In Reply to: [gentoo-dev] [PATCH v3 00/19] User/group packages by "Michał Górny"
1 ---
2 eclass/user.eclass | 88 ++++++++++++++++++++++++++++++++++++++++++++++
3 1 file changed, 88 insertions(+)
4
5 diff --git a/eclass/user.eclass b/eclass/user.eclass
6 index f4f6c75f3b71..23c3b953842f 100644
7 --- a/eclass/user.eclass
8 +++ b/eclass/user.eclass
9 @@ -438,6 +438,24 @@ egetcomment() {
10 egetent passwd "$1" | cut -d: -f${pos}
11 }
12
13 +# @FUNCTION: egetgroups
14 +# @USAGE: <user>
15 +# @DESCRIPTION:
16 +# Gets all the groups user belongs to. The primary group is returned
17 +# first, then all supplementary groups. Groups are ','-separated.
18 +egetgroups() {
19 + [[ $# -eq 1 ]] || die "usage: egetgroups <user>"
20 +
21 + local egroups_arr
22 + read -r -a egroups_arr < <(id -G -n "$1")
23 +
24 + local defgroup=${egroups_arr[0]}
25 + # sort supplementary groups to make comparison possible
26 + readarray -t exgroups_arr < <(printf '%s\n' "${egroups_arr[@]:1}" | sort)
27 + local exgroups=${exgroups_arr[*]}
28 + echo "${defgroup}${exgroups:+,${exgroups// /,}}"
29 +}
30 +
31 # @FUNCTION: esethome
32 # @USAGE: <user> <homedir>
33 # @DESCRIPTION:
34 @@ -627,4 +645,74 @@ esetcomment() {
35 esac
36 }
37
38 +# @FUNCTION: esetgroups
39 +# @USAGE: <user> <groups>
40 +# @DESCRIPTION:
41 +# Update the group field in a platform-agnostic way.
42 +# Required parameters is the username and the new list of groups,
43 +# primary group first.
44 +esetgroups() {
45 + _assert_pkg_ebuild_phase ${FUNCNAME}
46 +
47 + [[ ${#} -eq 2 ]] || die "Usage: ${FUNCNAME} <user> <groups>"
48 +
49 + # get the username
50 + local euser=$1; shift
51 +
52 + # lets see if the username already exists
53 + if [[ -z $(egetent passwd "${euser}") ]] ; then
54 + ewarn "User does not exist, cannot set group -- skipping."
55 + return 1
56 + fi
57 +
58 + # handle group
59 + local egroups=$1; shift
60 +
61 + local g egroups_arr=()
62 + IFS="," read -r -a egroups_arr <<<"${egroups}"
63 + [[ ${#egroups_arr[@]} -gt 0 ]] || die "${FUNCNAME}: no groups specified"
64 +
65 + for g in "${egroups_arr[@]}" ; do
66 + if [[ -z $(egetent group "${g}") ]] ; then
67 + eerror "You must add group ${g} to the system first"
68 + die "${g} is not a valid GID"
69 + fi
70 + done
71 +
72 + local defgroup=${egroups_arr[0]} exgroups_arr=()
73 + # sort supplementary groups to make comparison possible
74 + readarray -t exgroups_arr < <(printf '%s\n' "${egroups_arr[@]:1}" | sort)
75 + local exgroups=${exgroups_arr[*]}
76 + exgroups=${exgroups// /,}
77 + egroups=${defgroup}${exgroups:+,${exgroups}}
78 +
79 + # exit with no message if group membership is up to date
80 + if [[ $(egetgroups "${euser}") == ${egroups} ]]; then
81 + return 0
82 + fi
83 +
84 + local opts=( -g "${defgroup}" -G "${exgroups}" )
85 + einfo "Updating groups for user '${euser}' ..."
86 + einfo " - Groups: ${egroups}"
87 +
88 + # update the group
89 + case ${CHOST} in
90 + *-freebsd*|*-dragonfly*)
91 + pw usermod "${euser}" "${opts[@]}" && return 0
92 + [[ $? == 8 ]] && eerror "${euser} is in use, cannot update groups"
93 + eerror "There was an error when attempting to update the groups for ${euser}"
94 + eerror "Please update it manually on your system:"
95 + eerror "\t pw usermod \"${euser}\" ${opts[*]}"
96 + ;;
97 +
98 + *)
99 + usermod "${opts[@]}" "${euser}" && return 0
100 + [[ $? == 8 ]] && eerror "${euser} is in use, cannot update groups"
101 + eerror "There was an error when attempting to update the groups for ${euser}"
102 + eerror "Please update it manually on your system (as root):"
103 + eerror "\t usermod ${opts[*]} \"${euser}\""
104 + ;;
105 + esac
106 +}
107 +
108 fi
109 --
110 2.22.0.rc3