Exemple #1
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;

	/*
	 *	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;
}