From: Mike Yuan Date: Tue, 8 Apr 2025 13:20:21 +0000 (+0200) Subject: core/exec-invoke: consult NSS for root user creds if SetLoginEnvironment=/PAMName= X-Git-Tag: v256.14~67 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=574ae3d47d24557da8afcc5bd6ada1547b789e2c;p=thirdparty%2Fsystemd.git core/exec-invoke: consult NSS for root user creds if SetLoginEnvironment=/PAMName= (cherry picked from commit 9c0d8b8c4f18de76f945e82030db82135e7ffa34) (cherry picked from commit e558789a228dc34f6a5c60ad9f76f4996f4712d6) --- diff --git a/src/core/exec-invoke.c b/src/core/exec-invoke.c index 7c755f8169e..48137bb5014 100644 --- a/src/core/exec-invoke.c +++ b/src/core/exec-invoke.c @@ -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");