diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2017-04-13 12:57:04 +0200 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2017-04-13 12:57:04 +0200 |
commit | 335681ca8e39144fa19814f7ba10d0fe760e4055 (patch) | |
tree | 81c20a0be3daab564c842f510126037bf2331ab2 /loginutils | |
parent | 517a82c5b6b5e279f3e96a6774445a2952ca312b (diff) | |
download | busybox-w32-335681ca8e39144fa19814f7ba10d0fe760e4055.tar.gz busybox-w32-335681ca8e39144fa19814f7ba10d0fe760e4055.tar.bz2 busybox-w32-335681ca8e39144fa19814f7ba10d0fe760e4055.zip |
su: FEATURE_SU_BLANK_PW_NEEDS_SECURE_TTY
When this feature is enabled, blank passwords are not accepted by su
unless the user is on a secure TTY defined in /etc/securetty. This
resembles the default PAM configuration of some Linux distros which
specify the nullok_secure option for pam_unix.so.
Based on patch by Kaarle Ritvanen <kaarle.ritvanen@datakunkku.fi>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'loginutils')
-rw-r--r-- | loginutils/su.c | 27 |
1 files changed, 22 insertions, 5 deletions
diff --git a/loginutils/su.c b/loginutils/su.c index d04b85fb1..f2cd799ae 100644 --- a/loginutils/su.c +++ b/loginutils/su.c | |||
@@ -23,6 +23,11 @@ | |||
23 | //config: bool "If user's shell is not in /etc/shells, disallow -s PROG" | 23 | //config: bool "If user's shell is not in /etc/shells, disallow -s PROG" |
24 | //config: default y | 24 | //config: default y |
25 | //config: depends on SU | 25 | //config: depends on SU |
26 | //config: | ||
27 | //config:config FEATURE_SU_BLANK_PW_NEEDS_SECURE_TTY | ||
28 | //config: bool "Disallow blank passwords from TTYs other than specified in /etc/securetty" | ||
29 | //config: default n | ||
30 | //config: depends on SU | ||
26 | 31 | ||
27 | //applet:/* Needs to be run by root or be suid root - needs to change uid and gid: */ | 32 | //applet:/* Needs to be run by root or be suid root - needs to change uid and gid: */ |
28 | //applet:IF_SU(APPLET(su, BB_DIR_BIN, BB_SUID_REQUIRE)) | 33 | //applet:IF_SU(APPLET(su, BB_DIR_BIN, BB_SUID_REQUIRE)) |
@@ -79,6 +84,7 @@ int su_main(int argc UNUSED_PARAM, char **argv) | |||
79 | char user_buf[64]; | 84 | char user_buf[64]; |
80 | #endif | 85 | #endif |
81 | const char *old_user; | 86 | const char *old_user; |
87 | int r; | ||
82 | 88 | ||
83 | /* Note: we don't use "'+': stop at first non-option" idiom here. | 89 | /* Note: we don't use "'+': stop at first non-option" idiom here. |
84 | * For su, "SCRIPT ARGS" or "-c CMD ARGS" do not stop option parsing: | 90 | * For su, "SCRIPT ARGS" or "-c CMD ARGS" do not stop option parsing: |
@@ -99,6 +105,11 @@ int su_main(int argc UNUSED_PARAM, char **argv) | |||
99 | argv++; | 105 | argv++; |
100 | } | 106 | } |
101 | 107 | ||
108 | tty = xmalloc_ttyname(STDIN_FILENO); | ||
109 | if (!tty) | ||
110 | tty = "none"; | ||
111 | tty = skip_dev_pfx(tty); | ||
112 | |||
102 | if (ENABLE_FEATURE_SU_SYSLOG) { | 113 | if (ENABLE_FEATURE_SU_SYSLOG) { |
103 | /* The utmp entry (via getlogin) is probably the best way to | 114 | /* The utmp entry (via getlogin) is probably the best way to |
104 | * identify the user, especially if someone su's from a su-shell. | 115 | * identify the user, especially if someone su's from a su-shell. |
@@ -112,20 +123,26 @@ int su_main(int argc UNUSED_PARAM, char **argv) | |||
112 | pw = getpwuid(cur_uid); | 123 | pw = getpwuid(cur_uid); |
113 | old_user = pw ? xstrdup(pw->pw_name) : ""; | 124 | old_user = pw ? xstrdup(pw->pw_name) : ""; |
114 | } | 125 | } |
115 | tty = xmalloc_ttyname(2); | ||
116 | if (!tty) { | ||
117 | tty = "none"; | ||
118 | } | ||
119 | openlog(applet_name, 0, LOG_AUTH); | 126 | openlog(applet_name, 0, LOG_AUTH); |
120 | } | 127 | } |
121 | 128 | ||
122 | pw = xgetpwnam(opt_username); | 129 | pw = xgetpwnam(opt_username); |
123 | 130 | ||
124 | if (cur_uid == 0 || ask_and_check_password(pw) > 0) { | 131 | r = 1; |
132 | if (cur_uid != 0) | ||
133 | r = ask_and_check_password(pw); | ||
134 | if (r > 0) { | ||
135 | if (ENABLE_FEATURE_SU_BLANK_PW_NEEDS_SECURE_TTY | ||
136 | && r == CHECKPASS_PW_HAS_EMPTY_PASSWORD | ||
137 | && !check_securetty(tty) | ||
138 | ) { | ||
139 | goto fail; | ||
140 | } | ||
125 | if (ENABLE_FEATURE_SU_SYSLOG) | 141 | if (ENABLE_FEATURE_SU_SYSLOG) |
126 | syslog(LOG_NOTICE, "%c %s %s:%s", | 142 | syslog(LOG_NOTICE, "%c %s %s:%s", |
127 | '+', tty, old_user, opt_username); | 143 | '+', tty, old_user, opt_username); |
128 | } else { | 144 | } else { |
145 | fail: | ||
129 | if (ENABLE_FEATURE_SU_SYSLOG) | 146 | if (ENABLE_FEATURE_SU_SYSLOG) |
130 | syslog(LOG_NOTICE, "%c %s %s:%s", | 147 | syslog(LOG_NOTICE, "%c %s %s:%s", |
131 | '-', tty, old_user, opt_username); | 148 | '-', tty, old_user, opt_username); |