]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
sysusers: make sysusers work with dnf --installroot 19709/head
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Mon, 24 May 2021 09:34:16 +0000 (11:34 +0200)
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Mon, 24 May 2021 19:41:24 +0000 (21:41 +0200)
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

index 8e0d76ef46dc4bf9840d192b93119c05264cd2fa..5aa3531012c5d634cb9b115ec8d5f45600ac3583 100644 (file)
@@ -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);