diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2022-01-12 23:19:11 +0100 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2022-01-12 23:19:11 +0100 |
commit | d162a7b978a98b910e410dc10a40d5de12db0419 (patch) | |
tree | 63271dbbe027b26692befba9944d0554b00968d0 | |
parent | 004cefa918483513a9eca13e7701c74dff160e95 (diff) | |
download | busybox-w32-d162a7b978a98b910e410dc10a40d5de12db0419.tar.gz busybox-w32-d162a7b978a98b910e410dc10a40d5de12db0419.tar.bz2 busybox-w32-d162a7b978a98b910e410dc10a40d5de12db0419.zip |
sulogin: increase util-linux compatibility
Change to root's HOME. Set some envvars. Steal ctty if necessary and possible.
function old new delta
sulogin_main 240 340 +100
setup_environment 225 233 +8
su_main 479 474 -5
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 2/1 up/down: 108/-5) Total: 103 bytes
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r-- | include/libbb.h | 18 | ||||
-rw-r--r-- | libbb/setup_environment.c | 8 | ||||
-rw-r--r-- | loginutils/sulogin.c | 23 |
3 files changed, 37 insertions, 12 deletions
diff --git a/include/libbb.h b/include/libbb.h index daa310776..a0ffbef62 100644 --- a/include/libbb.h +++ b/include/libbb.h | |||
@@ -1726,15 +1726,16 @@ extern void selinux_or_die(void) FAST_FUNC; | |||
1726 | 1726 | ||
1727 | 1727 | ||
1728 | /* setup_environment: | 1728 | /* setup_environment: |
1729 | * if chdir pw->pw_dir: ok: else if to_tmp == 1: goto /tmp else: goto / or die | 1729 | * if !SETUP_ENV_NO_CHDIR: |
1730 | * if clear_env = 1: cd(pw->pw_dir), clear environment, then set | 1730 | * if cd(pw->pw_dir): ok: else if SETUP_ENV_TO_TMP: cd(/tmp) else: cd(/) or die |
1731 | * if SETUP_ENV_CLEARENV: cd(pw->pw_dir), clear environment, then set | ||
1731 | * TERM=(old value) | 1732 | * TERM=(old value) |
1732 | * USER=pw->pw_name, LOGNAME=pw->pw_name | 1733 | * USER=pw->pw_name, LOGNAME=pw->pw_name |
1733 | * PATH=bb_default_[root_]path | 1734 | * PATH=bb_default_[root_]path |
1734 | * HOME=pw->pw_dir | 1735 | * HOME=pw->pw_dir |
1735 | * SHELL=shell | 1736 | * SHELL=shell |
1736 | * else if change_env = 1: | 1737 | * else if SETUP_ENV_CHANGEENV: |
1737 | * if not root (if pw->pw_uid != 0): | 1738 | * if not root (if pw->pw_uid != 0) or if SETUP_ENV_CHANGEENV_LOGNAME: |
1738 | * USER=pw->pw_name, LOGNAME=pw->pw_name | 1739 | * USER=pw->pw_name, LOGNAME=pw->pw_name |
1739 | * HOME=pw->pw_dir | 1740 | * HOME=pw->pw_dir |
1740 | * SHELL=shell | 1741 | * SHELL=shell |
@@ -1743,10 +1744,11 @@ extern void selinux_or_die(void) FAST_FUNC; | |||
1743 | * NB: CHANGEENV and CLEARENV use setenv() - this leaks memory! | 1744 | * NB: CHANGEENV and CLEARENV use setenv() - this leaks memory! |
1744 | * If setup_environment() is used is vforked child, this leaks memory _in parent too_! | 1745 | * If setup_environment() is used is vforked child, this leaks memory _in parent too_! |
1745 | */ | 1746 | */ |
1746 | #define SETUP_ENV_CHANGEENV (1 << 0) | 1747 | #define SETUP_ENV_CHANGEENV (1 << 0) |
1747 | #define SETUP_ENV_CLEARENV (1 << 1) | 1748 | #define SETUP_ENV_CHANGEENV_LOGNAME (1 << 1) |
1748 | #define SETUP_ENV_TO_TMP (1 << 2) | 1749 | #define SETUP_ENV_CLEARENV (1 << 2) |
1749 | #define SETUP_ENV_NO_CHDIR (1 << 4) | 1750 | #define SETUP_ENV_TO_TMP (1 << 3) |
1751 | #define SETUP_ENV_NO_CHDIR (1 << 4) | ||
1750 | void setup_environment(const char *shell, int flags, const struct passwd *pw) FAST_FUNC; | 1752 | void setup_environment(const char *shell, int flags, const struct passwd *pw) FAST_FUNC; |
1751 | void nuke_str(char *str) FAST_FUNC; | 1753 | void nuke_str(char *str) FAST_FUNC; |
1752 | #if ENABLE_FEATURE_SECURETTY && !ENABLE_PAM | 1754 | #if ENABLE_FEATURE_SECURETTY && !ENABLE_PAM |
diff --git a/libbb/setup_environment.c b/libbb/setup_environment.c index f8de44967..df2983958 100644 --- a/libbb/setup_environment.c +++ b/libbb/setup_environment.c | |||
@@ -54,15 +54,15 @@ void FAST_FUNC setup_environment(const char *shell, int flags, const struct pass | |||
54 | xsetenv("TERM", term); | 54 | xsetenv("TERM", term); |
55 | xsetenv("PATH", (pw->pw_uid ? bb_default_path : bb_default_root_path)); | 55 | xsetenv("PATH", (pw->pw_uid ? bb_default_path : bb_default_root_path)); |
56 | goto shortcut; | 56 | goto shortcut; |
57 | // No, gcc (4.2.1) is not clever enougn to do it itself. | 57 | // No, gcc (4.2.1) is not clever enough to do it itself. |
58 | //xsetenv("USER", pw->pw_name); | 58 | //xsetenv("USER", pw->pw_name); |
59 | //xsetenv("LOGNAME", pw->pw_name); | 59 | //xsetenv("LOGNAME", pw->pw_name); |
60 | //xsetenv("HOME", pw->pw_dir); | 60 | //xsetenv("HOME", pw->pw_dir); |
61 | //xsetenv("SHELL", shell); | 61 | //xsetenv("SHELL", shell); |
62 | } else if (flags & SETUP_ENV_CHANGEENV) { | 62 | } else if (flags & SETUP_ENV_CHANGEENV) { |
63 | /* Set HOME, SHELL, and if not becoming a super-user, | 63 | /* Set HOME, SHELL, and if not becoming a super-user |
64 | * USER and LOGNAME. */ | 64 | * or if SETUP_ENV_CHANGEENV_LOGNAME, USER and LOGNAME. */ |
65 | if (pw->pw_uid) { | 65 | if ((flags & SETUP_ENV_CHANGEENV_LOGNAME) || pw->pw_uid != 0) { |
66 | shortcut: | 66 | shortcut: |
67 | xsetenv("USER", pw->pw_name); | 67 | xsetenv("USER", pw->pw_name); |
68 | xsetenv("LOGNAME", pw->pw_name); | 68 | xsetenv("LOGNAME", pw->pw_name); |
diff --git a/loginutils/sulogin.c b/loginutils/sulogin.c index 69d8b5ec7..5f1c1178f 100644 --- a/loginutils/sulogin.c +++ b/loginutils/sulogin.c | |||
@@ -28,6 +28,7 @@ | |||
28 | int sulogin_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | 28 | int sulogin_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
29 | int sulogin_main(int argc UNUSED_PARAM, char **argv) | 29 | int sulogin_main(int argc UNUSED_PARAM, char **argv) |
30 | { | 30 | { |
31 | int tsid; | ||
31 | int timeout = 0; | 32 | int timeout = 0; |
32 | struct passwd *pwd; | 33 | struct passwd *pwd; |
33 | const char *shell; | 34 | const char *shell; |
@@ -88,6 +89,28 @@ int sulogin_main(int argc UNUSED_PARAM, char **argv) | |||
88 | if (!shell) | 89 | if (!shell) |
89 | shell = pwd->pw_shell; | 90 | shell = pwd->pw_shell; |
90 | 91 | ||
92 | /* util-linux 2.36.1 compat: cd to root's HOME, set a few envvars */ | ||
93 | setup_environment(shell, SETUP_ENV_CHANGEENV | SETUP_ENV_CHANGEENV_LOGNAME, pwd); | ||
94 | // no SETUP_ENV_CLEARENV | ||
95 | // SETUP_ENV_CHANGEENV[+LOGNAME] - set HOME, SHELL, USER,and LOGNAME | ||
96 | // no SETUP_ENV_NO_CHDIR - IOW: cd to $HOME | ||
97 | |||
98 | /* util-linux 2.36.1 compat: steal ctty if we don't have it yet | ||
99 | * (yes, util-linux uses force=1) */ | ||
100 | tsid = tcgetsid(STDIN_FILENO); | ||
101 | if (tsid < 0 || getpid() != tsid) { | ||
102 | if (ioctl(STDIN_FILENO, TIOCSCTTY, /*force:*/ (long)1) != 0) { | ||
103 | // bb_perror_msg("TIOCSCTTY1 tsid:%d", tsid); | ||
104 | if (setsid() > 0) { | ||
105 | // bb_error_msg("done setsid()"); | ||
106 | /* If it still does not work, ignore */ | ||
107 | if (ioctl(STDIN_FILENO, TIOCSCTTY, /*force:*/ (long)1) != 0) { | ||
108 | // bb_perror_msg("TIOCSCTTY2 tsid:%d", tsid); | ||
109 | } | ||
110 | } | ||
111 | } | ||
112 | } | ||
113 | |||
91 | /* Exec login shell with no additional parameters. Never returns. */ | 114 | /* Exec login shell with no additional parameters. Never returns. */ |
92 | exec_login_shell(shell); | 115 | exec_login_shell(shell); |
93 | } | 116 | } |