* Licensed under GPLv2 or later, see file LICENSE in this source tree.
*/
//config:config SU
-//config: bool "su"
+//config: bool "su (19 kb)"
//config: default y
//config: select FEATURE_SYSLOG
//config: help
-//config: su is used to become another user during a login session.
-//config: Invoked without a username, su defaults to becoming the super user.
-//config:
-//config: Note that Busybox binary must be setuid root for this applet to
-//config: work properly.
+//config: su is used to become another user during a login session.
+//config: Invoked without a username, su defaults to becoming the super user.
+//config: Note that busybox binary must be setuid root for this applet to
+//config: work properly.
//config:
//config:config FEATURE_SU_SYSLOG
-//config: bool "Enable su to write to syslog"
+//config: bool "Log to syslog all attempts to use su"
//config: default y
//config: depends on SU
//config:
//config:config FEATURE_SU_CHECKS_SHELLS
-//config: bool "Enable su to check user's shell to be listed in /etc/shells"
-//config: depends on SU
+//config: bool "If user's shell is not in /etc/shells, disallow -s PROG"
//config: default y
+//config: depends on SU
+//config:
+//config:config FEATURE_SU_BLANK_PW_NEEDS_SECURE_TTY
+//config: bool "Allow blank passwords only on TTYs in /etc/securetty"
+//config: default n
+//config: depends on SU
//applet:/* Needs to be run by root or be suid root - needs to change uid and gid: */
//applet:IF_SU(APPLET(su, BB_DIR_BIN, BB_SUID_REQUIRE))
char user_buf[64];
#endif
const char *old_user;
+ int r;
/* Note: we don't use "'+': stop at first non-option" idiom here.
* For su, "SCRIPT ARGS" or "-c CMD ARGS" do not stop option parsing:
argv++;
}
+ tty = xmalloc_ttyname(STDIN_FILENO);
+ if (!tty)
+ tty = "none";
+ tty = skip_dev_pfx(tty);
+
if (ENABLE_FEATURE_SU_SYSLOG) {
/* The utmp entry (via getlogin) is probably the best way to
* identify the user, especially if someone su's from a su-shell.
pw = getpwuid(cur_uid);
old_user = pw ? xstrdup(pw->pw_name) : "";
}
- tty = xmalloc_ttyname(2);
- if (!tty) {
- tty = "none";
- }
openlog(applet_name, 0, LOG_AUTH);
}
pw = xgetpwnam(opt_username);
- if (cur_uid == 0 || ask_and_check_password(pw) > 0) {
+ r = 1;
+ if (cur_uid != 0)
+ r = ask_and_check_password(pw);
+ if (r > 0) {
+ if (ENABLE_FEATURE_SU_BLANK_PW_NEEDS_SECURE_TTY
+ && r == CHECKPASS_PW_HAS_EMPTY_PASSWORD
+ && !is_tty_secure(tty)
+ ) {
+ goto fail;
+ }
if (ENABLE_FEATURE_SU_SYSLOG)
syslog(LOG_NOTICE, "%c %s %s:%s",
'+', tty, old_user, opt_username);
} else {
+ fail:
if (ENABLE_FEATURE_SU_SYSLOG)
syslog(LOG_NOTICE, "%c %s %s:%s",
'-', tty, old_user, opt_username);