commit:     6e0d845766d5f622750379c8fdd3191bb651d33c
Author:     Nicolas PARLANT <nicolas.parlant <AT> parhuet <DOT> fr>
AuthorDate: Wed Mar 11 15:52:34 2026 +0000
Commit:     Mike Gilbert <floppym <AT> gentoo <DOT> org>
CommitDate: Sun Mar 15 20:17:44 2026 +0000
URL:        https://gitweb.gentoo.org/proj/portage.git/commit/?id=6e0d8457

fowners: use numeric-uid-gid w/ custom target root

fowners currently resolves users on the host system, even when a custom
target root is defined. Use numeric-uid-gid from the target database in
that case.

Bug: https://bugs.gentoo.org/971120
Signes-off-by: Nicolas PARLANT <nicolas.parlant <AT> parhuet.fr>
Signed-off-by: Mike Gilbert <floppym <AT> gentoo.org>

 bin/ebuild-helpers/fowners | 50 +++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 49 insertions(+), 1 deletion(-)

diff --git a/bin/ebuild-helpers/fowners b/bin/ebuild-helpers/fowners
index a6367e4c00..a1589d1b2d 100755
--- a/bin/ebuild-helpers/fowners
+++ b/bin/ebuild-helpers/fowners
@@ -8,6 +8,49 @@ if ! ___eapi_has_prefix_variables; then
        ED=${D}
 fi
 
+__resolve_owner() {
+       local owner="${1}"
+       local user group uid gid pgid pwdb_path
+
+       if [[ ${EBUILD_PHASE_FUNC} == pkg_* ]]; then
+               # for pkg_preinst
+               pwdb_path="${EROOT}"/etc
+       else
+               # for src_install
+               pwdb_path="${ESYSROOT}"/etc
+       fi
+
+       IFS=':' read -r user group <<< "${owner}"
+
+       if [[ -n "${user}" ]]; then
+               if [[ "${user}" =~ ^[0-9]+$ ]]; then
+                       uid="${user}"
+               else
+                       read -r uid pgid <<< "$(awk -F: -v u="${user}" '$1==u { 
print $3, $4 }' "${pwdb_path}"/passwd)"
+                       [[ "${uid}" =~ ^[0-9]+$ ]] || __helpers_die "fowners: 
invalid user in ${pwdb_path}/passwd: ${owner}"
+               fi
+       fi
+
+       if [[ -n "${group}" ]]; then
+               if [[ "${group}" =~ ^[0-9]+$ ]]; then
+                       gid="${group}"
+               else
+                       gid=$(awk -F: -v g="${group}" '$1==g{print $3}' 
"${pwdb_path}"/group)
+                       [[ "${gid}" =~ ^[0-9]+$ ]] || __helpers_die "fowners: 
invalid group in ${pwdb_path}/group: ${owner}"
+               fi
+               gid=":${gid}"
+       elif [[ "${owner}" == *: ]]; then
+               # `chown uid:` is invalid with numeric-uid-gid, use the primary 
group defined above
+               if [[ "${pgid}" =~ ^[0-9]+$ ]]; then
+                       gid=":${pgid}"
+               else
+                       __helpers_die "fowners: invalid primary group for 
${user} in ${pwdb_path}/passwd: ${owner}"
+               fi
+       fi
+
+       printf '%s%s' "${uid}" "${gid}"
+}
+
 args=()
 got_owner=
 for arg; do
@@ -16,7 +59,12 @@ for arg; do
        elif [[ ! ${got_owner} ]]; then
                # the first non-option is the owner and must not be prefixed
                got_owner=1
-               args+=( "${arg}" )
+               # use numeric-uid-gid from the custom target root
+               if ___eapi_has_SYSROOT && [[ -n "${SYSROOT}" || -n "${ROOT}" 
]]; then
+                       args+=( "$(__resolve_owner "${arg}")" )
+               else
+                       args+=( "${arg}" )
+               fi
        else
                args+=( "${ED%/}/${arg#/}" )
        fi

Reply via email to