summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/libbb.h18
-rw-r--r--libbb/setup_environment.c8
-rw-r--r--loginutils/sulogin.c23
3 files changed, 37 insertions, 12 deletions
diff --git a/include/libbb.h b/include/libbb.h
index daa3107..a0ffbef 100644
--- a/include/libbb.h
+++ b/include/libbb.h
@@ -1726,15 +1726,16 @@ extern void selinux_or_die(void) FAST_FUNC;
/* setup_environment:
- * if chdir pw->pw_dir: ok: else if to_tmp == 1: goto /tmp else: goto / or die
- * if clear_env = 1: cd(pw->pw_dir), clear environment, then set
+ * if !SETUP_ENV_NO_CHDIR:
+ * if cd(pw->pw_dir): ok: else if SETUP_ENV_TO_TMP: cd(/tmp) else: cd(/) or die
+ * if SETUP_ENV_CLEARENV: cd(pw->pw_dir), clear environment, then set
* TERM=(old value)
* USER=pw->pw_name, LOGNAME=pw->pw_name
* PATH=bb_default_[root_]path
* HOME=pw->pw_dir
* SHELL=shell
- * else if change_env = 1:
- * if not root (if pw->pw_uid != 0):
+ * else if SETUP_ENV_CHANGEENV:
+ * if not root (if pw->pw_uid != 0) or if SETUP_ENV_CHANGEENV_LOGNAME:
* USER=pw->pw_name, LOGNAME=pw->pw_name
* HOME=pw->pw_dir
* SHELL=shell
@@ -1743,10 +1744,11 @@ extern void selinux_or_die(void) FAST_FUNC;
* NB: CHANGEENV and CLEARENV use setenv() - this leaks memory!
* If setup_environment() is used is vforked child, this leaks memory _in parent too_!
*/
-#define SETUP_ENV_CHANGEENV (1 << 0)
-#define SETUP_ENV_CLEARENV (1 << 1)
-#define SETUP_ENV_TO_TMP (1 << 2)
-#define SETUP_ENV_NO_CHDIR (1 << 4)
+#define SETUP_ENV_CHANGEENV (1 << 0)
+#define SETUP_ENV_CHANGEENV_LOGNAME (1 << 1)
+#define SETUP_ENV_CLEARENV (1 << 2)
+#define SETUP_ENV_TO_TMP (1 << 3)
+#define SETUP_ENV_NO_CHDIR (1 << 4)
void setup_environment(const char *shell, int flags, const struct passwd *pw) FAST_FUNC;
void nuke_str(char *str) FAST_FUNC;
#if ENABLE_FEATURE_SECURETTY && !ENABLE_PAM
diff --git a/libbb/setup_environment.c b/libbb/setup_environment.c
index f8de449..df29839 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
xsetenv("TERM", term);
xsetenv("PATH", (pw->pw_uid ? bb_default_path : bb_default_root_path));
goto shortcut;
- // No, gcc (4.2.1) is not clever enougn to do it itself.
+ // No, gcc (4.2.1) is not clever enough to do it itself.
//xsetenv("USER", pw->pw_name);
//xsetenv("LOGNAME", pw->pw_name);
//xsetenv("HOME", pw->pw_dir);
//xsetenv("SHELL", shell);
} else if (flags & SETUP_ENV_CHANGEENV) {
- /* Set HOME, SHELL, and if not becoming a super-user,
- * USER and LOGNAME. */
- if (pw->pw_uid) {
+ /* Set HOME, SHELL, and if not becoming a super-user
+ * or if SETUP_ENV_CHANGEENV_LOGNAME, USER and LOGNAME. */
+ if ((flags & SETUP_ENV_CHANGEENV_LOGNAME) || pw->pw_uid != 0) {
shortcut:
xsetenv("USER", pw->pw_name);
xsetenv("LOGNAME", pw->pw_name);
diff --git a/loginutils/sulogin.c b/loginutils/sulogin.c
index 69d8b5e..5f1c117 100644
--- a/loginutils/sulogin.c
+++ b/loginutils/sulogin.c
@@ -28,6 +28,7 @@
int sulogin_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
int sulogin_main(int argc UNUSED_PARAM, char **argv)
{
+ int tsid;
int timeout = 0;
struct passwd *pwd;
const char *shell;
@@ -88,6 +89,28 @@ int sulogin_main(int argc UNUSED_PARAM, char **argv)
if (!shell)
shell = pwd->pw_shell;
+ /* util-linux 2.36.1 compat: cd to root's HOME, set a few envvars */
+ setup_environment(shell, SETUP_ENV_CHANGEENV | SETUP_ENV_CHANGEENV_LOGNAME, pwd);
+ // no SETUP_ENV_CLEARENV
+ // SETUP_ENV_CHANGEENV[+LOGNAME] - set HOME, SHELL, USER,and LOGNAME
+ // no SETUP_ENV_NO_CHDIR - IOW: cd to $HOME
+
+ /* util-linux 2.36.1 compat: steal ctty if we don't have it yet
+ * (yes, util-linux uses force=1) */
+ tsid = tcgetsid(STDIN_FILENO);
+ if (tsid < 0 || getpid() != tsid) {
+ if (ioctl(STDIN_FILENO, TIOCSCTTY, /*force:*/ (long)1) != 0) {
+// bb_perror_msg("TIOCSCTTY1 tsid:%d", tsid);
+ if (setsid() > 0) {
+// bb_error_msg("done setsid()");
+ /* If it still does not work, ignore */
+ if (ioctl(STDIN_FILENO, TIOCSCTTY, /*force:*/ (long)1) != 0) {
+// bb_perror_msg("TIOCSCTTY2 tsid:%d", tsid);
+ }
+ }
+ }
+ }
+
/* Exec login shell with no additional parameters. Never returns. */
exec_login_shell(shell);
}