From 82855aa610510ddacf72bec03629839a7829e3b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Mon, 24 May 2021 11:34:16 +0200 Subject: [PATCH] sysusers: make sysusers work with dnf --installroot This is not very pretty, but the code in fs-util.c already provisions for missing /proc. We ourselves are careful to set up /proc, but not everybody is and it is important for sysusers to also work where shadow-utils would: I would like to replace calls to useradd and groupadd in Fedora systemd rpm scriptlets with a call to sysusers. It has a number of advantages: - dogfooding - we don't need to manually duplicate the information from our sysusers files to scriptlets - a dependency on shadow-utils is dropped, which transitively drops dependencies on setup and fedora-repos and bunch of other stuff. We could try to get 'dnf' and 'rpm --root' and such to be reworked, but not in any reasonable timeframe. And even if this was done, we'd still want to support older rpm/dnf versions. --- src/sysusers/sysusers.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/sysusers/sysusers.c b/src/sysusers/sysusers.c index 8e0d76ef46d..5aa3531012c 100644 --- a/src/sysusers/sysusers.c +++ b/src/sysusers/sysusers.c @@ -396,7 +396,11 @@ static int write_temporary_passwd(const char *passwd_path, FILE **tmpfile, char original = fopen(passwd_path, "re"); if (original) { - r = copy_rights(fileno(original), fileno(passwd)); + /* Allow fallback path for when /proc is not mounted. On any normal system /proc will be + * mounted, but e.g. when 'dnf --installroot' is used, it might not be. There is no security + * relevance here, since the environment is ultimately trusted, and not requiring /proc makes + * it easier to depend on sysusers in packaging scripts and suchlike. */ + r = copy_rights_with_fallback(fileno(original), fileno(passwd), passwd_tmp); if (r < 0) return log_debug_errno(r, "Failed to copy permissions from %s to %s: %m", passwd_path, passwd_tmp); @@ -513,7 +517,7 @@ static int write_temporary_shadow(const char *shadow_path, FILE **tmpfile, char original = fopen(shadow_path, "re"); if (original) { - r = copy_rights(fileno(original), fileno(shadow)); + r = copy_rights_with_fallback(fileno(original), fileno(shadow), shadow_tmp); if (r < 0) return log_debug_errno(r, "Failed to copy permissions from %s to %s: %m", shadow_path, shadow_tmp); @@ -644,7 +648,7 @@ static int write_temporary_group(const char *group_path, FILE **tmpfile, char ** original = fopen(group_path, "re"); if (original) { - r = copy_rights(fileno(original), fileno(group)); + r = copy_rights_with_fallback(fileno(original), fileno(group), group_tmp); if (r < 0) return log_debug_errno(r, "Failed to copy permissions from %s to %s: %m", group_path, group_tmp); @@ -746,7 +750,7 @@ static int write_temporary_gshadow(const char * gshadow_path, FILE **tmpfile, ch if (original) { struct sgrp *sg; - r = copy_rights(fileno(original), fileno(gshadow)); + r = copy_rights_with_fallback(fileno(original), fileno(gshadow), gshadow_tmp); if (r < 0) return log_debug_errno(r, "Failed to copy permissions from %s to %s: %m", gshadow_path, gshadow_tmp);