commit:     5fd98f867aeaa30ccc62ff13257aefdffe1f3745
Author:     Jérémy Connat <morderca <AT> morderca <DOT> net>
AuthorDate: Mon Feb  1 12:24:47 2021 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Sat Apr 23 01:26:47 2022 +0000
URL:        https://gitweb.gentoo.org/repo/gentoo.git/commit/?id=5fd98f86

user-info.eclass: Fixing user/group creation when using different ROOT

Signed-off-by: Jérémy Connat <morderca <AT> morderca.net>
Signed-off-by: Sam James <sam <AT> gentoo.org>

 eclass/user-info.eclass | 35 +++++++++++++++++++++++++++++------
 1 file changed, 29 insertions(+), 6 deletions(-)

diff --git a/eclass/user-info.eclass b/eclass/user-info.eclass
index 3838585ab6c1..5550e4f08eeb 100644
--- a/eclass/user-info.eclass
+++ b/eclass/user-info.eclass
@@ -23,6 +23,7 @@ _USER_INFO_ECLASS=1
 # dscl (Mac OS X 10.5), and pw (FreeBSD) used in enewuser()/enewgroup().
 #
 # Supported databases: group passwd
+# Warning: This function can be used only in pkg_* phases when ROOT is valid.
 egetent() {
        local db=$1 key=$2
 
@@ -43,18 +44,31 @@ egetent() {
                # lookup by uid/gid
                local opts
                if [[ ${key} == [[:digit:]]* ]] ; then
-                       [[ ${db} == "user" ]] && opts="-u" || opts="-g"
+                       [[ ${db} == "user" ]] && opts=( -u ) || opts=( -g )
                fi
 
+               # Handle different ROOT
+               [[ -n ${ROOT} ]] && opts+=( -R "${ROOT}" )
+
                pw show ${db} ${opts} "${key}" -q
                ;;
        *-openbsd*)
-               grep "${key}:\*:" /etc/${db}
+               grep "${key}:\*:" "${EROOT}/etc/${db}"
                ;;
        *)
-               # ignore nscd output if we're not running as root
-               type -p nscd >/dev/null && nscd -i "${db}" 2>/dev/null
-               getent "${db}" "${key}"
+               # getent does not support -R option, if we are working on a 
different
+               # ROOT than /, fallback to grep technique.
+               if [[ -z ${ROOT} ]]; then
+                       # ignore nscd output if we're not running as root
+                       type -p nscd >/dev/null && nscd -i "${db}" 2>/dev/null
+                       getent "${db}" "${key}"
+               else
+                       if [[ ${key} =~ ^[[:digit:]]+$ ]]; then
+                               grep -E "^([^:]*:){2}${key}" "${ROOT}/etc/${db}"
+                       else
+                               grep "^${key}:" "${ROOT}/etc/${db}"
+                       fi
+               fi
                ;;
        esac
 }
@@ -151,7 +165,16 @@ egetgroups() {
        [[ $# -eq 1 ]] || die "usage: egetgroups <user>"
 
        local egroups_arr
-       read -r -a egroups_arr < <(id -G -n "$1")
+       if [[ -n "${ROOT}" ]]; then
+               local pgroup=$(egetent passwd "$1" | cut -d: -f1)
+               local sgroups=( $(grep -E ":([^:]*,)?$1(,[^:]*)?$" 
"${ROOT}/etc/group" | cut -d: -f1) )
+
+               # Remove primary group from list
+               sgroups=${sgroups#${pgroup}}
+               egroups_arr=( ${pgroup} ${sgroups[@]} )
+       else
+               read -r -a egroups_arr < <(id -G -n "$1")
+       fi
 
        local g groups=${egroups_arr[0]}
        # sort supplementary groups to make comparison possible

Reply via email to