From 23deef88b9bb020c87c8b4ad30113a4f97445a1a Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 9 Feb 2017 11:43:44 +0100 Subject: Revert "core/execute: set HOME, USER also for root users" This reverts commit 8b89628a10af3863bfc97872912e9da4076a5929. This broke #5246 --- src/core/execute.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/core/execute.c b/src/core/execute.c index f57eb26388..1e32697723 100644 --- a/src/core/execute.c +++ b/src/core/execute.c @@ -815,10 +815,13 @@ static int get_fixed_user(const ExecContext *c, const char **user, assert(c); + if (!c->user) + return 0; + /* Note that we don't set $HOME or $SHELL if they are not particularly enlightening anyway * (i.e. are "/" or "/bin/nologin"). */ - name = c->user ?: "root"; + name = c->user; r = get_user_creds_clean(&name, uid, gid, home, shell); if (r < 0) return r; -- cgit v1.2.3-54-g00ecf From 6732edab4eff2f656690681bc37595a59470e4a1 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 9 Feb 2017 11:58:39 +0100 Subject: execute: set working directory to /root if User= is not set, but WorkingDirectory=~ is Or actually, try to to do the right thing depending on what is available: - If we know $HOME from User=, then use that. - If the UID for the service is 0, hardcode that WorkingDirectory=~ means WorkingDirectory=/root - In any other case (which will be the unprivileged --user case), use get_home_dir() to find the $HOME of the user we are running as. - Otherwise fail. Fixes: #5246 #5124 --- src/core/execute.c | 50 +++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 45 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/core/execute.c b/src/core/execute.c index 1e32697723..492df2fedb 100644 --- a/src/core/execute.c +++ b/src/core/execute.c @@ -2017,14 +2017,18 @@ static int apply_working_directory( const char *home, const bool needs_mount_ns) { - const char *d; - const char *wd; + const char *d, *wd; assert(context); - if (context->working_directory_home) + if (context->working_directory_home) { + + if (!home) + return -ENXIO; + wd = home; - else if (context->working_directory) + + } else if (context->working_directory) wd = context->working_directory; else wd = "/"; @@ -2181,6 +2185,35 @@ static int send_user_lookup( return 0; } +static int acquire_home(const ExecContext *c, uid_t uid, const char** home, char **buf) { + int r; + + assert(c); + assert(home); + assert(buf); + + /* If WorkingDirectory=~ is set, try to acquire a usable home directory. */ + + if (*home) + return 0; + + if (!c->working_directory_home) + return 0; + + if (uid == 0) { + /* Hardcode /root as home directory for UID 0 */ + *home = "/root"; + return 1; + } + + r = get_home_dir(buf); + if (r < 0) + return r; + + *home = *buf; + return 1; +} + static int exec_child( Unit *unit, ExecCommand *command, @@ -2198,7 +2231,7 @@ static int exec_child( char **error_message) { _cleanup_strv_free_ char **our_env = NULL, **pass_env = NULL, **accum_env = NULL, **final_argv = NULL; - _cleanup_free_ char *mac_selinux_context_net = NULL; + _cleanup_free_ char *mac_selinux_context_net = NULL, *home_buffer = NULL; _cleanup_free_ gid_t *supplementary_gids = NULL; const char *username = NULL, *groupname = NULL; const char *home = NULL, *shell = NULL; @@ -2351,6 +2384,13 @@ static int exec_child( user_lookup_fd = safe_close(user_lookup_fd); + r = acquire_home(context, uid, &home, &home_buffer); + if (r < 0) { + *exit_status = EXIT_CHDIR; + *error_message = strdup("Failed to determine $HOME for user"); + return r; + } + /* If a socket is connected to STDIN/STDOUT/STDERR, we * must sure to drop O_NONBLOCK */ if (socket_fd >= 0) -- cgit v1.2.3-54-g00ecf From 3b0e5bb524e3274e61aced08f72907d96eaeedaa Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 9 Feb 2017 13:16:51 +0100 Subject: execute: use prefix_roota() where appropriate --- src/core/execute.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/core/execute.c b/src/core/execute.c index 492df2fedb..be03695776 100644 --- a/src/core/execute.c +++ b/src/core/execute.c @@ -2040,7 +2040,7 @@ static int apply_working_directory( d = wd; } else - d = strjoina(strempty(context->root_directory), "/", strempty(wd)); + d = prefix_roota(context->root_directory, wd); if (chdir(d) < 0 && !context->working_directory_missing_ok) return -errno; -- cgit v1.2.3-54-g00ecf From 376fecf6709fa7a080c9f5b4f9ee34b9eecfc0ac Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 9 Feb 2017 13:17:00 +0100 Subject: execute: set the right exit status for CHDIR vs. CHROOT Fixes: #5125 --- src/core/execute.c | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/core/execute.c b/src/core/execute.c index be03695776..6041da46d6 100644 --- a/src/core/execute.c +++ b/src/core/execute.c @@ -2015,16 +2015,20 @@ static int apply_working_directory( const ExecContext *context, const ExecParameters *params, const char *home, - const bool needs_mount_ns) { + const bool needs_mount_ns, + int *exit_status) { const char *d, *wd; assert(context); + assert(exit_status); if (context->working_directory_home) { - if (!home) + if (!home) { + *exit_status = EXIT_CHDIR; return -ENXIO; + } wd = home; @@ -2035,15 +2039,19 @@ static int apply_working_directory( if (params->flags & EXEC_APPLY_CHROOT) { if (!needs_mount_ns && context->root_directory) - if (chroot(context->root_directory) < 0) + if (chroot(context->root_directory) < 0) { + *exit_status = EXIT_CHROOT; return -errno; + } d = wd; } else d = prefix_roota(context->root_directory, wd); - if (chdir(d) < 0 && !context->working_directory_missing_ok) + if (chdir(d) < 0 && !context->working_directory_missing_ok) { + *exit_status = EXIT_CHDIR; return -errno; + } return 0; } @@ -2606,11 +2614,9 @@ static int exec_child( } /* Apply just after mount namespace setup */ - r = apply_working_directory(context, params, home, needs_mount_namespace); - if (r < 0) { - *exit_status = EXIT_CHROOT; + r = apply_working_directory(context, params, home, needs_mount_namespace, exit_status); + if (r < 0) return r; - } /* Drop groups as early as possbile */ if ((params->flags & EXEC_APPLY_PERMISSIONS) && !command->privileged) { -- cgit v1.2.3-54-g00ecf