/*
 * Originally based on an implementation of `su' by
 *
 *     Peter Orbaek  <poe@daimi.aau.dk>
 *
 * obtained circa 1997 from ftp://ftp.daimi.aau.dk/pub/linux/poe/
 *
 * Rewritten for Linux-PAM by Andrew G. Morgan <morgan@linux.kernel.org>
 * Modified by Andrey V. Savochkin <saw@msu.ru>
 * Modified for use with libcap by Andrew G. Morgan <morgan@kernel.org>
 */

/* #define PAM_DEBUG */

#include <sys/prctl.h>

/* non-root user of convenience to block signals */
#define TEMP_UID                  1

#ifndef PAM_APP_NAME
#define PAM_APP_NAME              "su"
#endif /* ndef PAM_APP_NAME */

#define DEFAULT_HOME              "/"
#define DEFAULT_SHELL             "/bin/bash"
#define SLEEP_TO_KILL_CHILDREN    3  /* seconds to wait after SIGTERM before
					SIGKILL */
#define SU_FAIL_DELAY     2000000    /* usec on authentication failure */

#define RHOST_UNKNOWN_NAME        ""     /* perhaps "[from.where?]" */
#define DEVICE_FILE_PREFIX        "/dev/"
#define WTMP_LOCK_TIMEOUT         3      /* in seconds */

#ifndef UT_IDSIZE
#define UT_IDSIZE 4            /* XXX - this is sizeof(struct utmp.ut_id) */
#endif

#include <stdlib.h>
#include <signal.h>
#include <stdio.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <pwd.h>
#include <grp.h>
#include <string.h>
#include <syslog.h>
#include <errno.h>
#include <fcntl.h>
#include <termios.h>
#include <sys/wait.h>
#include <utmp.h>
#include <ctype.h>
#include <stdarg.h>
#include <netdb.h>
#include <unistd.h>

#include <security/pam_appl.h>
#include <security/pam_misc.h>
#include <sys/capability.h>

#include <security/_pam_macros.h>

/* -------------------------------------------- */
/* ------ declarations ------------------------ */
/* -------------------------------------------- */

extern char **environ;
static pam_handle_t *pamh = NULL;
static int state;

static int wait_for_child_caught=0;
static int need_job_control=0;
static int is_terminal = 0;
static struct termios stored_mode;        /* initial terminal mode settings */
static uid_t terminal_uid = (uid_t) -1;
static uid_t invoked_uid = (uid_t) -1;

/* -------------------------------------------- */
/* ------ some local (static) functions ------- */
/* -------------------------------------------- */

/*
 * We will attempt to transcribe the following env variables
 * independent of whether we keep the whole environment. Others will
 * be set elsewhere: either in modules; or after the identity of the
 * user is known.
 */

static const char *posix_env[] = {
    "LANG",
    "LC_COLLATE",
    "LC_CTYPE",
    "LC_MONETARY",
    "LC_NUMERIC",
    "TZ",
    NULL
};

/*
 * make_environment transcribes a selection of environment variables
 * from the invoking user.
 */
static int make_environment(pam_handle_t *pamh, int keep_env)
{
    const char *tmpe;
    int i;
    int retval;

    if (keep_env) {
	/* preserve the original environment */
	return pam_misc_paste_env(pamh, (const char * const *)environ);
    }

    /* we always transcribe some variables anyway */
    tmpe = getenv("TERM");
    if (tmpe == NULL) {
	tmpe = "dumb";
    }
    retval = pam_misc_setenv(pamh, "TERM", tmpe, 0);
    if (retval == PAM_SUCCESS) {
	retval = pam_misc_setenv(pamh, "PATH", "/bin:/usr/bin", 0);
    }
    if (retval != PAM_SUCCESS) {
	tmpe = NULL;
	D(("error setting environment variables"));
	return retval;
    }

    /* also propagate the POSIX specific ones */
    for (i=0; retval == PAM_SUCCESS && posix_env[i]; ++i) {
	tmpe = getenv(posix_env[i]);
	if (tmpe != NULL) {
	    retval = pam_misc_setenv(pamh, posix_env[i], tmpe, 0);
	}
    }
    tmpe = NULL;

    return retval;
}

/*
 * checkfds ensures that stdout and stderr filedescriptors are
 * defined. If all else fails, it directs them to /dev/null.
 */
static void checkfds(void)
{
    struct stat st;
    int fd;

    if (fstat(1, &st) == -1) {
        fd = open("/dev/null", O_WRONLY);
        if (fd == -1) exit(1);
        if (fd != 1) {
            if (dup2(fd, 1) == -1) exit(1);
            if (close(fd) == -1) exit(1);
        }
    }
    if (fstat(2, &st) == -1) {
        fd = open("/dev/null", O_WRONLY);
        if (fd == -1) exit(1);
        if (fd != 2) {
            if (dup2(fd, 2) == -1) exit(1);
            if (close(fd) == -1) exit(1);
        }
    }
}

/*
 * store_terminal_modes captures the current state of the input
 * terminal. Calling this at the start of the program, we ensure we
 * can restore these default settings when su exits.
 */
static void store_terminal_modes(void)
{
    if (isatty(STDIN_FILENO)) {
	is_terminal = 1;
	if (tcgetattr(STDIN_FILENO, &stored_mode) != 0) {
	    fprintf(stderr, PAM_APP_NAME ": couldn't copy terminal mode");
	    exit(1);
	}
	return;
    }
    fprintf(stderr, PAM_APP_NAME ": must be run from a terminal\n");
    exit(1);
}

/*
 * restore_terminal_modes resets the terminal to the state it was in
 * when the program started.
 *
 * Returns:
 *   0     ok
 *   1     error
 */
static int restore_terminal_modes(void)
{
    if (is_terminal && tcsetattr(STDIN_FILENO, TCSAFLUSH, &stored_mode) != 0) {
	fprintf(stderr, PAM_APP_NAME ": cannot restore terminal mode: %s\n",
		strerror(errno));
	return 1;
    } else {
	return 0;
    }
}

/* ------ unexpected signals ------------------ */

struct sigaction old_int_act, old_quit_act, old_tstp_act, old_pipe_act;

/*
 * disable_terminal_signals attempts to make the process resistant to
 * being stopped - it helps ensure that the PAM stack can complete
 * session and auth failure logging etc.
 */
static void disable_terminal_signals(void)
{
    /*
     * Protect the process from dangerous terminal signals.
     * The protection is implemented via sigaction() because
     * the signals are sent regardless of the process' uid.
     */
    struct sigaction act;

    act.sa_handler = SIG_IGN;  /* ignore the signal */
    sigemptyset(&act.sa_mask); /* no signal blocking on handler
				  call needed */
    act.sa_flags = SA_RESTART; /* do not reset after first signal
				  arriving, restart interrupted
				  system calls if possible */
    sigaction(SIGINT, &act, &old_int_act);
    sigaction(SIGQUIT, &act, &old_quit_act);
    /*
     * Ignore SIGTSTP signals. Why? attacker could otherwise stop
     * a process and a. kill it, or b. wait for the system to
     * shutdown - either way, nothing appears in syslogs.
     */
    sigaction(SIGTSTP, &act, &old_tstp_act);
    /*
     * Ignore SIGPIPE. The parent `su' process may print something
     * on stderr. Killing of the process would be undesired.
     */
    sigaction(SIGPIPE, &act, &old_pipe_act);
}

static void enable_terminal_signals(void)
{
    sigaction(SIGINT, &old_int_act, NULL);
    sigaction(SIGQUIT, &old_quit_act, NULL);
    sigaction(SIGTSTP, &old_tstp_act, NULL);
    sigaction(SIGPIPE, &old_pipe_act, NULL);
}

/* ------ terminal ownership ------------------ */

/*
 * change_terminal_owner changes the ownership of STDIN if needed.
 * Returns:
 *   0     ok,
 *  -1     fatal error (continuing is impossible),
 *   1     non-fatal error.
 * In the case of an error "err_descr" is set to the error message
 * and "callname" to the name of the failed call.
 */
static int change_terminal_owner(uid_t uid, int is_login,
				 const char **callname, const char **err_descr)
{
    /* determine who owns the terminal line */
    if (is_terminal && is_login) {
	struct stat stat_buf;
	cap_t current, working;
	int status;
	cap_value_t cchown = CAP_CHOWN;

	if (fstat(STDIN_FILENO, &stat_buf) != 0) {
            *callname = "fstat to STDIN";
	    *err_descr = strerror(errno);
	    return -1;
	}

	current = cap_get_proc();
	working = cap_dup(current);
	cap_set_flag(working, CAP_EFFECTIVE, 1, &cchown, CAP_SET);
	status = cap_set_proc(working);
	cap_free(working);

	if (status != 0) {
	    *callname = "capset CHOWN";
	} else if ((status = fchown(STDIN_FILENO, uid, -1)) != 0) {
	    *callname = "fchown of STDIN";
	} else {
	    cap_set_proc(current);
	}
	cap_free(current);

	if (status != 0) {
	    *err_descr = strerror(errno);
	    return 1;
	}

	terminal_uid = stat_buf.st_uid;
    }
    return 0;
}

/*
 * restore_terminal_owner changes the terminal owner back to the value
 * it had when su was started.
 */
static void restore_terminal_owner(void)
{
    if (terminal_uid != (uid_t) -1) {
	cap_t current, working;
	int status;
	cap_value_t cchown = CAP_CHOWN;

	current = cap_get_proc();
	working = cap_dup(current);
	cap_set_flag(working, CAP_EFFECTIVE, 1, &cchown, CAP_SET);
	status = cap_set_proc(working);
	cap_free(working);

	if (status == 0) {
	    status = fchown(STDIN_FILENO, terminal_uid, -1);
	    cap_set_proc(current);
	}
	cap_free(current);

        if (status != 0) {
            openlog(PAM_APP_NAME, LOG_CONS|LOG_PERROR|LOG_PID, LOG_AUTHPRIV);
	    syslog(LOG_ALERT, "Terminal owner hasn\'t been restored: %s",
		   strerror(errno));
	    closelog();
        }
        terminal_uid = (uid_t) -1;
    }
}

/*
 * make_process_unkillable changes the uid of the process. TEMP_UID is
 * used for this temporary state.
 *
 * Returns:
 *   0     ok,
 *  -1     fatal error (continue of the work is impossible),
 *   1     non-fatal error.
 * In the case of an error "err_descr" is set to the error message
 * and "callname" to the name of the failed call.
 */
int make_process_unkillable(const char **callname, const char **err_descr)
{
    invoked_uid = getuid();
    if (invoked_uid == TEMP_UID) {
	/* no change needed */
	return 0;
    }

    if (cap_setuid(TEMP_UID) != 0) {
        *callname = "setuid";
	*err_descr = strerror(errno);
	return -1;
    }
    return 0;
}

/*
 * make_process_killable restores the invoking uid to the current
 * process.
 */
void make_process_killable()
{
    (void) cap_setuid(invoked_uid);
}

/* ------ command line parser ----------------- */

void usage(int exit_val)
{
    fprintf(stderr,"usage: su [-] [-h] [-c \"command\"] [username]\n");
    exit(exit_val);
}

/*
 * parse_command_line extracts the options from the command line
 * arguments.
 */
void parse_command_line(int argc, char *argv[],
			int *is_login, const char **user, const char **command)
{
    int username_present, command_present;

    *is_login = 0;
    *user = NULL;
    *command = NULL;
    username_present = command_present = 0;

    while ( --argc > 0 ) {
	const char *token;

	token = *++argv;
	if (*token == '-') {
	    switch (*++token) {
	    case '\0':             /* su as a login shell for the user */
		if (*is_login)
		    usage(1);
		*is_login = 1;
		break;
	    case 'c':
		if (command_present) {
		    usage(1);
		} else {               /* indicate we are running commands */
		    if (*++token != '\0') {
			command_present = 1;
			*command = token;
		    } else if (--argc > 0) {
			command_present = 1;
			*command = *++argv;
		    } else
			usage(1);
		}
		break;
	    case 'h':
		usage(0);
	    default:
		usage(1);
	    }
	} else {                       /* must be username */
	    if (username_present) {
		usage(1);
	    }
	    username_present = 1;
	    *user = *argv;
	}
    }

    if (!username_present) {
	fprintf(stderr, PAM_APP_NAME ": requires a username\n");
	usage(1);
    }
}

/*
 * This following contains code that waits for a child process to die.
 * It also chooses to intercept a couple of signals that it will
 * kindly pass on a SIGTERM to the child ;^). Waiting again for the
 * child to exit. If the child resists dying, it will SIGKILL it!
 */

static void wait_for_child_catch_sig(int ignore)
{
    wait_for_child_caught = 1;
}

static void prepare_for_job_control(int need_it)
{
    sigset_t ourset;

    (void) sigfillset(&ourset);
    if (sigprocmask(SIG_BLOCK, &ourset, NULL) != 0) {
	fprintf(stderr,"[trouble blocking signals]\n");
	wait_for_child_caught = 1;
	return;
    }
    need_job_control = need_it;
}

int wait_for_child(pid_t child)
{
    int retval, status, exit_code;
    sigset_t ourset;

    exit_code = -1; /* no exit code yet, exit codes could be from 0 to 255 */
    if (child == -1) {
	return exit_code;
    }

    /*
     * set up signal handling
     */

    if (!wait_for_child_caught) {
	struct sigaction action, defaction;

	action.sa_handler = wait_for_child_catch_sig;
	sigemptyset(&action.sa_mask);
	action.sa_flags = 0;

	defaction.sa_handler = SIG_DFL;
	sigemptyset(&defaction.sa_mask);
	defaction.sa_flags = 0;

	sigemptyset(&ourset);

	if (   sigaddset(&ourset, SIGTERM)
	    || sigaction(SIGTERM, &action, NULL)
	    || sigaddset(&ourset, SIGHUP)
	    || sigaction(SIGHUP, &action, NULL)
	    || sigaddset(&ourset, SIGALRM)          /* required by sleep(3) */
            || (need_job_control && sigaddset(&ourset, SIGTSTP))
            || (need_job_control && sigaction(SIGTSTP, &defaction, NULL))
            || (need_job_control && sigaddset(&ourset, SIGTTIN))
            || (need_job_control && sigaction(SIGTTIN, &defaction, NULL))
            || (need_job_control && sigaddset(&ourset, SIGTTOU))
            || (need_job_control && sigaction(SIGTTOU, &defaction, NULL))
	    || (need_job_control && sigaddset(&ourset, SIGCONT))
            || (need_job_control && sigaction(SIGCONT, &defaction, NULL))
	    || sigprocmask(SIG_UNBLOCK, &ourset, NULL)
	    ) {
	    fprintf(stderr,"[trouble setting signal intercept]\n");
	    wait_for_child_caught = 1;
	}

	/* application should be ready for receiving a SIGTERM/HUP now */
    }

    /*
     * This code waits for the process to actually die. If it stops,
     * then the parent attempts to mimic the behavior of the
     * child.. There is a slight bug in the code when the 'su'd user
     * attempts to restart the child independently of the parent --
     * the child dies.
     */
    while (!wait_for_child_caught) {
        /* parent waits for child */
	if ((retval = waitpid(child, &status, 0)) <= 0) {
            if (errno == EINTR) {
                continue;             /* recovering from a 'fg' */
	    }
            fprintf(stderr, "[error waiting child: %s]\n", strerror(errno));
            /*
             * Break the loop keeping exit_code undefined.
             * Do we have a chance for a successful wait() call
             * after kill()? (SAW)
             */
            wait_for_child_caught = 1;
            break;
        } else {
	    /* the child is terminated via exit() or a fatal signal */
	    if (WIFEXITED(status)) {
		exit_code = WEXITSTATUS(status);
	    } else {
		exit_code = 1;
	    }
	    break;
	}
    }

    if (wait_for_child_caught) {
	fprintf(stderr,"\nKilling shell...");
	kill(child, SIGTERM);
    }

    /*
     * do we need to wait for the child to catch up?
     */
    if (wait_for_child_caught) {
	sleep(SLEEP_TO_KILL_CHILDREN);
	kill(child, SIGKILL);
	fprintf(stderr, "killed\n");
    }

    /*
     * collect the zombie the shell was killed by ourself
     */
    if (exit_code == -1) {
	do {
	    retval = waitpid(child, &status, 0);
	} while (retval == -1 && errno == EINTR);
	if (retval == -1) {
	    fprintf(stderr, PAM_APP_NAME ": the final wait failed: %s\n",
		    strerror(errno));
	}
	if (WIFEXITED(status)) {
	    exit_code = WEXITSTATUS(status);
	} else {
	    exit_code = 1;
	}
    }

    return exit_code;
}


/*
 * Next some code that parses the spawned shell command line.
 */

static char * const *build_shell_args(const char *pw_shell, int login,
				      const char *command)
{
    int use_default = 1;  /* flag to signal we should use the default shell */
    const char **args=NULL;             /* array of PATH+ARGS+NULL pointers */

    D(("called."));
    if (login) {
        command = NULL;                 /* command always ignored for login */
    }

    if (pw_shell && *pw_shell != '\0') {
        char *line;
        const char *tmp, *tmpb=NULL;
        int arg_no=0,i;

        /* first find the number of arguments */
        D(("non-null shell"));
        for (tmp=pw_shell; *tmp; ++arg_no) {

            /* skip leading spaces */
            while (isspace(*tmp))
                ++tmp;

            if (tmpb == NULL)               /* mark beginning token */
                tmpb = tmp;
            if (*tmp == '\0')               /* end of line with no token */
                break;

            /* skip token */
            while (*tmp && !isspace(*tmp))
                ++tmp;
        }

        /*
         * We disallow shells:
         *    - without a full specified path;
         *    - when we are not logging in and the #args != 1
         *                                         (unlikely a simple shell)
         */

        D(("shell so far = %s, arg_no = %d", tmpb, arg_no));
        if (tmpb != NULL && tmpb[0] == '/'    /* something (full path) */
            && ( login || arg_no == 1 )       /* login, or single arg shells */
            ) {

            use_default = 0;                  /* we will use this shell */
            D(("committed to using user's shell"));
            if (command) {
                arg_no += 2;                  /* will append "-c" "command" */
            }

            /* allocate an array of pointers long enough */

            D(("building array of size %d", 2+arg_no));
            args = (const char **) calloc(2+arg_no, sizeof(const char *));
            if (args == NULL)
                return NULL;
            /* get a string long enough for all the arguments */

            D(("an array of size %d chars", 2+strlen(tmpb)
                                   + ( command ? 4:0 )));
            line = (char *) malloc(2+strlen(tmpb)
                                   + ( command ? 4:0 ));
            if (line == NULL) {
                free(args);
                return NULL;
            }

            /* fill array - tmpb points to start of first non-space char */

            line[0] = '-';
            strcpy(line+1, tmpb);

            /* append " -c" to line? */
            if (command) {
                strcat(line, " -c");
            }

            D(("complete command: %s [+] %s", line, command));

            tmp = strtok(line, " \t");
            D(("command path=%s", line+1));
            args[0] = line+1;

            if (login) {               /* standard procedure for login shell */
                D(("argv[0]=%s", line));
                args[i=1] = line;
            } else {                 /* not a login shell -- for use with su */
                D(("argv[0]=%s", line+1));
                args[i=1] = line+1;
            }

            while ((tmp = strtok(NULL, " \t"))) {
                D(("adding argument %d: %s",i,tmp));
                args[++i] = tmp;
            }
            if (command) {
                D(("appending command [%s]", command));
                args[++i] = command;
            }
            D(("terminating args with NULL"));
            args[++i] = NULL;
            D(("list completed."));
        }
    }

    /* should we use the default shell instead of specific one? */

    if (use_default && !login) {
        int last_arg;

        D(("selecting default shell"));
        last_arg = command ? 5:3;

        args = (const char **) calloc(last_arg--, sizeof(const char *));
        if (args == NULL) {
            return NULL;
        }
        args[1] = DEFAULT_SHELL;      /* mapped to argv[0] (NOT login shell) */
        args[0] = args[1];            /* path to program */
        if (command) {
            args[2] = "-c";           /* should perform command and exit */
            args[3] = command;        /* the desired command */
        }
        args[last_arg] = NULL;        /* terminate list of args */
    }

    D(("returning arg list"));
    return (char * const *) args;
}


/* ------ abnormal termination ---------------- */

static void exit_now(int exit_code, const char *format, ...)
{
    va_list args;

    va_start(args, format);
    vfprintf(stderr, format, args);
    va_end(args);

    if (pamh != NULL)
	pam_end(pamh, exit_code ? PAM_ABORT:PAM_SUCCESS);

    /* USER's shell may have completely broken terminal settings
       restore the sane(?) initial conditions */
    restore_terminal_modes();

    exit(exit_code);
}

static void exit_child_now(int exit_code, const char *format, ...)
{
    va_list args;

    va_start(args,format);
    vfprintf(stderr, format, args);
    va_end(args);

    if (pamh != NULL)
	pam_end(pamh, (exit_code ? PAM_ABORT:PAM_SUCCESS) | PAM_DATA_SILENT);

    exit(exit_code);
}

/* ------ PAM setup --------------------------- */

static struct pam_conv conv = {
    misc_conv,                   /* defined in <pam_misc/libmisc.h> */
    NULL
};

static void do_pam_init(const char *user, int is_login)
{
    int retval;

    retval = pam_start(PAM_APP_NAME, user, &conv, &pamh);
    if (retval != PAM_SUCCESS) {
	/*
	 * From my point of view failing of pam_start() means that
	 * pamh isn't a valid handler. Without a handler
	 * we couldn't call pam_strerror :-(   1998/03/29 (SAW)
	 */
	fprintf(stderr, PAM_APP_NAME ": pam_start failed with code %d\n",
		retval);
	exit(1);
    }

    /*
     * Fill in some blanks
     */

    retval = make_environment(pamh, !is_login);
    D(("made_environment returned: %s", pam_strerror(pamh,retval)));

    if (retval == PAM_SUCCESS && is_terminal) {
	const char *terminal = ttyname(STDIN_FILENO);
	if (terminal) {
	    retval = pam_set_item(pamh, PAM_TTY, (const void *)terminal);
	} else {
	    retval = PAM_PERM_DENIED;                /* how did we get here? */
	}
	terminal = NULL;
    }

    if (retval == PAM_SUCCESS && is_terminal) {
	const char *ruser = getlogin();      /* Who is running this program? */
	if (ruser) {
	    retval = pam_set_item(pamh, PAM_RUSER, (const void *)ruser);
	} else {
	    retval = PAM_PERM_DENIED;             /* must be known to system */
	}
	ruser = NULL;
    }

    if (retval == PAM_SUCCESS) {
	retval = pam_set_item(pamh, PAM_RHOST, (const void *)"localhost");
    }

    if (retval != PAM_SUCCESS) {
	exit_now(1, PAM_APP_NAME ": problem establishing environment\n");
    }

    /* have to pause on failure. At least this long (doubles..) */
    retval = pam_fail_delay(pamh, SU_FAIL_DELAY);
    if (retval != PAM_SUCCESS) {
	exit_now(1, PAM_APP_NAME ": problem initializing failure delay\n");
    }
}

/*
 * authenticate_user arranges for the PAM authentication stack to run.
 */
static int authenticate_user(pam_handle_t *pamh, cap_t all,
			     int *retval, const char **place,
			     const char **err_descr)
{
    *place = "pre-auth cap_set_proc";
    if (cap_set_proc(all)) {
	D(("failed to raise all capabilities"));
	*err_descr = "cap_set_proc() failed";
	*retval = PAM_SUCCESS;
	return 1;
    }

    D(("attempt to authenticate user"));
    *place = "pam_authenticate";
    *retval = pam_authenticate(pamh, 0);
    return (*retval != PAM_SUCCESS);
}

/*
 * user_accounting confirms an authenticated user is permitted service.
 */
static int user_accounting(pam_handle_t *pamh, cap_t all,
			   int *retval, const char **place,
			   const char **err_descr) {
    *place = "user_accounting";
    if (cap_set_proc(all)) {
	D(("failed to raise all capabilities"));
	*err_descr = "cap_set_proc() failed";
	return 1;
    }
    *place = "pam_acct_mgmt";
    *retval = pam_acct_mgmt(pamh, 0);
    return (*retval != PAM_SUCCESS);
}

/*
 * Find entry for this terminal (if there is one).
 * Utmp file should have been opened and rewinded for the call.
 *
 * XXX: the search should be more or less compatible with libc one.
 * The caller expects that pututline with the same arguments
 * will replace the found entry.
 */
static const struct utmp *find_utmp_entry(const char *ut_line,
					  const char *ut_id)
{
    struct utmp *u_tmp_p;

    while ((u_tmp_p = getutent()) != NULL)
	if ((u_tmp_p->ut_type == INIT_PROCESS ||
             u_tmp_p->ut_type == LOGIN_PROCESS ||
             u_tmp_p->ut_type == USER_PROCESS ||
             u_tmp_p->ut_type == DEAD_PROCESS) &&
            !strncmp(u_tmp_p->ut_id, ut_id, UT_IDSIZE) &&
            !strncmp(u_tmp_p->ut_line, ut_line, UT_LINESIZE))
                break;

    return u_tmp_p;
}

/*
 * Identify the terminal name and the abbreviation we will use.
 */
static void set_terminal_name(const char *terminal, char *ut_line, char *ut_id)
{
    memset(ut_line, 0, UT_LINESIZE);
    memset(ut_id, 0, UT_IDSIZE);

    /* set the terminal entry */
    if ( *terminal == '/' ) {     /* now deal with filenames */
	int o1, o2;

	o1 = strncmp(DEVICE_FILE_PREFIX, terminal, 5) ? 0 : 5;
	if (!strncmp("/dev/tty", terminal, 8)) {
	    o2 = 8;
	} else {
	    o2 = strlen(terminal) - sizeof(UT_IDSIZE);
	    if (o2 < 0)
		o2 = 0;
	}

	strncpy(ut_line, terminal + o1, UT_LINESIZE);
	strncpy(ut_id, terminal + o2, UT_IDSIZE);
    } else if (strchr(terminal, ':')) {  /* deal with X-based session */
	const char *suffix;

	suffix = strrchr(terminal,':');
	strncpy(ut_line, terminal, UT_LINESIZE);
	strncpy(ut_id, suffix, UT_IDSIZE);
    } else {	                         /* finally deal with weird terminals */
	strncpy(ut_line, terminal, UT_LINESIZE);
	ut_id[0] = '?';
	strncpy(ut_id + 1, terminal, UT_IDSIZE - 1);
    }
}

/*
 * Append an entry to wtmp. See utmp_open_session for the return convention.
 * Be careful: the function uses alarm().
 */

#define WWTMP_STATE_BEGINNING     0
#define WWTMP_STATE_FILE_OPENED   1
#define WWTMP_STATE_SIGACTION_SET 2
#define WWTMP_STATE_LOCK_TAKEN    3

static int write_wtmp(struct utmp *u_tmp_p, const char **callname,
		      const char **err_descr)
{
    int w_tmp_fd;
    struct flock w_lock;
    struct sigaction act1, act2;
    int state;
    int retval;

    state = WWTMP_STATE_BEGINNING;
    retval = 1;

    do {
        D(("writing to wtmp"));
        w_tmp_fd = open(_PATH_WTMP, O_APPEND|O_WRONLY);
        if (w_tmp_fd == -1) {
            *callname = "wtmp open";
            *err_descr = strerror(errno);
            break;
        }
        state = WWTMP_STATE_FILE_OPENED;

        /* prepare for blocking operation... */
        act1.sa_handler = SIG_DFL;
        sigemptyset(&act1.sa_mask);
        act1.sa_flags = 0;
        if (sigaction(SIGALRM, &act1, &act2) == -1) {
            *callname = "sigaction";
            *err_descr = strerror(errno);
            break;
        }
        alarm(WTMP_LOCK_TIMEOUT);
        state = WWTMP_STATE_SIGACTION_SET;

        /* now we try to lock this file-rcord exclusively; non-blocking */
        memset(&w_lock, 0, sizeof(w_lock));
        w_lock.l_type = F_WRLCK;
        w_lock.l_whence = SEEK_END;
        if (fcntl(w_tmp_fd, F_SETLK, &w_lock) < 0) {
            D(("locking %s failed.", _PATH_WTMP));
            *callname = "fcntl(F_SETLK)";
            *err_descr = strerror(errno);
            break;
        }
        alarm(0);
        sigaction(SIGALRM, &act2, NULL);
        state = WWTMP_STATE_LOCK_TAKEN;

        if (write(w_tmp_fd, u_tmp_p, sizeof(struct utmp)) != -1) {
            retval = 0;
	}
    } while(0); /* it's not a loop! */

    if (state >= WWTMP_STATE_LOCK_TAKEN) {
        w_lock.l_type = F_UNLCK;               /* unlock wtmp file */
        fcntl(w_tmp_fd, F_SETLK, &w_lock);
    }else if (state >= WWTMP_STATE_SIGACTION_SET) {
        alarm(0);
        sigaction(SIGALRM, &act2, NULL);
    }

    if (state >= WWTMP_STATE_FILE_OPENED) {
        close(w_tmp_fd);                       /* close wtmp file */
        D(("wtmp written"));
    }

    return retval;
}

/*
 * XXX - if this gets turned into a module, make this a
 * pam_data item. You should put the pid in the name so we can
 * "probably" nest calls more safely...
 */
struct utmp *login_stored_utmp=NULL;

/*
 * Returns:
 *   0     ok,
 *   1     non-fatal error
 *  -1     fatal error
 *  callname and err_descr will be set
 * Be careful: the function indirectly uses alarm().
 */
static int utmp_do_open_session(const char *user, const char *terminal,
				const char *rhost, pid_t pid,
				const char **place, const char **err_descr)
{
    struct utmp u_tmp;
    const struct utmp *u_tmp_p;
    char ut_line[UT_LINESIZE], ut_id[UT_IDSIZE];
    int retval;

    set_terminal_name(terminal, ut_line, ut_id);

    utmpname(_PATH_UTMP);
    setutent();                                           /* rewind file */
    u_tmp_p = find_utmp_entry(ut_line, ut_id);

    /* reset new entry */
    memset(&u_tmp, 0, sizeof(u_tmp));                     /* reset new entry */
    if (u_tmp_p == NULL) {
	D(("[NEW utmp]"));
    } else {
	D(("[OLD utmp]"));

	/*
	 * here, we make a record of the former entry. If the
	 * utmp_close_session code is attached to the same process,
	 * the wtmp will be replaced, otherwise we leave init to pick
	 * up the pieces.
	 */
	if (login_stored_utmp == NULL) {
	    login_stored_utmp = malloc(sizeof(struct utmp));
            if (login_stored_utmp == NULL) {
                *place = "malloc";
                *err_descr = "fail";
                endutent();
                return -1;
            }
	}
        memcpy(login_stored_utmp, u_tmp_p, sizeof(struct utmp));
    }

    /* we adjust the entry to reflect the current session */
    {
	strncpy(u_tmp.ut_line, ut_line, UT_LINESIZE);
	memset(ut_line, 0, UT_LINESIZE);
	strncpy(u_tmp.ut_id, ut_id, UT_IDSIZE);
	memset(ut_id, 0, UT_IDSIZE);
	strncpy(u_tmp.ut_user, user
		, sizeof(u_tmp.ut_user));
	strncpy(u_tmp.ut_host, rhost ? rhost : RHOST_UNKNOWN_NAME
		, sizeof(u_tmp.ut_host));

	/* try to fill the host address entry */
	if (rhost != NULL) {
	    struct hostent *hptr;

	    /* XXX: it isn't good to do DNS lookup here...  1998/05/29  SAW */
            hptr = gethostbyname(rhost);
	    if (hptr != NULL && hptr->h_addr_list) {
		memcpy(&u_tmp.ut_addr, hptr->h_addr_list[0]
		       , sizeof(u_tmp.ut_addr));
	    }
	}

	/* we fill in the remaining info */
	u_tmp.ut_type = USER_PROCESS;          /* a user process starting */
	u_tmp.ut_pid = pid;                    /* session identifier */
	u_tmp.ut_time = time(NULL);
    }

    setutent();                                /* rewind file (replace old) */
    pututline(&u_tmp);                         /* write it to utmp */
    endutent();                                /* close the file */

    retval = write_wtmp(&u_tmp, place, err_descr); /* write to wtmp file */
    memset(&u_tmp, 0, sizeof(u_tmp));          /* reset entry */

    return retval;
}

static int utmp_do_close_session(const char *terminal,
				 const char **place, const char **err_descr)
{
    int retval;
    struct utmp u_tmp;
    const struct utmp *u_tmp_p;
    char ut_line[UT_LINESIZE], ut_id[UT_IDSIZE];

    retval = 0;

    set_terminal_name(terminal, ut_line, ut_id);

    utmpname(_PATH_UTMP);
    setutent();                                              /* rewind file */

    /*
     * if there was a stored entry, return it to the utmp file, else
     * if there is a session to close, we close that
     */
    if (login_stored_utmp) {
	pututline(login_stored_utmp);

	memcpy(&u_tmp, login_stored_utmp, sizeof(u_tmp));
	u_tmp.ut_time = time(NULL);            /* a new time to restart */

        retval = write_wtmp(&u_tmp, place, err_descr);

	memset(login_stored_utmp, 0, sizeof(u_tmp)); /* reset entry */
	free(login_stored_utmp);
    } else {
        u_tmp_p = find_utmp_entry(ut_line, ut_id);
        if (u_tmp_p != NULL) {
            memset(&u_tmp, 0, sizeof(u_tmp));
            strncpy(u_tmp.ut_line, ut_line, UT_LINESIZE);
            strncpy(u_tmp.ut_id, ut_id, UT_IDSIZE);
            memset(&u_tmp.ut_user, 0, sizeof(u_tmp.ut_user));
            memset(&u_tmp.ut_host, 0, sizeof(u_tmp.ut_host));
            u_tmp.ut_addr = 0;
            u_tmp.ut_type = DEAD_PROCESS;      /* `old' login process */
            u_tmp.ut_pid = 0;
            u_tmp.ut_time = time(NULL);
            setutent();                        /* rewind file (replace old) */
            pututline(&u_tmp);                 /* mark as dead */

            retval = write_wtmp(&u_tmp, place, err_descr);
        }
    }

    /* clean up */
    memset(ut_line, 0, UT_LINESIZE);
    memset(ut_id, 0, UT_IDSIZE);

    endutent();                                /* close utmp file */
    memset(&u_tmp, 0, sizeof(u_tmp));          /* reset entry */

    return 0;
}

/*
 * Returns:
 *   0     ok,
 *   1     non-fatal error
 *  -1     fatal error
 * place and err_descr will be set
 * Be careful: the function indirectly uses alarm().
 */
static int utmp_open_session(pam_handle_t *pamh, pid_t pid,
			     int *retval,
			     const char **place, const char **err_descr)
{
    const char *user, *terminal, *rhost;

    *retval = pam_get_item(pamh, PAM_USER, (const void **)&user);
    if (*retval != PAM_SUCCESS) {
        return -1;
    }
    *retval = pam_get_item(pamh, PAM_TTY, (const void **)&terminal);
    if (retval != PAM_SUCCESS) {
        return -1;
    }
    *retval = pam_get_item(pamh, PAM_RHOST, (const void **)&rhost);
    if (retval != PAM_SUCCESS) {
        rhost = NULL;
    }

    return utmp_do_open_session(user, terminal, rhost, pid, place, err_descr);
}

static int utmp_close_session(pam_handle_t *pamh
                              , const char **place, const char **err_descr)
{
    int retval;
    const char *terminal;

    retval = pam_get_item(pamh, PAM_TTY, (const void **)&terminal);
    if (retval != PAM_SUCCESS) {
        *place = "pam_get_item(PAM_TTY)";
        *err_descr = pam_strerror(pamh, retval);
        return -1;
    }

    return utmp_do_close_session(terminal, place, err_descr);
}

/*
 * set_credentials raises all of the process and PAM credentials.
 */
static int set_credentials(pam_handle_t *pamh, cap_t all, int login,
			   const char **pw_shell,
			   int *retval, const char **place,
			   const char **err_descr)
{
    const char *user;
    char *shell;
    cap_value_t csetgid = CAP_SETGID;
    cap_t current;
    int status;
    struct passwd *pw;
    uid_t uid;

    D(("get user from pam"));
    *place = "set_credentials";
    *retval = pam_get_item(pamh, PAM_USER, (const void **)&user);
    if (*retval != PAM_SUCCESS || user == NULL || *user == '\0') {
	D(("error identifying user from PAM."));
	*retval = PAM_USER_UNKNOWN;
	return 1;
    }

    /*
     * Add the LOGNAME and HOME environment variables.
     */

    pw = getpwnam(user);
    if (pw == NULL || (user = x_strdup(pw->pw_name)) == NULL) {
	D(("failed to identify user"));
	*retval = PAM_USER_UNKNOWN;
	return 1;
    }

    uid = pw->pw_uid;
    shell = x_strdup(pw->pw_shell);
    if (shell == NULL) {
	D(("user %s has no shell", user));
	*retval = PAM_CRED_ERR;
	return 1;
    }

    if (login) {
	/* set LOGNAME, HOME */
	if (pam_misc_setenv(pamh, "LOGNAME", user, 0) != PAM_SUCCESS) {
	    D(("failed to set LOGNAME"));
	    *retval = PAM_CRED_ERR;
	    return 1;
	}
	if (pam_misc_setenv(pamh, "HOME", pw->pw_dir, 0) != PAM_SUCCESS) {
	    D(("failed to set HOME"));
	    *retval = PAM_CRED_ERR;
	    return 1;
	}
    }

    current = cap_get_proc();
    cap_set_flag(current, CAP_EFFECTIVE, 1, &csetgid, CAP_SET);
    status = cap_set_proc(current);
    cap_free(current);
    if (status != 0) {
	*err_descr = "unable to raise CAP_SETGID";
	return 1;
    }

    /* initialize groups */
    if (initgroups(pw->pw_name, pw->pw_gid) != 0 || setgid(pw->pw_gid) != 0) {
	D(("failed to setgid etc"));
	*retval = PAM_PERM_DENIED;
	return 1;
    }
    *pw_shell = shell;

    pw = NULL;                                                  /* be tidy */

    D(("desired uid=%d", uid));

    /* assume user's identity - but preserve the permitted set */
    if (cap_setuid(uid) != 0) {
	D(("failed to setuid: %v", strerror(errno)));
	*retval = PAM_PERM_DENIED;
	return 1;
    }

    /*
     * Next, we call the PAM framework to add/enhance the credentials
     * of this user [it may change the user's home directory in the
     * pam_env, and add supplemental group memberships...].
     */
    D(("setting credentials"));
    if (cap_set_proc(all)) {
	D(("failed to raise all capabilities"));
	*retval = PAM_PERM_DENIED;
	return 1;
    }

    D(("calling pam_setcred to establish credentials"));
    *retval = pam_setcred(pamh, PAM_ESTABLISH_CRED);

    return (*retval != PAM_SUCCESS);
}

/*
 * open_session invokes the open session PAM stack.
 */
static int open_session(pam_handle_t *pamh, cap_t all,
			int *retval, const char **place, const char **err_descr)
{
    /* Open the su-session */
    *place = "pam_open_session";
    if (cap_set_proc(all)) {
	D(("failed to raise t_caps capabilities"));
	*err_descr = "capability setting failed";
	return 1;
    }
    *retval = pam_open_session(pamh, 0);     /* Must take care to close */
    if (*retval != PAM_SUCCESS) {
	return 1;
    }
    return 0;
}

/* ------ shell invoker ----------------------- */

static int launch_callback_fn(void *h)
{
    pam_handle_t *pamh = h;
    int retval;

    D(("pam_end"));
    retval = pam_end(pamh, PAM_SUCCESS | PAM_DATA_SILENT);
    pamh = NULL;
    if (retval != PAM_SUCCESS) {
	return -1;
    }

    /*
     * Restore a signal status: information if the signal is ignored
     * is inherited across exec() call.  (SAW)
     */
    enable_terminal_signals();

    D(("about to launch"));
    return 0;
}

/* Returns PAM_<STATUS>. */
static int perform_launch_and_cleanup(cap_t all, int is_login,
				      const char *shell, const char *command)
{
    int retval, status;
    const char *user, *home;
    uid_t uid;
    char * const * shell_args;
    char * const * shell_env;
    cap_launch_t launcher;
    pid_t child;


    /*
     * Break up the shell command into a command and arguments
     */
    shell_args = build_shell_args(shell, is_login, command);
    if (shell_args == NULL) {
	D(("failed to compute shell arguments"));
	return PAM_SYSTEM_ERR;
    }

    home = pam_getenv(pamh, "HOME");
    if ( !home || home[0] == '\0' ) {
	fprintf(stderr, "setting home directory for %s to %s\n",
		user, DEFAULT_HOME);
	home = DEFAULT_HOME;
	if (pam_misc_setenv(pamh, "HOME", home, 0) != PAM_SUCCESS) {
	    D(("unable to set $HOME"));
	    fprintf(stderr,
		    "Warning: unable to set HOME environment variable\n");
	}
    }
    if (is_login) {
	if (chdir(home) && chdir(DEFAULT_HOME)) {
	    D(("failed to change directory"));
	    return PAM_SYSTEM_ERR;
	}
    }

    shell_env = pam_getenvlist(pamh);
    if (shell_env == NULL) {
	D(("failed to obtain environment for child"));
	return PAM_SYSTEM_ERR;
    }

    launcher = cap_new_launcher(shell_args[0],
				(const char * const *) &shell_args[1],
				(const char * const *) shell_env);
    if (launcher == NULL) {
	D(("failed to initialize launcher"));
	return PAM_SYSTEM_ERR;
    }
    cap_launcher_set_iab(launcher, cap_iab_get_proc());
    cap_launcher_callback(launcher, launch_callback_fn);

    child = cap_launch(launcher, pamh);
    cap_free(launcher);

    /* job control is off for login sessions */
    prepare_for_job_control(!is_login && command != NULL);

    if (cap_setuid(TEMP_UID) != 0) {
	fprintf(stderr, "[failed to change monitor UID=%d]\n", TEMP_UID);
    }

    /* wait for child to terminate */
    status = wait_for_child(child);
    if (status != 0) {
	D(("shell returned %d", status));
    }
    return status;
}

static void close_session(pam_handle_t *pamh, cap_t all)
{
    int retval;

    D(("session %p closing", pamh));
    if (cap_set_proc(all)) {
	fprintf(stderr, "WARNING: could not raise all caps\n");
    }
    retval = pam_close_session(pamh, 0);
    if (retval != PAM_SUCCESS) {
	fprintf(stderr, "WARNING: could not close session\n\t%s\n",
		pam_strerror(pamh,retval));
    }
}

/* -------------------------------------------- */
/* ------ the application itself -------------- */
/* -------------------------------------------- */

int main(int argc, char *argv[])
{
    int retcode, is_login, status;
    int retval, final_retval; /* PAM_xxx return values */
    const char *command, *shell;
    pid_t child;
    uid_t uid;
    const char *place = NULL, *err_descr = NULL;
    cap_t all, t_caps;

    all = cap_get_proc();
    cap_fill(all, CAP_EFFECTIVE, CAP_PERMITTED);

    checkfds();

    /*
     * Check whether stdin is a terminal and store terminal modes for later.
     */
    store_terminal_modes();

    /* ---------- parse the argument list and --------- */
    /* ------ initialize the Linux-PAM interface ------ */
    {
	const char *user;              /* transient until PAM_USER defined */
	parse_command_line(argc, argv, &is_login, &user, &command);
	place = "do_pam_init";
	do_pam_init(user, is_login);   /* call pam_start and set PAM items */
    }

    /*
     * Turn off terminal signals - this is to be sure that su gets a
     * chance to call pam_end() and restore the terminal modes in
     * spite of the frustrated user pressing Ctrl-C.
     */
    disable_terminal_signals();

    /*
     * Random exits from here are strictly prohibited :-) (SAW) AGM
     * achieves this with goto's and a single exit at the end of main.
     */
    status = 1;                       /* fake exit status of a child */
    err_descr = NULL;                 /* errors haven't happened */

    if (make_process_unkillable(&place, &err_descr) != 0) {
	goto su_exit;
    }

    if (authenticate_user(pamh, all, &retval, &place, &err_descr) != 0) {
	goto auth_exit;
    }

    /*
     * The user is valid, but should they have access at this
     * time?
     */
    if (user_accounting(pamh, all, &retval, &place, &err_descr) != 0) {
	goto auth_exit;
    }

    D(("su attempt is confirmed as authorized"));

    /*
     * ... setup terminal, ...
     */
    retcode = change_terminal_owner(uid, is_login, &place, &err_descr);
    if (retcode > 0) {
	fprintf(stderr, PAM_APP_NAME ": %s: %s\n", place, err_descr);
	err_descr = NULL; /* forget about the problem */
    } else if (retcode < 0) {
	D(("terminal owner to uid=%d change failed", uid));
	goto auth_exit;
    }

    if (set_credentials(pamh, all, is_login,
			&shell, &retval, &place, &err_descr) != 0) {
	D(("failed to set credentials"));
	goto auth_exit;
    }

    /*
     * Here the IAB value is fixed and may differ from all's
     * Inheritable value. So synthesize what we need to proceed in the
     * child, for now, in this current process.
     */
    place = "preserving inheritable parts";
    t_caps = cap_get_proc();
    if (t_caps == NULL) {
	D(("failed to read capabilities"));
	err_descr = "capability read failed";
	goto delete_cred;
    }
    if (cap_fill(t_caps, CAP_EFFECTIVE, CAP_PERMITTED)) {
	D(("failed to fill effective bits"));
	err_descr = "capability fill failed";
	goto delete_cred;
    }

    /*
     * ... make [uw]tmp entries.
     */
    if (is_login) {
	/*
	 * Note: we use the parent pid as a session identifier for
	 * the logging.
	 */
	retcode = utmp_open_session(pamh, getpid(),
				    &retval, &place, &err_descr);
	if (retcode > 0) {
	    fprintf(stderr, PAM_APP_NAME ": %s: %s\n", place, err_descr);
	    err_descr = NULL; /* forget about this non-critical problem */
	} else if (retcode < 0) {
	    goto delete_cred;
	}
    }

    if (open_session(pamh, t_caps, &retval, &place, &err_descr) != 0) {
	goto utmp_closer;
    }

    status = perform_launch_and_cleanup(t_caps, is_login, shell, command);
    close_session(pamh, all);

utmp_closer:
    if (is_login) {
	/* do [uw]tmp cleanup */
	retcode = utmp_close_session(pamh, &place, &err_descr);
	if (retcode) {
	    fprintf(stderr, PAM_APP_NAME ": %s: %s\n", place, err_descr);
	}
    }

delete_cred:
    D(("delete credentials"));
    if (cap_set_proc(all)) {
	D(("failed to raise all capabilities"));
    }
    retcode = pam_setcred(pamh, PAM_DELETE_CRED);
    if (retcode != PAM_SUCCESS) {
	fprintf(stderr, "WARNING: could not delete credentials\n\t%s\n",
		pam_strerror(pamh, retcode));
    }

old_owner:
    D(("return terminal to local control"));
    restore_terminal_owner();

auth_exit:
    D(("for clean up we restore the launching user"));
    make_process_killable();

    D(("all done - closing down pam"));
    if (retval != PAM_SUCCESS) {      /* PAM has failed */
	fprintf(stderr, PAM_APP_NAME ": %s\n", pam_strerror(pamh, retval));
	final_retval = PAM_ABORT;
    } else if (err_descr != NULL) {   /* a system error has happened */
	fprintf(stderr, PAM_APP_NAME ": %s: %s\n", place, err_descr);
	final_retval = PAM_ABORT;
    } else {
	final_retval = PAM_SUCCESS;
    }
    (void) pam_end(pamh, final_retval);
    pamh = NULL;

    if (restore_terminal_modes() != 0 && !status) {
	status = 1;
    }

su_exit:
    exit(status);                 /* transparent exit */
}
