]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
core/exec-invoke: consult NSS for root user creds if SetLoginEnvironment=/PAMName=
authorMike Yuan <me@yhndnzj.com>
Tue, 8 Apr 2025 13:20:21 +0000 (15:20 +0200)
committerLuca Boccassi <luca.boccassi@gmail.com>
Sat, 17 May 2025 11:43:20 +0000 (12:43 +0100)
(cherry picked from commit 9c0d8b8c4f18de76f945e82030db82135e7ffa34)
(cherry picked from commit e558789a228dc34f6a5c60ad9f76f4996f4712d6)

src/core/exec-invoke.c

index 7c755f8169eb5679db3bea3a14632505891db3d9..48137bb5014422a75e3f78d3a1a1cd2d4b8cc1fe 100644 (file)
@@ -847,6 +847,7 @@ restore_stdio:
 
 static int get_fixed_user(
                 const char *user_or_uid,
+                bool prefer_nss,
                 const char **ret_username,
                 uid_t *ret_uid,
                 gid_t *ret_gid,
@@ -858,7 +859,8 @@ static int get_fixed_user(
         assert(user_or_uid);
         assert(ret_username);
 
-        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|(prefer_nss ? USER_CREDS_PREFER_NSS : 0));
         if (r < 0)
                 return r;
 
@@ -1861,7 +1863,7 @@ static int build_environment(
         if (!username && !c->dynamic_user && p->runtime_scope == RUNTIME_SCOPE_SYSTEM) {
                 assert(!c->user);
 
-                r = get_fixed_user("root", &username, NULL, NULL, &home, &shell);
+                r = get_fixed_user("root", /* prefer_nss = */ false, &username, NULL, NULL, &home, &shell);
                 if (r < 0)
                         return log_exec_debug_errno(c,
                                                     p,
@@ -4278,7 +4280,14 @@ int exec_invoke(
                         u = NULL;
 
                 if (u) {
-                        r = get_fixed_user(u, &username, &uid, &gid, &home, &shell);
+                        /* We can't use nss unconditionally for root without risking deadlocks if some IPC services
+                         * will be started by pid1 and are ordered after us. But if SetLoginEnvironment= is
+                         * enabled *explicitly* (i.e. no exec_context_get_set_login_environment() here),
+                         * or PAM shall be invoked, let's consult NSS even for root, so that the user
+                         * gets accurate $SHELL in session(-like) contexts. */
+                        r = get_fixed_user(u,
+                                           /* prefer_nss = */ context->set_login_environment > 0 || context->pam_name,
+                                           &username, &uid, &gid, &home, &shell);
                         if (r < 0) {
                                 *exit_status = EXIT_USER;
                                 return log_exec_error_errno(context, params, r, "Failed to determine user credentials: %m");