diff options
author | Ron Yorston <rmy@pobox.com> | 2023-03-27 08:57:40 +0100 |
---|---|---|
committer | Ron Yorston <rmy@pobox.com> | 2023-03-27 08:57:40 +0100 |
commit | 255ebaf535c9f6d8a88e23d55d8be04b0ea73343 (patch) | |
tree | 160986f98132d365c341ae17a0ce13a9d6f2f763 | |
parent | f4178f8d0b97baea0bb6a6444fc37171c83ad316 (diff) | |
download | busybox-w32-255ebaf535c9f6d8a88e23d55d8be04b0ea73343.tar.gz busybox-w32-255ebaf535c9f6d8a88e23d55d8be04b0ea73343.tar.bz2 busybox-w32-255ebaf535c9f6d8a88e23d55d8be04b0ea73343.zip |
drop: adjust environment on privilege change
Some environment variables are subject to special treatment: USER,
LOGNAME, HOME and SHELL are initialised when the shell starts if
they don't already have a value.
Some adjustments are necessary when changing privilege level:
- USERNAME is added to the set of variables subject to special
treatment. Unlike the others this is normally set on Windows.
- The special variables are now also updated on shell start up if
the current process is running with elevated privileges. This is
necessary so USER, USERNAME and LOGNAME have the correct value.
- USER, USERNAME and LOGNAME are set to the name of the unprivileged
user when elevated privileges are dropped, though not if they've
been changed from the expected value of "root".
Costs 160-208 bytes.
(GitHub issue #300)
-rw-r--r-- | miscutils/drop.c | 16 | ||||
-rw-r--r-- | shell/ash.c | 11 |
2 files changed, 22 insertions, 5 deletions
diff --git a/miscutils/drop.c b/miscutils/drop.c index 6effc1831..db3d709d1 100644 --- a/miscutils/drop.c +++ b/miscutils/drop.c | |||
@@ -58,6 +58,18 @@ | |||
58 | #include <lazyload.h> | 58 | #include <lazyload.h> |
59 | #include "NUM_APPLETS.h" | 59 | #include "NUM_APPLETS.h" |
60 | 60 | ||
61 | // Set an environment variable to the name of the unprivileged user, | ||
62 | // but only if it was previously unset or contained "root". | ||
63 | static void setenv_name(const char *key) | ||
64 | { | ||
65 | const char *name = get_user_name(); | ||
66 | const char *oldname = getenv(key); | ||
67 | |||
68 | if (name && (!oldname || strcmp(oldname, "root") == 0)) { | ||
69 | setenv(key, name, 1); | ||
70 | } | ||
71 | } | ||
72 | |||
61 | int drop_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | 73 | int drop_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
62 | int drop_main(int argc, char **argv) | 74 | int drop_main(int argc, char **argv) |
63 | { | 75 | { |
@@ -166,6 +178,10 @@ int drop_main(int argc, char **argv) | |||
166 | si.hStdError = GetStdHandle(STD_ERROR_HANDLE); | 178 | si.hStdError = GetStdHandle(STD_ERROR_HANDLE); |
167 | si.dwFlags = STARTF_USESTDHANDLES; | 179 | si.dwFlags = STARTF_USESTDHANDLES; |
168 | 180 | ||
181 | setenv_name("USER"); | ||
182 | setenv_name("USERNAME"); | ||
183 | setenv_name("LOGNAME"); | ||
184 | |||
169 | if (!CreateProcessAsUserA(token, exe, cmd, NULL, NULL, TRUE, | 185 | if (!CreateProcessAsUserA(token, exe, cmd, NULL, NULL, TRUE, |
170 | 0, NULL, NULL, &si, &pi)) { | 186 | 0, NULL, NULL, &si, &pi)) { |
171 | xfunc_error_retval = 126; | 187 | xfunc_error_retval = 126; |
diff --git a/shell/ash.c b/shell/ash.c index d78c6e828..1eddec4ea 100644 --- a/shell/ash.c +++ b/shell/ash.c | |||
@@ -15550,7 +15550,7 @@ exitshell(void) | |||
15550 | # undef getenv | 15550 | # undef getenv |
15551 | static void xsetenv_if_unset(const char *key, const char *value) | 15551 | static void xsetenv_if_unset(const char *key, const char *value) |
15552 | { | 15552 | { |
15553 | if (!getenv(key)) | 15553 | if (!getenv(key) || getuid() == 0) |
15554 | xsetenv(key, value); | 15554 | xsetenv(key, value); |
15555 | } | 15555 | } |
15556 | #endif | 15556 | #endif |
@@ -15641,12 +15641,13 @@ init(void) | |||
15641 | } | 15641 | } |
15642 | 15642 | ||
15643 | /* Initialise some variables normally set at login, but | 15643 | /* Initialise some variables normally set at login, but |
15644 | * only if someone hasn't already set them. */ | 15644 | * only if someone hasn't already set them or we're root. */ |
15645 | pw = getpwuid(getuid()); | 15645 | pw = getpwuid(getuid()); |
15646 | if (pw) { | 15646 | if (pw) { |
15647 | xsetenv_if_unset("USER", pw->pw_name); | 15647 | xsetenv_if_unset("USER", pw->pw_name); |
15648 | xsetenv_if_unset("LOGNAME", pw->pw_name); | 15648 | xsetenv_if_unset("USERNAME", pw->pw_name); |
15649 | xsetenv_if_unset("HOME", pw->pw_dir); | 15649 | xsetenv_if_unset("LOGNAME", pw->pw_name); |
15650 | xsetenv_if_unset("HOME", pw->pw_dir); | ||
15650 | } | 15651 | } |
15651 | xsetenv_if_unset("SHELL", DEFAULT_SHELL); | 15652 | xsetenv_if_unset("SHELL", DEFAULT_SHELL); |
15652 | } | 15653 | } |