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)
committerMike Yuan <me@yhndnzj.com>
Mon, 18 Nov 2024 23:38:18 +0000 (00:38 +0100)
No functional change, preparation for later commits.

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

index 632f1b6281cf890dab72987c5d8855c21076313c..2b7c923b5e6ee0145dae5c569306042906c19e36 100644 (file)
@@ -220,9 +220,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;
         }
@@ -244,6 +244,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)) {
@@ -315,16 +316,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 4858a9cb587e0c91654926aba4d1dd081f7c7010..6f221ebfb0b321fc661c89f2dbe71417ea88833c 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 2f8924cd0187da4ad74e58b5464cdcc2f49f86c8..517727a7b20d6f316f19be6fb96e25367d825d0a 100644 (file)
@@ -858,7 +858,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 c62dce8950fde42bb8012132f3ce81b75232ce6b..1b13e74b83c388e0574597655a497c9f2acdb631 100644 (file)
@@ -2297,7 +2297,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);