+ username[0] = '\0';
+ }
+
+ alarm(0);
+ die_if_nologin_and_non_root(pw->pw_uid == 0);
+
+ write_utent(username);
+
+#ifdef CONFIG_SELINUX
+ if (is_selinux_enabled()) {
+ security_context_t old_tty_sid, new_tty_sid;
+
+ if (get_default_context(username, NULL, &user_sid)) {
+ bb_error_msg_and_die("cannot get SID for %s",
+ username);
+ }
+ if (getfilecon(full_tty, &old_tty_sid) < 0) {
+ bb_perror_msg_and_die("getfilecon(%s) failed",
+ full_tty);
+ }
+ if (security_compute_relabel(user_sid, old_tty_sid,
+ SECCLASS_CHR_FILE, &new_tty_sid) != 0) {
+ bb_perror_msg_and_die("security_change_sid(%s) failed",
+ full_tty);
+ }
+ if (setfilecon(full_tty, new_tty_sid) != 0) {
+ bb_perror_msg_and_die("chsid(%s, %s) failed",
+ full_tty, new_tty_sid);
+ }
+ }
+#endif
+ /* Try these, but don't complain if they fail.
+ * _f_chown is safe wrt race t=ttyname(0);...;chown(t); */
+ fchown(0, pw->pw_uid, pw->pw_gid);
+ fchmod(0, 0600);
+
+ /* TODO: be nommu-friendly, use spawn? */
+ if (ENABLE_LOGIN_SCRIPTS) {
+ char *script = getenv("LOGIN_PRE_SUID_SCRIPT");
+ if (script) {
+ char *t_argv[2] = { script, NULL };
+ switch (fork()) {
+ case -1: break;
+ case 0: /* child */
+ xchdir("/");
+ setenv("LOGIN_TTY", full_tty, 1);
+ setenv("LOGIN_USER", pw->pw_name, 1);
+ setenv("LOGIN_UID", utoa(pw->pw_uid), 1);
+ setenv("LOGIN_GID", utoa(pw->pw_gid), 1);
+ setenv("LOGIN_SHELL", pw->pw_shell, 1);
+ execvp(script, t_argv);
+ exit(1);
+ default: /* parent */
+ wait(NULL);
+ }