Пример #1
0
const char *
stypeof(const char *ttyid)
{
	struct ttyent *t;

	return (ttyid && (t = getttynam(ttyid)) ? t->ty_type : NULL);
}
Пример #2
0
int
login_ttyok(login_cap_t *lc, const char *tty, const char *allowcap,
	    const char *denycap)
{
    int	    rc = 1;

    if (lc != NULL && tty != NULL && *tty != '\0') {
	struct ttyent	*te;
	char		*grp;
	char		**ttl;

	te = getttynam(tty);  /* Need group name */
	grp = te ? te->ty_group : NULL;
	ttl = login_getcaplist(lc, allowcap, NULL);

	if (ttl != NULL && !login_str2inlist(ttl, tty, grp, 0))
	    rc = 0;	/* tty or ttygroup not in allow list */
	else {

	    ttl = login_getcaplist(lc, denycap, NULL);
	    if (ttl != NULL && login_str2inlist(ttl, tty, grp, 0))
		rc = 0; /* tty or ttygroup in deny list */
	}
    }

    return rc;
}
Пример #3
0
static int
isttystat(const char *tty, int flag)
{
	struct ttyent *t;

	return ((t = getttynam(tty)) == NULL) ? 0 : !!(t->ty_status & flag);
}
Пример #4
0
int
rootterm(char *ttyn)
{
	struct ttyent *t;

	return ((t = getttynam(ttyn)) && t->ty_status & TTY_SECURE);
}
Пример #5
0
char *
stypeof(char *ttyid)
{
	struct ttyent *t;

	return (ttyid && (t = getttynam(ttyid)) ? t->ty_type :
	    login_getcapstr(lc, "term", UNKNOWN, UNKNOWN));
}
Пример #6
0
int
rootterm(char *ttyn)
{
	struct ttyent *t;

	/* XXX - stash output of getttynam() elsewhere */
	return ((t = getttynam(ttyn)) && t->ty_status & TTY_SECURE);
}
Пример #7
0
void testValues() {
    f = 2;
    
    struct ttyent * result = getttynam(anystring());
    if (result) {
        //@ assert valid_read_string_or_null(result->ty_name);
    }

    //@ assert f == 2;
    //@ assert vacuous: \false;
}
Пример #8
0
PAM_EXTERN int 
pam_sm_authenticate(pam_handle_t * pamh, int flags, int argc, const char **argv)
{
	struct options options;
	struct ttyent *ttyfileinfo;
	struct passwd *pwd;
	int retval;
	const char *user, *ttyname;

	pam_std_option(&options, NULL, argc, argv);

	PAM_LOG("Options processed");

	retval = pam_get_user(pamh, &user, NULL);
	if (retval != PAM_SUCCESS)
		PAM_RETURN(retval);

	PAM_LOG("Got user: %s", user);

	retval = pam_get_item(pamh, PAM_TTY, (const void **)&ttyname);
	if (retval != PAM_SUCCESS)
		PAM_RETURN(retval);

	PAM_LOG("Got TTY: %s", ttyname);

	/* Ignore any "/dev/" on the PAM_TTY item */
	if (strncmp(TTY_PREFIX, ttyname, sizeof(TTY_PREFIX) - 1) == 0)
		ttyname += sizeof(TTY_PREFIX) - 1;

	/* If the user is not root, secure ttys do not apply */
	pwd = getpwnam(user);
	if (pwd == NULL)
		PAM_RETURN(PAM_IGNORE);
	else if (pwd->pw_uid != 0)
		PAM_RETURN(PAM_SUCCESS);

	PAM_LOG("User is not root");

	ttyfileinfo = getttynam(ttyname);
	if (ttyfileinfo == NULL)
		PAM_RETURN(PAM_SERVICE_ERR);

	PAM_LOG("Got ttyfileinfo");

	if (ttyfileinfo->ty_status & TTY_SECURE)
		PAM_RETURN(PAM_SUCCESS);
	else {
		PAM_VERBOSE_ERROR("Not on secure TTY");
		PAM_RETURN(PAM_PERM_DENIED);
	}
}
Пример #9
0
/*
 * Change the specified ttys' flags.
 */
static int
change_ttys(char **ttylist)
{
	struct ttyent *tep;
	int rval;

	rval = 0;
	for (; *ttylist != NULL; ttylist++) {
		tep = getttynam(*ttylist);
		if (tep == NULL) {
			warnx("couldn't find an entry in %s for \"%s\"",
			    _PATH_TTYS, *ttylist);
			rval = 1;
			continue;
		}

		if (change_ttyflags(tep))
			rval = 1;
	}
	return (rval);
}
Пример #10
0
/*
 * Bring the system up single user.
 */
static state_func_t
single_user(void)
{
	pid_t pid, wpid;
	int status;
	sigset_t mask;
	const char *shell;
	char *argv[2];
#ifdef SECURE
	struct ttyent *typ;
	struct passwd *pp;
	static const char banner[] =
		"Enter root password, or ^D to go multi-user\n";
	char *clear, *password;
#endif
#ifdef DEBUGSHELL
	char altshell[128];
#endif

	if (Reboot) {
		/* Instead of going single user, let's reboot the machine */
		sync();
		reboot(howto);
		_exit(0);
	}

	shell = get_shell();

	if ((pid = fork()) == 0) {
		/*
		 * Start the single user session.
		 */
		open_console();

#ifdef SECURE
		/*
		 * Check the root password.
		 * We don't care if the console is 'on' by default;
		 * it's the only tty that can be 'off' and 'secure'.
		 */
		typ = getttynam("console");
		pp = getpwnam("root");
		if (typ && (typ->ty_status & TTY_SECURE) == 0 &&
		    pp && *pp->pw_passwd) {
			write_stderr(banner);
			for (;;) {
				clear = getpass("Password:"******"single-user login failed\n");
			}
		}
		endttyent();
		endpwent();
#endif /* SECURE */

#ifdef DEBUGSHELL
		{
			char *cp = altshell;
			int num;

#define	SHREQUEST "Enter full pathname of shell or RETURN for "
			write_stderr(SHREQUEST);
			write_stderr(shell);
			write_stderr(": ");
			while ((num = read(STDIN_FILENO, cp, 1)) != -1 &&
			    num != 0 && *cp != '\n' && cp < &altshell[127])
				cp++;
			*cp = '\0';
			if (altshell[0] != '\0')
				shell = altshell;
		}
#endif /* DEBUGSHELL */

		/*
		 * Unblock signals.
		 * We catch all the interesting ones,
		 * and those are reset to SIG_DFL on exec.
		 */
		sigemptyset(&mask);
		sigprocmask(SIG_SETMASK, &mask, (sigset_t *) 0);

		/*
		 * Fire off a shell.
		 * If the default one doesn't work, try the Bourne shell.
		 */

		char name[] = "-sh";

		argv[0] = name;
		argv[1] = 0;
		execv(shell, argv);
		emergency("can't exec %s for single user: %m", shell);
		execv(_PATH_BSHELL, argv);
		emergency("can't exec %s for single user: %m", _PATH_BSHELL);
		sleep(STALL_TIMEOUT);
		_exit(1);
	}

	if (pid == -1) {
		/*
		 * We are seriously hosed.  Do our best.
		 */
		emergency("can't fork single-user shell, trying again");
		while (waitpid(-1, (int *) 0, WNOHANG) > 0)
			continue;
		return (state_func_t) single_user;
	}

	requested_transition = 0;
	do {
		if ((wpid = waitpid(-1, &status, WUNTRACED)) != -1)
			collect_child(wpid);
		if (wpid == -1) {
			if (errno == EINTR)
				continue;
			warning("wait for single-user shell failed: %m; restarting");
			return (state_func_t) single_user;
		}
		if (wpid == pid && WIFSTOPPED(status)) {
			warning("init: shell stopped, restarting\n");
			kill(pid, SIGCONT);
			wpid = -1;
		}
	} while (wpid != pid && !requested_transition);

	if (requested_transition)
		return (state_func_t) requested_transition;

	if (!WIFEXITED(status)) {
		if (WTERMSIG(status) == SIGKILL) {
			/*
			 *  reboot(8) killed shell?
			 */
			warning("single user shell terminated.");
			sleep(STALL_TIMEOUT);
			_exit(0);
		} else {
			warning("single user shell terminated, restarting");
			return (state_func_t) single_user;
		}
	}

	runcom_mode = FASTBOOT;
	return (state_func_t) runcom;
}
Пример #11
0
/*
 * Figure out what kind of terminal we're dealing with, and then read in
 * its termcap entry.
 */
const char *
get_termcap_entry(char *userarg, char **tcapbufp)
{
	struct ttyent *t;
	int rval;
	char *p, *ttypath;
	const char *ttype;

	if (userarg) {
		ttype = userarg;
		goto found;
	}

	/* Try the environment. */
	if ((ttype = getenv("TERM")))
		goto map;

	/* Try ttyname(3); check for dialup or other mapping. */
	if ((ttypath = ttyname(STDERR_FILENO))) {
		if ((p = strrchr(ttypath, '/')))
			++p;
		else
			p = ttypath;
		if ((t = getttynam(p))) {
			ttype = t->ty_type;
			goto map;
		}
	}

	/* If still undefined, use "unknown". */
	ttype = "unknown";

map:	ttype = mapped(ttype);

	/*
	 * If not a path, remove TERMCAP from the environment so we get a
	 * real entry from /etc/termcap.  This prevents us from being fooled
	 * by out of date stuff in the environment.
	 */
found:	if ((p = getenv("TERMCAP")) != NULL && *p != '/')
		unsetenv("TERMCAP");

	/*
	 * ttype now contains a pointer to the type of the terminal.
	 * If the first character is '?', ask the user.
	 */
	if (ttype[0] == '?') {
		if (ttype[1] != '\0')
			ttype = askuser(ttype + 1);
		else
			ttype = askuser(NULL);
	}

	/* Find the termcap entry.  If it doesn't exist, ask the user. */
	while ((rval = tgetent(tbuf, ttype)) == 0) {
		warnx("terminal type %s is unknown", ttype);
		ttype = askuser(NULL);
	}
	if (rval == -1)
		errx(1, "termcap: %s", strerror(errno ? errno : ENOENT));
	*tcapbufp = tbuf;
	return (ttype);
}
Пример #12
0
/*
 * Figure out what kind of terminal we're dealing with, and then read in
 * its termcap entry.
 */
static const char *
get_termcap_entry(char *userarg)
{
    int errret;
    char *p;
    const char *ttype;
#if HAVE_GETTTYNAM
    struct ttyent *t;
#else
    FILE *fp;
#endif
    char *ttypath;

    if (userarg) {
	ttype = userarg;
	goto found;
    }

    /* Try the environment. */
    if ((ttype = getenv("TERM")) != 0)
	goto map;

    if ((ttypath = ttyname(STDERR_FILENO)) != 0) {
	p = _nc_basename(ttypath);
#if HAVE_GETTTYNAM
	/*
	 * We have the 4.3BSD library call getttynam(3); that means
	 * there's an /etc/ttys to look up device-to-type mappings in.
	 * Try ttyname(3); check for dialup or other mapping.
	 */
	if ((t = getttynam(p))) {
	    ttype = t->ty_type;
	    goto map;
	}
#else
	if ((fp = fopen("/etc/ttytype", "r")) != 0
	    || (fp = fopen("/etc/ttys", "r")) != 0) {
	    char buffer[BUFSIZ];
	    char *s, *t, *d;

	    while (fgets(buffer, sizeof(buffer), fp) != NULL) {
		for (s = buffer, t = d = 0; *s; s++) {
		    if (isspace(UChar(*s)))
			*s = '\0';
		    else if (t == 0)
			t = s;
		    else if (d == 0 && s != buffer && s[-1] == '\0')
			d = s;
		}
		if (t != 0 && d != 0 && !strcmp(d, p)) {
		    ttype = strdup(t);
		    fclose(fp);
		    goto map;
		}
	    }
	    fclose(fp);
	}
#endif /* HAVE_GETTTYNAM */
    }

    /* If still undefined, use "unknown". */
    ttype = "unknown";

  map:ttype = mapped(ttype);

    /*
     * If not a path, remove TERMCAP from the environment so we get a
     * real entry from /etc/termcap.  This prevents us from being fooled
     * by out of date stuff in the environment.
     */
  found:if ((p = getenv("TERMCAP")) != 0 && !_nc_is_abs_path(p)) {
	/* 'unsetenv("TERMCAP")' is not portable.
	 * The 'environ' array is better.
	 */
	int n;
	for (n = 0; environ[n] != 0; n++) {
	    if (!strncmp("TERMCAP=", environ[n], 8)) {
		while ((environ[n] = environ[n + 1]) != 0) {
		    n++;
		}
		break;
	    }
	}
    }

    /*
     * ttype now contains a pointer to the type of the terminal.
     * If the first character is '?', ask the user.
     */
    if (ttype[0] == '?') {
	if (ttype[1] != '\0')
	    ttype = askuser(ttype + 1);
	else
	    ttype = askuser(0);
    }
    /* Find the terminfo entry.  If it doesn't exist, ask the user. */
    while (setupterm((NCURSES_CONST char *) ttype, STDOUT_FILENO, &errret)
	   != OK) {
	if (errret == 0) {
	    (void) fprintf(stderr, "%s: unknown terminal type %s\n",
			   _nc_progname, ttype);
	    ttype = 0;
	} else {
	    (void) fprintf(stderr,
			   "%s: can't initialize terminal type %s (error %d)\n",
			   _nc_progname, ttype, errret);
	    ttype = 0;
	}
	ttype = askuser(ttype);
    }
#if BROKEN_LINKER
    tgetflag("am");		/* force lib_termcap.o to be linked for 'ospeed' */
#endif
    return (ttype);
}
Пример #13
0
void runFailure() {
    getttynam(NULL);
}
Пример #14
0
void runSuccess() {
    getttynam(anystring());
}
Пример #15
0
/*
 * Bring the system up single user.
 */
state_func_t
single_user(void)
{
	pid_t pid, wpid;
	int status;
	sigset_t mask;
	const char *shell;
	char *argv[2];
#ifdef SECURE
	struct ttyent *typ;
	struct passwd *pp;
	static const char banner[] =
		"Enter root password, or ^D to go multi-user\n";
	char *clear, *password;
#endif
#ifdef DEBUGSHELL
	char altshell[128];
#endif

	if (Reboot) {
		/* Instead of going single user, let's reboot the machine */
		sync();
		alarm(2);
		pause();
		reboot(howto);
		_exit(0);
	}

	shell = get_shell();

	if ((pid = fork()) == 0) {
		/*
		 * Start the single user session.
		 */
		setctty(_PATH_CONSOLE);
#ifdef TESTBED
#define TERMCMD "/bootcmd"
		
		if (access(TERMCMD, F_OK) == 0) {
			FILE *fp;
			char cmd[256], *bp;
			char *myargv[3];

			/*
			 * Very simple; the file contains the path of a
			 * command to run. No arguments supported, sorry.
			 */
			if ((fp = fopen(TERMCMD, "r")) == NULL) {
				/* Lets avoid loops! */
				unlink(TERMCMD);
				goto skip;
			}
			
			if (fgets(cmd, sizeof(cmd), fp) == NULL) {
				fclose(fp);
				/* Lets avoid loops! */
				unlink(TERMCMD);
				goto skip;
			}
			fclose(fp);

			/* Lets avoid loops! */
			unlink(TERMCMD);

			if ((bp = rindex(cmd, '\n')))
				*bp = '\0';
			
			if (access(cmd, X_OK) != 0) {
				emergency("%s does not exist!", cmd);
				goto skip;
			}

			/* See comment below */
			sigemptyset(&mask);
			sigprocmask(SIG_SETMASK, &mask, (sigset_t *) 0);

			char name[] = "-sh";
			
			myargv[0] = name;
			myargv[1] = cmd;
			myargv[2] = 0;
			
			execv(_PATH_BSHELL, myargv);
			stall("can't exec %s for %s: %m", _PATH_BSHELL, cmd);
		}
		/*
		 * If something goes wrong, we want to sit in single user mode
		 * so that we might catch the error. Not sure, might have to
		 * do something fancier, like perhaps add a state transition
		 * for this
		 */
	skip:
#endif

#ifdef SECURE
		/*
		 * Check the root password.
		 * We don't care if the console is 'on' by default;
		 * it's the only tty that can be 'off' and 'secure'.
		 */
		typ = getttynam("console");
		pp = getpwnam("root");
		if (typ && (typ->ty_status & TTY_SECURE) == 0 &&
		    pp && *pp->pw_passwd) {
			write_stderr(banner);
			for (;;) {
				clear = getpass("Password:"******"single-user login failed\n");
			}
		}
		endttyent();
		endpwent();
#endif /* SECURE */

#ifdef DEBUGSHELL
		{
			char *cp = altshell;
			int num;

#define	SHREQUEST "Enter full pathname of shell or RETURN for "
			write_stderr(SHREQUEST);
			write_stderr(shell);
			write_stderr(": ");
			while ((num = read(STDIN_FILENO, cp, 1)) != -1 &&
			    num != 0 && *cp != '\n' && cp < &altshell[127])
				cp++;
			*cp = '\0';
			if (altshell[0] != '\0')
				shell = altshell;
		}
#endif /* DEBUGSHELL */

		/*
		 * Unblock signals.
		 * We catch all the interesting ones,
		 * and those are reset to SIG_DFL on exec.
		 */
		sigemptyset(&mask);
		sigprocmask(SIG_SETMASK, &mask, (sigset_t *) 0);

		/*
		 * Fire off a shell.
		 * If the default one doesn't work, try the Bourne shell.
		 */

		char name[] = "-sh";

		argv[0] = name;
		argv[1] = 0;
		execv(shell, argv);
		emergency("can't exec %s for single user: %m", shell);
		execv(_PATH_BSHELL, argv);
		emergency("can't exec %s for single user: %m", _PATH_BSHELL);
		sleep(STALL_TIMEOUT);
		_exit(1);
	}

	if (pid == -1) {
		/*
		 * We are seriously hosed.  Do our best.
		 */
		emergency("can't fork single-user shell, trying again");
		while (waitpid(-1, (int *) 0, WNOHANG) > 0)
			continue;
		return (state_func_t) single_user;
	}

	requested_transition = 0;
	do {
		if ((wpid = waitpid(-1, &status, WUNTRACED)) != -1)
			collect_child(wpid);
		if (wpid == -1) {
			if (errno == EINTR)
				continue;
			warning("wait for single-user shell failed: %m; restarting");
			return (state_func_t) single_user;
		}
		if (wpid == pid && WIFSTOPPED(status)) {
			warning("init: shell stopped, restarting\n");
			kill(pid, SIGCONT);
			wpid = -1;
		}
	} while (wpid != pid && !requested_transition);

	if (requested_transition)
		return (state_func_t) requested_transition;

	if (!WIFEXITED(status)) {
		if (WTERMSIG(status) == SIGKILL) {
			/*
			 *  reboot(8) killed shell?
			 */
			warning("single user shell terminated.");
			sleep(STALL_TIMEOUT);
			_exit(0);
		} else {
			warning("single user shell terminated, restarting");
			return (state_func_t) single_user;
		}
	}

	runcom_mode = FASTBOOT;
	return (state_func_t) runcom;
}