Merge tag 'debian/1.8.5p2-1' into squeeze
[debian/sudo] / set_perms.c
diff --git a/set_perms.c b/set_perms.c
deleted file mode 100644 (file)
index 81e2e76..0000000
+++ /dev/null
@@ -1,593 +0,0 @@
-/*
- * 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");
-    }
-}