void
start_login(char *host, int autologin, char *name)
{
	char **argv;
#define	TABBUFSIZ	512
	char	defent[TABBUFSIZ];
	char	defstrs[TABBUFSIZ];
#undef	TABBUFSIZ
	const char *loginprog = NULL;
	extern struct sockaddr_storage from;
	char buf[sizeof(from) * 4 + 1];

	scrub_env();

	/*
	 * -a : pass on the address of the host.
	 * -h : pass on name of host.
	 *	WARNING:  -h and -a are accepted by login
	 *	if and only if getuid() == 0.
	 * -p : don't clobber the environment (so terminal type stays set).
	 *
	 * -f : force this login, he has already been authenticated
	 */
	argv = addarg(0, "login");

	argv = addarg(argv, "-a");
	(void)strvisx(buf, (const char *)(const void *)&from, sizeof(from),
	    VIS_WHITE);
	argv = addarg(argv, buf);

	argv = addarg(argv, "-h");
	argv = addarg(argv, host);

	argv = addarg(argv, "-p");
#ifdef	LINEMODE
	/*
	 * Set the environment variable "LINEMODE" to either
	 * "real" or "kludge" if we are operating in either
	 * real or kludge linemode.
	 */
	if (lmodetype == REAL_LINEMODE)
		setenv("LINEMODE", "real", 1);
# ifdef KLUDGELINEMODE
	else if (lmodetype == KLUDGE_LINEMODE || lmodetype == KLUDGE_OK)
		setenv("LINEMODE", "kludge", 1);
# endif
#endif
#ifdef SECURELOGIN
	/*
	 * don't worry about the -f that might get sent.
	 * A -s is supposed to override it anyhow.
	 */
	if (require_secure_login)
		argv = addarg(argv, "-s");
#endif
#ifdef AUTHENTICATION
	if (auth_level >= 0 && autologin == AUTH_VALID) {
		argv = addarg(argv, "-f");
		argv = addarg(argv, "--");
		argv = addarg(argv, name);
	} else
#endif
	if (getenv("USER")) {
		argv = addarg(argv, "--");
		argv = addarg(argv, getenv("USER"));
		/*
		 * Assume that login will set the USER variable
		 * correctly.  For SysV systems, this means that
		 * USER will no longer be set, just LOGNAME by
		 * login.  (The problem is that if the auto-login
		 * fails, and the user then specifies a different
		 * account name, he can get logged in with both
		 * LOGNAME and USER in his environment, but the
		 * USER value will be wrong.
		 */
		unsetenv("USER");
	}
        if (getent(defent, gettyname) == 1) {
                char *cp = defstrs;

                loginprog = getstr("lo", &cp);
        }
        if (loginprog == NULL)
                loginprog = _PATH_LOGIN;
	closelog();
	/*
	 * This sleep(1) is in here so that telnetd can
	 * finish up with the tty.  There's a race condition
	 * the login banner message gets lost...
	 */
	sleep(1);
        execv(loginprog, argv);

        syslog(LOG_ERR, "%s: %m", loginprog);
        fatalperror(net, loginprog);
	/*NOTREACHED*/
}
Example #2
0
void
start_login(const char *host, int autologin, char *name)
{
    struct arg_val argv;
    char *user;
    int save_errno;

#ifdef ENCRYPTION
    encrypt_output = NULL;
    decrypt_input = NULL;
#endif

#ifdef HAVE_UTMPX_H
    {
	int pid = getpid();
	struct utmpx utmpx;
	struct timeval tv;
	char *clean_tty;

	/*
	 * Create utmp entry for child
	 */

	clean_tty = clean_ttyname(line);
	memset(&utmpx, 0, sizeof(utmpx));
	strncpy(utmpx.ut_user,  ".telnet", sizeof(utmpx.ut_user));
	strncpy(utmpx.ut_line,  clean_tty, sizeof(utmpx.ut_line));
#ifdef HAVE_STRUCT_UTMP_UT_ID
	strncpy(utmpx.ut_id, make_id(clean_tty), sizeof(utmpx.ut_id));
#endif
	utmpx.ut_pid = pid;

	utmpx.ut_type = LOGIN_PROCESS;

	gettimeofday (&tv, NULL);
	utmpx.ut_tv.tv_sec = tv.tv_sec;
	utmpx.ut_tv.tv_usec = tv.tv_usec;

	if (pututxline(&utmpx) == NULL)
	    fatal(net, "pututxline failed");
    }
#endif

    scrub_env();

    /*
     * -h : pass on name of host.
     *		WARNING:  -h is accepted by login if and only if
     *			getuid() == 0.
     * -p : don't clobber the environment (so terminal type stays set).
     *
     * -f : force this login, he has already been authenticated
     */

    /* init argv structure */
    argv.size=0;
    argv.argc=0;
    argv.argv=malloc(0); /*so we can call realloc later */
    addarg(&argv, "login");
    addarg(&argv, "-h");
    addarg(&argv, host);
    addarg(&argv, "-p");
    if(name && name[0])
	user = name;
    else
	user = getenv("USER");
#ifdef AUTHENTICATION
    if (auth_level < 0 || autologin != AUTH_VALID) {
	if(!no_warn) {
	    printf("User not authenticated. ");
	    if (require_otp)
		printf("Using one-time password\r\n");
	    else
		printf("Using plaintext username and password\r\n");
	}
	if (require_otp) {
	    addarg(&argv, "-a");
	    addarg(&argv, "otp");
	}
	if(log_unauth)
	    syslog(LOG_INFO, "unauthenticated access from %s (%s)",
		   host, user ? user : "******");
    }
    if (auth_level >= 0 && autologin == AUTH_VALID)
	addarg(&argv, "-f");
#endif
    if(user){
	addarg(&argv, "--");
	addarg(&argv, strdup(user));
    }
    if (getenv("USER")) {
	/*
	 * Assume that login will set the USER variable
	 * correctly.  For SysV systems, this means that
	 * USER will no longer be set, just LOGNAME by
	 * login.  (The problem is that if the auto-login
	 * fails, and the user then specifies a different
	 * account name, he can get logged in with both
	 * LOGNAME and USER in his environment, but the
	 * USER value will be wrong.
	 */
	unsetenv("USER");
    }
    closelog();
    /*
     * This sleep(1) is in here so that telnetd can
     * finish up with the tty.  There's a race condition
     * the login banner message gets lost...
     */
    sleep(1);

    execv(new_login, argv.argv);
    save_errno = errno;
    syslog(LOG_ERR, "%s: %m", new_login);
    fatalperror_errno(net, new_login, save_errno);
    /*NOTREACHED*/
}