/*
 * Copyright (c) 1994-1996,1998-2010 Todd C. Miller <Todd.Miller@courtesan.com>
 *
 * Permission to use, copy, modify, and distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 *
 * Sponsored in part by the Defense Advanced Research Projects
 * Agency (DARPA) and Air Force Research Laboratory, Air Force
 * Materiel Command, USAF, under agreement number F39502-99-1-0512.
 */

#include <config.h>

#include <sys/types.h>
#include <sys/param.h>
#include <sys/stat.h>
#include <stdio.h>
#ifdef STDC_HEADERS
# include <stdlib.h>
# include <stddef.h>
#else
# ifdef HAVE_STDLIB_H
#  include <stdlib.h>
# endif
#endif /* STDC_HEADERS */
#ifdef HAVE_STRING_H
# include <string.h>
#endif /* HAVE_STRING_H */
#ifdef HAVE_STRINGS_H
# include <strings.h>
#endif /* HAVE_STRINGS_H */
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif /* HAVE_UNISTD_H */
#include <pwd.h>
#include <errno.h>
#include <grp.h>
#ifdef HAVE_LOGIN_CAP_H
# include <login_cap.h>
#endif

#include "sudo.h"

#ifdef __TANDEM
# define ROOT_UID	65535
#else
# define ROOT_UID	0
#endif

/*
 * Prototypes
 */
static void runas_setup		__P((void));
static void runas_setgroups	__P((void));
static void restore_groups	__P((void));

static int current_perm = -1;

#ifdef HAVE_SETRESUID
/*
 * Set real and effective and saved uids and gids based on perm.
 * We always retain a saved uid of 0 unless we are headed for an exec().
 * We only flip the effective gid since it only changes for PERM_SUDOERS.
 * This version of set_perms() works fine with the "stay_setuid" option.
 */
int
set_perms(perm)
    int perm;
{
    const char *errstr;
    int noexit;

    noexit = ISSET(perm, PERM_NOEXIT);
    CLR(perm, PERM_MASK);

    if (perm == current_perm)
	return(1);

    switch (perm) {
	case PERM_ROOT:
				if (setresuid(ROOT_UID, ROOT_UID, ROOT_UID)) {
				    errstr = "setresuid(ROOT_UID, ROOT_UID, ROOT_UID)";
				    goto bad;
				}
				(void) setresgid(-1, user_gid, -1);
				if (current_perm == PERM_RUNAS)
				    restore_groups();
			      	break;

	case PERM_USER:
    	    	    	        (void) setresgid(-1, user_gid, -1);
				if (setresuid(user_uid, user_uid, ROOT_UID)) {
				    errstr = "setresuid(user_uid, user_uid, ROOT_UID)";
				    goto bad;
				}
			      	break;
				
	case PERM_FULL_USER:
				/* headed for exec() */
    	    	    	        (void) setgid(user_gid);
				if (setresuid(user_uid, user_uid, user_uid)) {
				    errstr = "setresuid(user_uid, user_uid, user_uid)";
				    goto bad;
				}
			      	break;
				
	case PERM_RUNAS:
				runas_setgroups();
				(void) setresgid(-1, runas_gr ?
				    runas_gr->gr_gid : runas_pw->pw_gid, -1);
				if (setresuid(-1, runas_pw ? runas_pw->pw_uid :
				    user_uid, -1)) {
				    errstr = "unable to change to runas uid";
				    goto bad;
				}
			      	break;

	case PERM_FULL_RUNAS:
				/* headed for exec(), assume euid == ROOT_UID */
				runas_setup();
				if (setresuid(def_stay_setuid ?
				    user_uid : runas_pw->pw_uid,
				    runas_pw->pw_uid, runas_pw->pw_uid)) {
				    errstr = "unable to change to runas uid";
				    goto bad;
				}
				break;

	case PERM_SUDOERS:
				/* assume euid == ROOT_UID, ruid == user */
				if (setresgid(-1, SUDOERS_GID, -1))
				    error(1, "unable to change to sudoers gid");

				/*
				 * If SUDOERS_UID == ROOT_UID and SUDOERS_MODE
				 * is group readable we use a non-zero
				 * uid in order to avoid NFS lossage.
				 * Using uid 1 is a bit bogus but should
				 * work on all OS's.
				 */
				if (SUDOERS_UID == ROOT_UID) {
				    if ((SUDOERS_MODE & 040) && setresuid(ROOT_UID, 1, ROOT_UID)) {
					errstr = "setresuid(ROOT_UID, 1, ROOT_UID)";
					goto bad;
				    }
				} else {
				    if (setresuid(ROOT_UID, SUDOERS_UID, ROOT_UID)) {
					errstr = "setresuid(ROOT_UID, SUDOERS_UID, ROOT_UID)";
					goto bad;
				    }
				}
			      	break;
	case PERM_TIMESTAMP:
				if (setresuid(ROOT_UID, timestamp_uid, ROOT_UID)) {
				    errstr = "setresuid(ROOT_UID, timestamp_uid, ROOT_UID)";
				    goto bad;
				}
			      	break;
    }

    current_perm = perm;
    return(1);
bad:
    warningx("%s: %s", errstr,
	errno == EAGAIN ? "too many processes" : strerror(errno));
    if (noexit)
	return(0);
    exit(1);
}

#else
# ifdef HAVE_SETREUID

/*
 * Set real and effective uids and gids based on perm.
 * We always retain a real or effective uid of ROOT_UID unless
 * we are headed for an exec().
 * This version of set_perms() works fine with the "stay_setuid" option.
 */
int
set_perms(perm)
    int perm;
{
    const char *errstr;
    int noexit;

    noexit = ISSET(perm, PERM_NOEXIT);
    CLR(perm, PERM_MASK);

    if (perm == current_perm)
	return(1);

    switch (perm) {
	case PERM_ROOT:
				if (setreuid(-1, ROOT_UID)) {
				    errstr = "setreuid(-1, ROOT_UID)";
				    goto bad;
				}
				if (setuid(ROOT_UID)) {
				    errstr = "setuid(ROOT_UID)";
				    goto bad;
				}
				(void) setregid(-1, user_gid);
				if (current_perm == PERM_RUNAS)
				    restore_groups();
			      	break;

	case PERM_USER:
    	    	    	        (void) setregid(-1, user_gid);
				if (setreuid(ROOT_UID, user_uid)) {
				    errstr = "setreuid(ROOT_UID, user_uid)";
				    goto bad;
				}
			      	break;
				
	case PERM_FULL_USER:
				/* headed for exec() */
    	    	    	        (void) setgid(user_gid);
				if (setreuid(user_uid, user_uid)) {
				    errstr = "setreuid(user_uid, user_uid)";
				    goto bad;
				}
			      	break;
				
	case PERM_RUNAS:
				runas_setgroups();
				(void) setregid(-1, runas_gr ?
				    runas_gr->gr_gid : runas_pw->pw_gid);
				if (setreuid(-1,
				    runas_pw ? runas_pw->pw_uid : user_uid)) {
				    errstr = "unable to change to runas uid";
				    goto bad;
				}
			      	break;

	case PERM_FULL_RUNAS:
				/* headed for exec(), assume euid == ROOT_UID */
				runas_setup();
				if (setreuid(def_stay_setuid ? user_uid :
				    runas_pw->pw_uid, runas_pw->pw_uid)) {
				    errstr = "unable to change to runas uid";
				    goto bad;
				}
				break;

	case PERM_SUDOERS:
				/* assume euid == ROOT_UID, ruid == user */
				if (setregid(-1, SUDOERS_GID))
				    error(1, "unable to change to sudoers gid");

				/*
				 * If SUDOERS_UID == ROOT_UID and SUDOERS_MODE
				 * is group readable we use a non-zero
				 * uid in order to avoid NFS lossage.
				 * Using uid 1 is a bit bogus but should
				 * work on all OS's.
				 */
				if (SUDOERS_UID == ROOT_UID) {
				    if ((SUDOERS_MODE & 040) && setreuid(ROOT_UID, 1)) {
					errstr = "setreuid(ROOT_UID, 1)";
					goto bad;
				    }
				} else {
				    if (setreuid(ROOT_UID, SUDOERS_UID)) {
					errstr = "setreuid(ROOT_UID, SUDOERS_UID)";
					goto bad;
				    }
				}
			      	break;
	case PERM_TIMESTAMP:
				if (setreuid(ROOT_UID, timestamp_uid)) {
				    errstr = "setreuid(ROOT_UID, timestamp_uid)";
				    goto bad;
				}
			      	break;
    }

    current_perm = perm;
    return(1);
bad:
    warningx("%s: %s", errstr,
	errno == EAGAIN ? "too many processes" : strerror(errno));
    if (noexit)
	return(0);
    exit(1);
}

# else /* !HAVE_SETRESUID && !HAVE_SETREUID */
# ifdef HAVE_SETEUID

/*
 * Set real and effective uids and gids based on perm.
 * NOTE: does not support the "stay_setuid" option.
 */
int
set_perms(perm)
    int perm;
{
    const char *errstr;
    int noexit;

    noexit = ISSET(perm, PERM_NOEXIT);
    CLR(perm, PERM_MASK);

    if (perm == current_perm)
	return(1);

    /*
     * Since we only have setuid() and seteuid() and semantics
     * for these calls differ on various systems, we set
     * real and effective uids to ROOT_UID initially to be safe.
     */
    if (seteuid(ROOT_UID)) {
	errstr = "seteuid(ROOT_UID)";
	goto bad;
    }
    if (setuid(ROOT_UID)) {
	errstr = "setuid(ROOT_UID)";
	goto bad;
    }

    switch (perm) {
	case PERM_ROOT:
				/* uid set above */
				(void) setegid(user_gid);
				if (current_perm == PERM_RUNAS)
				    restore_groups();
			      	break;

	case PERM_USER:
    	    	    	        (void) setegid(user_gid);
				if (seteuid(user_uid)) {
				    errstr = "seteuid(user_uid)";
				    goto bad;
				}
			      	break;
				
	case PERM_FULL_USER:
				/* headed for exec() */
    	    	    	        (void) setgid(user_gid);
				if (setuid(user_uid)) {
				    errstr = "setuid(user_uid)";
				    goto bad;
				}
			      	break;
				
	case PERM_RUNAS:
				runas_setgroups();
				(void) setegid(runas_gr ?
				    runas_gr->gr_gid : runas_pw->pw_gid);
				if (seteuid(runas_pw ? runas_pw->pw_uid : user_uid)) {
				    errstr = "unable to change to runas uid";
				    goto bad;
				}
			      	break;

	case PERM_FULL_RUNAS:
				/* headed for exec() */
				runas_setup();
				if (setuid(runas_pw->pw_uid)) {
				    errstr = "unable to change to runas uid";
				    goto bad;
				}
				break;

	case PERM_SUDOERS:
				if (setegid(SUDOERS_GID))
				    error(1, "unable to change to sudoers gid");

				/*
				 * If SUDOERS_UID == ROOT_UID and SUDOERS_MODE
				 * is group readable we use a non-zero
				 * uid in order to avoid NFS lossage.
				 * Using uid 1 is a bit bogus but should
				 * work on all OS's.
				 */
				if (SUDOERS_UID == ROOT_UID) {
				    if ((SUDOERS_MODE & 040) && seteuid(1)) {
					errstr = "seteuid(1)";
					goto bad;
				    }
				} else {
				    if (seteuid(SUDOERS_UID)) {
					errstr = "seteuid(SUDOERS_UID)";
					goto bad;
				    }
				}
			      	break;
	case PERM_TIMESTAMP:
				if (seteuid(timestamp_uid)) {
				    errstr = "seteuid(timestamp_uid)";
				    goto bad;
				}
			      	break;
    }

    current_perm = perm;
    return(1);
bad:
    warningx("%s: %s", errstr,
	errno == EAGAIN ? "too many processes" : strerror(errno));
    if (noexit)
	return(0);
    exit(1);
}

# else /* !HAVE_SETRESUID && !HAVE_SETREUID && !HAVE_SETEUID */

/*
 * Set uids and gids based on perm via setuid() and setgid().
 * NOTE: does not support the "stay_setuid" or timestampowner options.
 *       Also, SUDOERS_UID and SUDOERS_GID are not used.
 */
int
set_perms(perm)
    int perm;
{
    const char *errstr;
    int noexit;

    noexit = ISSET(perm, PERM_NOEXIT);
    CLR(perm, PERM_MASK);

    if (perm == current_perm)
	return(1);

    switch (perm) {
	case PERM_ROOT:
				if (setuid(ROOT_UID)) {
				    errstr = "setuid(ROOT_UID)";
				    goto bad;
				}
				if (current_perm == PERM_RUNAS)
				    restore_groups();
				break;

	case PERM_FULL_USER:
    	    	    	        (void) setgid(user_gid);
				if (setuid(user_uid)) {
				    errstr = "setuid(user_uid)";
				    goto bad;
				}
			      	break;
				
	case PERM_FULL_RUNAS:
				runas_setup();
				if (setuid(runas_pw->pw_uid)) {
				    errstr = "unable to change to runas uid";
				    goto bad;
				}
				break;

	case PERM_USER:
	case PERM_SUDOERS:
	case PERM_RUNAS:
	case PERM_TIMESTAMP:
				/* Unsupported since we can't set euid. */
				break;
    }

    current_perm = perm;
    return(1);
bad:
    warningx("%s: %s", errstr,
	errno == EAGAIN ? "too many processes" : strerror(errno));
    if (noexit)
	return(0);
    exit(1);
}
#  endif /* HAVE_SETEUID */
# endif /* HAVE_SETREUID */
#endif /* HAVE_SETRESUID */

#ifdef HAVE_INITGROUPS
static void
runas_setgroups()
{
    static int ngroups = -1;
# ifdef HAVE_GETGROUPS
    static GETGROUPS_T *groups;
# endif
    static struct passwd *pw;
    struct passwd *opw = pw;

    if (def_preserve_groups)
	return;

    /*
     * Use stashed copy of runas groups if available, else initgroups and stash.
     */
    pw = runas_pw ? runas_pw : sudo_user.pw;
    if (pw != opw) {
# ifdef HAVE_SETAUTHDB
	aix_setauthdb(pw->pw_name);
# endif
	if (initgroups(pw->pw_name, pw->pw_gid) < 0)
	    log_error(USE_ERRNO|MSG_ONLY, "can't set runas group vector");
# ifdef HAVE_GETGROUPS
	if (groups) {
	    efree(groups);
	    groups = NULL;
	}
	if ((ngroups = getgroups(0, NULL)) > 0) {
	    groups = emalloc2(ngroups, sizeof(GETGROUPS_T));
	    if (getgroups(ngroups, groups) < 0)
		log_error(USE_ERRNO|MSG_ONLY, "can't get runas group vector");
	}
#  ifdef HAVE_SETAUTHDB
	aix_restoreauthdb();
#  endif
    } else {
	if (setgroups(ngroups, groups) < 0)
	    log_error(USE_ERRNO|MSG_ONLY, "can't set runas group vector");
# endif /* HAVE_GETGROUPS */
    }
}

static void
restore_groups()
{
    if (user_ngroups >= 0 && setgroups(user_ngroups, user_groups) < 0)
	log_error(USE_ERRNO|MSG_ONLY, "can't reset user group vector");
}

#else

static void
runas_setgroups()
{
    /* STUB */
}

static void
restore_groups()
{
    /* STUB */
}

#endif /* HAVE_INITGROUPS */

static void
runas_setup()
{
    gid_t gid;
#ifdef HAVE_LOGIN_CAP_H
    int flags;
    extern login_cap_t *lc;
#endif

    if (runas_pw->pw_name != NULL) {
	gid = runas_gr ? runas_gr->gr_gid : runas_pw->pw_gid;
#ifdef HAVE_GETUSERATTR
	aix_prep_user(runas_pw->pw_name, user_ttypath);
#endif
#ifdef HAVE_PAM
	pam_begin_session(runas_pw);
#endif /* HAVE_PAM */

#ifdef HAVE_LOGIN_CAP_H
	if (def_use_loginclass) {
	    /*
             * We only use setusercontext() to set the nice value and rlimits.
	     */
	    flags = LOGIN_SETRESOURCES|LOGIN_SETPRIORITY;
	    if (setusercontext(lc, runas_pw, runas_pw->pw_uid, flags)) {
		if (runas_pw->pw_uid != ROOT_UID)
		    error(1, "unable to set user context");
		else
		    warning("unable to set user context");
	    }
	}
#endif /* HAVE_LOGIN_CAP_H */
	/*
	 * Initialize group vector
	 */
	runas_setgroups();
#ifdef HAVE_SETEUID
	if (setegid(gid))
	    warning("cannot set egid to runas gid");
#endif
	if (setgid(gid))
	    warning("cannot set gid to runas gid");
    }
}
