aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--loginutils/login.c102
1 files changed, 56 insertions, 46 deletions
diff --git a/loginutils/login.c b/loginutils/login.c
index af871436a..d9e9b532b 100644
--- a/loginutils/login.c
+++ b/loginutils/login.c
@@ -165,6 +165,56 @@ static int check_securetty(void)
165static ALWAYS_INLINE int check_securetty(void) { return 1; } 165static ALWAYS_INLINE int check_securetty(void) { return 1; }
166#endif 166#endif
167 167
168#if ENABLE_SELINUX
169static void initselinux(char *username, char *full_tty,
170 security_context_t *user_sid)
171{
172 security_context_t old_tty_sid, new_tty_sid;
173
174 if (!is_selinux_enabled())
175 return;
176
177 if (get_default_context(username, NULL, user_sid)) {
178 bb_error_msg_and_die("cannot get SID for %s", username);
179 }
180 if (getfilecon(full_tty, &old_tty_sid) < 0) {
181 bb_perror_msg_and_die("getfilecon(%s) failed", full_tty);
182 }
183 if (security_compute_relabel(user_sid, old_tty_sid,
184 SECCLASS_CHR_FILE, &new_tty_sid) != 0) {
185 bb_perror_msg_and_die("security_change_sid(%s) failed", full_tty);
186 }
187 if (setfilecon(full_tty, new_tty_sid) != 0) {
188 bb_perror_msg_and_die("chsid(%s, %s) failed", full_tty, new_tty_sid);
189 }
190}
191#endif
192
193#if ENABLE_LOGIN_SCRIPTS
194static void run_login_script(struct passwd *pw, char *full_tty)
195{
196 char *t_argv[2];
197
198 t_argv[0] = getenv("LOGIN_PRE_SUID_SCRIPT");
199 if (t_argv[0]) {
200 t_argv[1] = NULL;
201 xsetenv("LOGIN_TTY", full_tty);
202 xsetenv("LOGIN_USER", pw->pw_name);
203 xsetenv("LOGIN_UID", utoa(pw->pw_uid));
204 xsetenv("LOGIN_GID", utoa(pw->pw_gid));
205 xsetenv("LOGIN_SHELL", pw->pw_shell);
206 spawn_and_wait(t_argv); /* NOMMU-friendly */
207 unsetenv("LOGIN_TTY");
208 unsetenv("LOGIN_USER");
209 unsetenv("LOGIN_UID");
210 unsetenv("LOGIN_GID");
211 unsetenv("LOGIN_SHELL");
212 }
213}
214#else
215void run_login_script(struct passwd *pw, char *full_tty);
216#endif
217
168static void get_username_or_die(char *buf, int size_buf) 218static void get_username_or_die(char *buf, int size_buf)
169{ 219{
170 int c, cntdown; 220 int c, cntdown;
@@ -285,8 +335,7 @@ int login_main(int argc UNUSED_PARAM, char **argv)
285 read_or_build_utent(&utent, run_by_root); 335 read_or_build_utent(&utent, run_by_root);
286 336
287 if (opt & LOGIN_OPT_h) { 337 if (opt & LOGIN_OPT_h) {
288 if (ENABLE_FEATURE_UTMP) 338 USE_FEATURE_UTMP(safe_strncpy(utent.ut_host, opt_host, sizeof(utent.ut_host));)
289 safe_strncpy(utent.ut_host, opt_host, sizeof(utent.ut_host));
290 fromhost = xasprintf(" on '%s' from '%s'", short_tty, opt_host); 339 fromhost = xasprintf(" on '%s' from '%s'", short_tty, opt_host);
291 } else { 340 } else {
292 fromhost = xasprintf(" on '%s'", short_tty); 341 fromhost = xasprintf(" on '%s'", short_tty);
@@ -410,54 +459,16 @@ int login_main(int argc UNUSED_PARAM, char **argv)
410 459
411 write_utent(&utent, username); 460 write_utent(&utent, username);
412 461
413#if ENABLE_SELINUX 462 USE_SELINUX(initselinux(username, full_tty, &user_sid));
414 if (is_selinux_enabled()) {
415 security_context_t old_tty_sid, new_tty_sid;
416 463
417 if (get_default_context(username, NULL, &user_sid)) {
418 bb_error_msg_and_die("cannot get SID for %s",
419 username);
420 }
421 if (getfilecon(full_tty, &old_tty_sid) < 0) {
422 bb_perror_msg_and_die("getfilecon(%s) failed",
423 full_tty);
424 }
425 if (security_compute_relabel(user_sid, old_tty_sid,
426 SECCLASS_CHR_FILE, &new_tty_sid) != 0) {
427 bb_perror_msg_and_die("security_change_sid(%s) failed",
428 full_tty);
429 }
430 if (setfilecon(full_tty, new_tty_sid) != 0) {
431 bb_perror_msg_and_die("chsid(%s, %s) failed",
432 full_tty, new_tty_sid);
433 }
434 }
435#endif
436 /* Try these, but don't complain if they fail. 464 /* Try these, but don't complain if they fail.
437 * _f_chown is safe wrt race t=ttyname(0);...;chown(t); */ 465 * _f_chown is safe wrt race t=ttyname(0);...;chown(t); */
438 fchown(0, pw->pw_uid, pw->pw_gid); 466 fchown(0, pw->pw_uid, pw->pw_gid);
439 fchmod(0, 0600); 467 fchmod(0, 0600);
440 468
441 /* We trust environment only if we run by root */ 469 /* We trust environment only if we run by root */
442 if (ENABLE_LOGIN_SCRIPTS && run_by_root) { 470 if (ENABLE_LOGIN_SCRIPTS && run_by_root)
443 char *t_argv[2]; 471 run_login_script(pw, full_tty);
444
445 t_argv[0] = getenv("LOGIN_PRE_SUID_SCRIPT");
446 if (t_argv[0]) {
447 t_argv[1] = NULL;
448 xsetenv("LOGIN_TTY", full_tty);
449 xsetenv("LOGIN_USER", pw->pw_name);
450 xsetenv("LOGIN_UID", utoa(pw->pw_uid));
451 xsetenv("LOGIN_GID", utoa(pw->pw_gid));
452 xsetenv("LOGIN_SHELL", pw->pw_shell);
453 spawn_and_wait(t_argv); /* NOMMU-friendly */
454 unsetenv("LOGIN_TTY" );
455 unsetenv("LOGIN_USER" );
456 unsetenv("LOGIN_UID" );
457 unsetenv("LOGIN_GID" );
458 unsetenv("LOGIN_SHELL");
459 }
460 }
461 472
462 change_identity(pw); 473 change_identity(pw);
463 tmp = pw->pw_shell; 474 tmp = pw->pw_shell;
@@ -470,11 +481,10 @@ int login_main(int argc UNUSED_PARAM, char **argv)
470 481
471 if (pw->pw_uid == 0) 482 if (pw->pw_uid == 0)
472 syslog(LOG_INFO, "root login%s", fromhost); 483 syslog(LOG_INFO, "root login%s", fromhost);
473#if ENABLE_SELINUX 484
474 /* well, a simple setexeccon() here would do the job as well, 485 /* well, a simple setexeccon() here would do the job as well,
475 * but let's play the game for now */ 486 * but let's play the game for now */
476 set_current_security_context(user_sid); 487 USE_SELINUX(set_current_security_context(user_sid);)
477#endif
478 488
479 // util-linux login also does: 489 // util-linux login also does:
480 // /* start new session */ 490 // /* start new session */