basic/user-util: split out placeholder suppression from USER_CREDS_CLEAN into its...
authorMike Yuan <me@yhndnzj.com>
Mon, 18 Nov 2024 18:30:02 +0000 (19:30 +0100)
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Thu, 28 Nov 2024 14:08:33 +0000 (15:08 +0100)
No functional change, preparation for later commits.

(cherry picked from commit eea9d3eb106a91d4479d859603463bdfe3d262eb)

src/basic/user-util.c
src/basic/user-util.h
src/core/exec-invoke.c
src/run/run.c

index 85bd5f20be0c71d6630fd0d39af3e02afeaf7050..a40799d5e544756c985ac5ef8159a81db198f39b 100644 (file)
@@ -219,9 +219,9 @@ static int synthesize_user_creds(
                 if (ret_gid)
                         *ret_gid = GID_NOBODY;
                 if (ret_home)
-                        *ret_home = FLAGS_SET(flags, USER_CREDS_CLEAN) ? NULL : "/";
+                        *ret_home = FLAGS_SET(flags, USER_CREDS_SUPPRESS_PLACEHOLDER) ? NULL : "/";
                 if (ret_shell)
-                        *ret_shell = FLAGS_SET(flags, USER_CREDS_CLEAN) ? NULL : NOLOGIN;
+                        *ret_shell = FLAGS_SET(flags, USER_CREDS_SUPPRESS_PLACEHOLDER) ? NULL : NOLOGIN;
 
                 return 0;
         }
@@ -243,6 +243,7 @@ int get_user_creds(
 
         assert(username);
         assert(*username);
+        assert((ret_home || ret_shell) || !(flags & (USER_CREDS_SUPPRESS_PLACEHOLDER|USER_CREDS_CLEAN)));
 
         if (!FLAGS_SET(flags, USER_CREDS_PREFER_NSS) ||
             (!ret_home && !ret_shell)) {
@@ -314,16 +315,14 @@ int get_user_creds(
 
         if (ret_home)
                 /* Note: we don't insist on normalized paths, since there are setups that have /./ in the path */
-                *ret_home = (FLAGS_SET(flags, USER_CREDS_CLEAN) &&
-                             (empty_or_root(p->pw_dir) ||
-                              !path_is_valid(p->pw_dir) ||
-                              !path_is_absolute(p->pw_dir))) ? NULL : p->pw_dir;
+                *ret_home = (FLAGS_SET(flags, USER_CREDS_SUPPRESS_PLACEHOLDER) && empty_or_root(p->pw_dir)) ||
+                            (FLAGS_SET(flags, USER_CREDS_CLEAN) && (!path_is_valid(p->pw_dir) || !path_is_absolute(p->pw_dir)))
+                            ? NULL : p->pw_dir;
 
         if (ret_shell)
-                *ret_shell = (FLAGS_SET(flags, USER_CREDS_CLEAN) &&
-                              (shell_is_placeholder(p->pw_shell) ||
-                               !path_is_valid(p->pw_shell) ||
-                               !path_is_absolute(p->pw_shell))) ? NULL : p->pw_shell;
+                *ret_shell = (FLAGS_SET(flags, USER_CREDS_SUPPRESS_PLACEHOLDER) && shell_is_placeholder(p->pw_shell)) ||
+                             (FLAGS_SET(flags, USER_CREDS_CLEAN) && (!path_is_valid(p->pw_shell) || !path_is_absolute(p->pw_shell)))
+                             ? NULL : p->pw_shell;
 
         if (patch_username)
                 *username = p->pw_name;
index d53b60c3567103da9d0ef70d4e759cc172a9399d..8f913a26a49ba8dae87b24a16941cfe45b8a5056 100644 (file)
@@ -48,9 +48,10 @@ static inline bool shell_is_placeholder(const char *shell) {
 }
 
 typedef enum UserCredsFlags {
-        USER_CREDS_PREFER_NSS    = 1 << 0,  /* if set, only synthesize user records if database lacks them. Normally we bypass the userdb entirely for the records we can synthesize */
-        USER_CREDS_ALLOW_MISSING = 1 << 1,  /* if a numeric UID string is resolved, be OK if there's no record for it */
-        USER_CREDS_CLEAN         = 1 << 2,  /* try to clean up shell and home fields with invalid data */
+        USER_CREDS_PREFER_NSS           = 1 << 0,  /* if set, only synthesize user records if database lacks them. Normally we bypass the userdb entirely for the records we can synthesize */
+        USER_CREDS_ALLOW_MISSING        = 1 << 1,  /* if a numeric UID string is resolved, be OK if there's no record for it */
+        USER_CREDS_CLEAN                = 1 << 2,  /* try to clean up shell and home fields with invalid data */
+        USER_CREDS_SUPPRESS_PLACEHOLDER = 1 << 3,  /* suppress home and/or shell fields if value is placeholder (root/empty/nologin) */
 } UserCredsFlags;
 
 int get_user_creds(const char **username, uid_t *ret_uid, gid_t *ret_gid, const char **ret_home, const char **ret_shell, UserCredsFlags flags);
index 56df5cf8aacbf93db5b2787e4769f33ad404ca23..98401b85b7513dcce867be1b529e388da33ac805 100644 (file)
@@ -861,7 +861,7 @@ static int get_fixed_user(
         /* Note that we don't set $HOME or $SHELL if they are not particularly enlightening anyway
          * (i.e. are "/" or "/bin/nologin"). */
 
-        r = get_user_creds(&user_or_uid, ret_uid, ret_gid, ret_home, ret_shell, USER_CREDS_CLEAN);
+        r = get_user_creds(&user_or_uid, ret_uid, ret_gid, ret_home, ret_shell, USER_CREDS_CLEAN|USER_CREDS_SUPPRESS_PLACEHOLDER);
         if (r < 0)
                 return r;
 
index c5f5fb87bc3062ea0f8a4850ef271997e4a0c6ae..d8118763f073dc6f9545f07cbdabd7218706ead1 100644 (file)
@@ -2086,7 +2086,8 @@ static int start_transient_scope(sd_bus *bus) {
                 uid_t uid;
                 gid_t gid;
 
-                r = get_user_creds(&arg_exec_user, &uid, &gid, &home, &shell, USER_CREDS_CLEAN|USER_CREDS_PREFER_NSS);
+                r = get_user_creds(&arg_exec_user, &uid, &gid, &home, &shell,
+                                   USER_CREDS_CLEAN|USER_CREDS_SUPPRESS_PLACEHOLDER|USER_CREDS_PREFER_NSS);
                 if (r < 0)
                         return log_error_errno(r, "Failed to resolve user %s: %m", arg_exec_user);