diff --git a/src/basic/user-util.c b/src/basic/user-util.c index 9dcf16d7a43..d39be553369 100644 --- a/src/basic/user-util.c +++ b/src/basic/user-util.c @@ -569,21 +569,21 @@ int getgroups_alloc(gid_t** gids) { return ngroups; } -int get_home_dir(char **ret) { +int get_home_dir_for_uid(uid_t u, char **ret) { _cleanup_free_ struct passwd *p = NULL; const char *e; - uid_t u; int r; assert(ret); - /* Take the user specified one */ - e = secure_getenv("HOME"); - if (e && path_is_valid(e) && path_is_absolute(e)) - goto found; + /* If we are the same user we're checking, try to use the environment's $HOME */ + if (u == getuid()) { + e = secure_getenv("HOME"); + if (e && path_is_valid(e) && path_is_absolute(e)) + goto found; + } /* Hardcode home directory for root and nobody to avoid NSS */ - u = getuid(); if (u == 0) { e = "/root"; goto found; @@ -606,21 +606,25 @@ int get_home_dir(char **ret) { return path_simplify_alloc(e, ret); } -int get_shell(char **ret) { +int get_home_dir(char **ret) { + return get_home_dir_for_uid(getuid(), ret); +} + +int get_shell_for_uid(uid_t u, char **ret) { _cleanup_free_ struct passwd *p = NULL; const char *e; - uid_t u; int r; assert(ret); - /* Take the user specified one */ - e = secure_getenv("SHELL"); - if (e && path_is_valid(e) && path_is_absolute(e)) - goto found; + /* If we are the same user we're checking, try to use the environment's $SHELL */ + if (u == getuid()) { + e = secure_getenv("SHELL"); + if (e && path_is_valid(e) && path_is_absolute(e)) + goto found; + } /* Hardcode shell for root and nobody to avoid NSS */ - u = getuid(); if (u == 0) { e = default_root_shell(NULL); goto found; @@ -643,6 +647,10 @@ int get_shell(char **ret) { return path_simplify_alloc(e, ret); } +int get_shell(char **ret) { + return get_shell_for_uid(getuid(), ret); +} + int fully_set_uid_gid(uid_t uid, gid_t gid, const gid_t supplementary_gids[], size_t n_supplementary_gids) { int r; diff --git a/src/basic/user-util.h b/src/basic/user-util.h index 777451b8c88..4c077217cd1 100644 --- a/src/basic/user-util.h +++ b/src/basic/user-util.h @@ -55,7 +55,9 @@ int merge_gid_lists(const gid_t *list1, size_t size1, const gid_t *list2, size_t int getgroups_alloc(gid_t** gids); int get_home_dir(char **ret); +int get_home_dir_for_uid(uid_t u, char **ret); int get_shell(char **ret); +int get_shell_for_uid(uid_t u, char **ret); int fully_set_uid_gid(uid_t uid, gid_t gid, const gid_t supplementary_gids[], size_t n_supplementary_gids); static inline int reset_uid_gid(void) { diff --git a/src/core/exec-invoke.c b/src/core/exec-invoke.c index 4b63e2a2040..89d0579a279 100644 --- a/src/core/exec-invoke.c +++ b/src/core/exec-invoke.c @@ -3579,7 +3579,7 @@ static int send_user_lookup( return 0; } -static int acquire_home(const ExecContext *c, const char **home, char **ret_buf) { +static int acquire_home(const ExecContext *c, const char **home, uid_t uid, char **ret_buf) { int r; assert(c); @@ -3597,7 +3597,7 @@ static int acquire_home(const ExecContext *c, const char **home, char **ret_buf) if (c->dynamic_user) return -EADDRNOTAVAIL; - r = get_home_dir(ret_buf); + r = get_home_dir_for_uid(uid, ret_buf); if (r < 0) return r; @@ -4346,7 +4346,7 @@ int exec_invoke( params->user_lookup_fd = safe_close(params->user_lookup_fd); - r = acquire_home(context, &home, &home_buffer); + r = acquire_home(context, &home, uid, &home_buffer); if (r < 0) { *exit_status = EXIT_CHDIR; return log_exec_error_errno(context, params, r, "Failed to determine $HOME for user: %m");