int main(int argc, char **argv) { char *tty = NULL; char *p; struct passwd *pwd; int c, fd = -1; int opt_e = 0; pid_t pid, pgrp, ppgrp, ttypgrp; /* * See if we have a timeout flag. */ opterr = 0; while((c = getopt(argc, argv, "ept:")) != EOF) switch(c) { case 't': timeout = atoi(optarg); break; case 'p': profile = 1; break; case 'e': opt_e = 1; break; default: usage(); /* Do not exit! */ break; } #if 0 if (geteuid() != 0) { fprintf(stderr, "sulogin: only root can run sulogin.\n"); exit(1); } #endif /* * See if we need to open an other tty device. */ saved_sigint = signal(SIGINT, SIG_IGN); saved_sigtstp = signal(SIGQUIT, SIG_IGN); saved_sigquit = signal(SIGTSTP, SIG_IGN); if (optind < argc) tty = argv[optind]; if (tty || (tty = getenv("CONSOLE"))) { if ((fd = open(tty, O_RDWR)) < 0) { perror(tty); fd = dup(0); } if (!isatty(fd)) { fprintf(stderr, "%s: not a tty\n", tty); close(fd); } else { /* * Only go through this trouble if the new * tty doesn't fall in this process group. */ pid = getpid(); pgrp = getpgid(0); ppgrp = getpgid(getppid()); ttypgrp = tcgetpgrp(fd); if (pgrp != ttypgrp && ppgrp != ttypgrp) { if (pid != getsid(0)) { if (pid == getpgid(0)) setpgid(0, getpgid(getppid())); setsid(); } signal(SIGHUP, SIG_IGN); if (ttypgrp > 0) ioctl(0, TIOCNOTTY, (char *)1); signal(SIGHUP, SIG_DFL); close(0); close(1); close(2); if (fd > 2) close(fd); if ((fd = open(tty, O_RDWR|O_NOCTTY)) < 0) { perror(tty); } else { ioctl(0, TIOCSCTTY, (char *)1); tcsetpgrp(fd, ppgrp); dup2(fd, 0); dup2(fd, 1); dup2(fd, 2); if (fd > 2) close(fd); } } else if (fd > 2) close(fd); } } else if (getpid() == 1) { /* We are init. We hence need to set a session anyway */ setsid(); if (ioctl(0, TIOCSCTTY, (char *)1)) perror("ioctl(TIOCSCTTY)"); } #if defined(SANE_TIO) && (SANE_TIO == 1) fixtty(); #endif /* * Get the root password. */ if ((pwd = getrootpwent(opt_e)) == NULL) { fprintf(stderr, "sulogin: cannot open password database!\n"); sleep(2); } sushell(pwd); /* * Ask for the password. */ while(pwd) { if ((p = getpasswd(pwd->pw_passwd)) == NULL) break; if (pwd->pw_passwd[0] == 0 || strcmp(crypt(p, pwd->pw_passwd), pwd->pw_passwd) == 0) sushell(pwd); saved_sigquit = signal(SIGQUIT, SIG_IGN); saved_sigtstp = signal(SIGTSTP, SIG_IGN); saved_sigint = signal(SIGINT, SIG_IGN); printf("Login incorrect.\n"); } /* * User pressed Control-D. */ return 0; }
int main(int argc, char **argv) { char *tty = NULL; char *p; struct passwd *pwd; int c, fd = -1; int opt_e = 0; pid_t pid, pgrp, ppgrp, ttypgrp; struct sigaction saved_sighup; static const struct option longopts[] = { { "login-shell", 0, 0, 'p' }, { "timeout", 1, 0, 't' }, { "force", 0, 0, 'e' }, { "help", 0, 0, 'h' }, { "version", 0, 0, 'V' }, { NULL, 0, 0, 0 } }; setlocale(LC_ALL, ""); bindtextdomain(PACKAGE, LOCALEDIR); textdomain(PACKAGE); atexit(close_stdout); /* * See if we have a timeout flag. */ while ((c = getopt_long(argc, argv, "ehpt:V", longopts, NULL)) != -1) { switch(c) { case 't': timeout = strtou32_or_err(optarg, _("invalid timeout argument")); break; case 'p': profile = 1; break; case 'e': opt_e = 1; break; case 'V': printf(UTIL_LINUX_VERSION); return EXIT_SUCCESS; case 'h': usage(stdout); return EXIT_SUCCESS; default: usage(stderr); /* Do not exit! */ break; } } if (geteuid() != 0) errx(EXIT_FAILURE, _("only root can run this program.")); /* * See if we need to open an other tty device. */ mask_signal(SIGQUIT, SIG_IGN, &saved_sigquit); mask_signal(SIGTSTP, SIG_IGN, &saved_sigtstp); mask_signal(SIGINT, SIG_IGN, &saved_sigint); if (optind < argc) tty = argv[optind]; if (tty || (tty = getenv("CONSOLE"))) { if ((fd = open(tty, O_RDWR)) < 0) { warn(_("cannot open %s"), tty); fd = dup(0); } if (!isatty(fd)) { warn(_("%s: not a tty"), tty); close(fd); } else { /* * Only go through this trouble if the new tty doesn't * fall in this process group. */ pid = getpid(); pgrp = getpgid(0); ppgrp = getpgid(getppid()); ttypgrp = tcgetpgrp(fd); if (pgrp != ttypgrp && ppgrp != ttypgrp) { if (pid != getsid(0)) { if (pid == getpgid(0)) setpgid(0, getpgid(getppid())); setsid(); } sigaction(SIGHUP, NULL, &saved_sighup); if (ttypgrp > 0) ioctl(0, TIOCNOTTY, (char *)1); sigaction(SIGHUP, &saved_sighup, NULL); close(0); close(1); close(2); if (fd > 2) close(fd); if ((fd = open(tty, O_RDWR|O_NOCTTY)) < 0) warn(_("cannot open %s"), tty); else { ioctl(0, TIOCSCTTY, (char *)1); tcsetpgrp(fd, ppgrp); dup2(fd, 0); dup2(fd, 1); dup2(fd, 2); if (fd > 2) close(fd); } } else if (fd > 2) close(fd); } } else if (getpid() == 1) { /* We are init. We hence need to set a session anyway */ setsid(); if (ioctl(0, TIOCSCTTY, (char *)1)) warn(_("TIOCSCTTY: ioctl failed")); } fixtty(); /* * Get the root password. */ if ((pwd = getrootpwent(opt_e)) == NULL) { warnx(_("cannot open password database.")); sleep(2); } /* * Ask for the password. */ while (pwd) { if ((p = getpasswd(pwd->pw_passwd)) == NULL) break; if (pwd->pw_passwd[0] == 0 || strcmp(crypt(p, pwd->pw_passwd), pwd->pw_passwd) == 0) sushell(pwd); mask_signal(SIGQUIT, SIG_IGN, &saved_sigquit); mask_signal(SIGTSTP, SIG_IGN, &saved_sigtstp); mask_signal(SIGINT, SIG_IGN, &saved_sigint); fprintf(stderr, _("Login incorrect\n\n")); } /* * User pressed Control-D. */ return EXIT_SUCCESS; }