- if ( !is_my_tty ( full_tty ))
- syslog ( LOG_ERR, "unable to determine TTY name, got %s\n", full_tty );
-
- /* Try these, but don't complain if they fail
- * (for example when the root fs is read only) */
- chown ( full_tty, pw-> pw_uid, pw-> pw_gid );
- chmod ( full_tty, 0600 );
-
- change_identity ( pw );
- tmp = pw-> pw_shell;
- if(!tmp || !*tmp)
- tmp = DEFAULT_SHELL;
- setup_environment ( tmp, 1, !opt_preserve, pw );
-
- motd ( );
- signal ( SIGALRM, SIG_DFL ); /* default alarm signal */
-
- if ( pw-> pw_uid == 0 )
- syslog ( LOG_INFO, "root login %s\n", fromhost );
-#ifdef CONFIG_SELINUX
- set_current_security_context(sid);
-#endif
- run_shell ( tmp, 1, 0, 0); /* exec the shell finally. */
-
- return EXIT_FAILURE;
-}
-
-
-
-static int login_prompt ( char *buf_name )
-{
- char buf [1024];
- char *sp, *ep;
- int i;
-
- for(i=0; i<EMPTY_USERNAME_COUNT; i++) {
- print_login_prompt();
-
- if ( !fgets ( buf, sizeof( buf ) - 1, stdin ))
- return 0;
-
- if ( !strchr ( buf, '\n' ))
- return 0;
-
- for ( sp = buf; isspace ( *sp ); sp++ ) { }
- for ( ep = sp; isgraph ( *ep ); ep++ ) { }
-
- *ep = 0;
- safe_strncpy(buf_name, sp, USERNAME_SIZE);
- if(buf_name[0])
- return 1;
- }
- return 0;
-}
-
-
-static int check_nologin ( int amroot )
-{
- if ( access ( bb_path_nologin_file, F_OK ) == 0 ) {
- FILE *fp;
- int c;
-
- if (( fp = fopen ( bb_path_nologin_file, "r" ))) {
- while (( c = getc ( fp )) != EOF )
- putchar (( c == '\n' ) ? '\r' : c );
-
- fflush ( stdout );
- fclose ( fp );
- } else {
- puts ( "\r\nSystem closed for routine maintenance.\r" );
- }
- if ( !amroot )
- return 1;
-
- puts ( "\r\n[Disconnect bypassed -- root login allowed.]\r" );
- }
- return 0;
-}
-
-#ifdef CONFIG_FEATURE_SECURETTY
-
-static int check_tty ( const char *tty )
-{
- FILE *fp;
- int i;
- char buf[BUFSIZ];
-
- if (( fp = fopen ( bb_path_securetty_file, "r" ))) {
- while ( fgets ( buf, sizeof( buf ) - 1, fp )) {
- for ( i = bb_strlen( buf ) - 1; i >= 0; --i ) {
- if ( !isspace ( buf[i] ))
- break;
- }
- buf[++i] = '\0';
- if (( buf [0] == '\0' ) || ( buf [0] == '#' ))
- continue;
-
- if ( strcmp ( buf, tty ) == 0 ) {
- fclose ( fp );
- return 1;
+ /* 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);