]> granicus.if.org Git - sudo/commitdiff
Primitive set/restore permissions. Will be replaced by a push/pop
authorTodd C. Miller <Todd.Miller@courtesan.com>
Sat, 10 Apr 2010 14:34:37 +0000 (10:34 -0400)
committerTodd C. Miller <Todd.Miller@courtesan.com>
Sat, 10 Apr 2010 14:34:37 +0000 (10:34 -0400)
model.

plugins/sudoers/check.c
plugins/sudoers/logging.c
plugins/sudoers/parse.c
plugins/sudoers/set_perms.c
plugins/sudoers/sudoers.c
plugins/sudoers/sudoers.h

index 161d86e5d859059ec413b53fea6d7cf03f49bef0..8aafa28aa068db1d07995196bd9d6934b6bfbb28 100644 (file)
@@ -215,7 +215,7 @@ update_timestamp(timestampdir, timestampfile)
        }
     }
     if (timestamp_uid != 0)
-       set_perms(PERM_ROOT);
+       restore_perms();
 }
 
 /*
@@ -464,11 +464,8 @@ timestamp_status(timestampdir, timestampfile, user, flags)
                status = TS_MISSING;
        }
     }
-    if (status == TS_ERROR) {
-       if (timestamp_uid != 0)
-           set_perms(PERM_ROOT);
-       return(status);
-    }
+    if (status == TS_ERROR)
+       goto done;
 
     /*
      * Sanity check the user's ticket dir.  We start by downgrading
@@ -592,7 +589,7 @@ timestamp_status(timestampdir, timestampfile, user, flags)
 
 done:
     if (timestamp_uid != 0)
-       set_perms(PERM_ROOT);
+       restore_perms();
     return(status);
 }
 
index 6caf0cd6e2071a14708d1758a875b7227bb929ef..eb8d1f8298b30e9d51561de22f098fa149f8ffed 100644 (file)
@@ -406,7 +406,7 @@ log_error(flags, fmt, va_alist)
 
     efree(logline);
 
-    set_perms(PERM_USER);
+    restore_perms();
 
     if (!ISSET(flags, NO_EXIT)) {
        cleanup(0);
index f7ea49e4c15ee979e773970970f1f149851bc374..0278cd76e98b4aff9a49d9ce9096abbf3e82481a 100644 (file)
@@ -257,7 +257,7 @@ sudo_file_lookup(nss, validated, pwflag)
        SET(validated, VALIDATE_NOT_OK);
        CLR(validated, VALIDATE_OK);
     }
-    set_perms(PERM_ROOT);
+    restore_perms();
     return(validated);
 }
 
index d3b2c2b876438451c408654ab0ed4c2a840d85e1..6956237b22682ea84a3fed4680ab995843afce05 100644 (file)
@@ -66,7 +66,38 @@ static void runas_setup(void);
 static void runas_setgroups(void);
 static void restore_groups(void);
 
-static int current_perm = -1;
+/*
+ * We keep track of the current permisstions and use a stack to restore
+ * the old permissions.  A depth of 16 is overkill.
+ */
+#define PERM_STACK_MAX 16
+static int perm_stack[PERM_STACK_MAX];
+static int perm_stack_depth = 0;
+static int perm_current = PERM_INITIAL;
+
+/*
+ * XXX - better to push what we've changed:
+ *     ruid, euid, suid, gids group vector.
+ */
+
+int
+restore_perms(void)
+{
+    int old_perm;
+
+    if (!perm_stack_depth) {
+       /* nothing to do */
+       return TRUE;
+    }
+    old_perm = perm_stack[--perm_stack_depth];
+    return set_perms2(old_perm, FALSE);
+}
+
+int
+set_perms(int perm)
+{
+    return set_perms2(perm, TRUE);
+}
 
 #ifdef HAVE_SETRESUID
 /*
@@ -76,8 +107,7 @@ static int current_perm = -1;
  * This version of set_perms() works fine with the "stay_setuid" option.
  */
 int
-set_perms(perm)
-    int perm;
+set_perms2(int perm, int push_it)
 {
     const char *errstr;
     int noexit;
@@ -85,17 +115,32 @@ set_perms(perm)
     noexit = ISSET(perm, PERM_NOEXIT);
     CLR(perm, PERM_MASK);
 
-    if (perm == current_perm)
-       return(1);
+    if (perm_stack_depth == PERM_STACK_MAX) {
+       errno = EINVAL;
+       goto bad;
+    }
+    if (perm == perm_current)
+       goto done;
 
     switch (perm) {
+       case PERM_INITIAL:
+                               /* Setuid root */
+                               if (setuid(ROOT_UID)) {
+                                   errstr = "setuid(ROOT_UID)";
+                                   goto bad;
+                               }
+                               (void) setresgid(-1, user_gid, -1);
+                               if (perm_current == PERM_RUNAS)
+                                   restore_groups();
+                               (void) setresuid(user_uid, -1, -1);
+                               break;
        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)
+                               if (perm_current == PERM_RUNAS)
                                    restore_groups();
                                break;
 
@@ -172,7 +217,10 @@ set_perms(perm)
                                break;
     }
 
-    current_perm = perm;
+done:
+    if (push_it)
+       perm_stack[perm_stack_depth++] = perm_current;
+    perm_current = perm;
     return(1);
 bad:
     warningx("%s: %s", errstr,
@@ -201,7 +249,7 @@ set_perms(perm)
     noexit = ISSET(perm, PERM_NOEXIT);
     CLR(perm, PERM_MASK);
 
-    if (perm == current_perm)
+    if (perm == perm_current)
        return(1);
 
     switch (perm) {
@@ -215,7 +263,7 @@ set_perms(perm)
                                    goto bad;
                                }
                                (void) setregid(-1, user_gid);
-                               if (current_perm == PERM_RUNAS)
+                               if (perm_current == PERM_RUNAS)
                                    restore_groups();
                                break;
 
@@ -291,7 +339,7 @@ set_perms(perm)
                                break;
     }
 
-    current_perm = perm;
+    perm_current = perm;
     return(1);
 bad:
     warningx("%s: %s", errstr,
@@ -318,7 +366,7 @@ set_perms(perm)
     noexit = ISSET(perm, PERM_NOEXIT);
     CLR(perm, PERM_MASK);
 
-    if (perm == current_perm)
+    if (perm == perm_current)
        return(1);
 
     /*
@@ -339,7 +387,7 @@ set_perms(perm)
        case PERM_ROOT:
                                /* uid set above */
                                (void) setegid(user_gid);
-                               if (current_perm == PERM_RUNAS)
+                               if (perm_current == PERM_RUNAS)
                                    restore_groups();
                                break;
 
@@ -412,7 +460,7 @@ set_perms(perm)
                                break;
     }
 
-    current_perm = perm;
+    perm_current = perm;
     return(1);
 bad:
     warningx("%s: %s", errstr,
@@ -439,7 +487,7 @@ set_perms(perm)
     noexit = ISSET(perm, PERM_NOEXIT);
     CLR(perm, PERM_MASK);
 
-    if (perm == current_perm)
+    if (perm == perm_current)
        return(1);
 
     switch (perm) {
@@ -448,7 +496,7 @@ set_perms(perm)
                                    errstr = "setuid(ROOT_UID)";
                                    goto bad;
                                }
-                               if (current_perm == PERM_RUNAS)
+                               if (perm_current == PERM_RUNAS)
                                    restore_groups();
                                break;
 
@@ -478,7 +526,7 @@ set_perms(perm)
                                break;
     }
 
-    current_perm = perm;
+    perm_current = perm;
     return(1);
 bad:
     warningx("%s: %s", errstr,
index f04439b8906ac18f06259078b7b6e86aa6c8f5a0..232080d02a555a0fc4ab603372c616c2b1b451b8 100644 (file)
@@ -737,12 +737,12 @@ set_cmnd(sudo_mode)
        if (ISSET(sudo_mode, MODE_RUN | MODE_CHECK)) {
            set_perms(PERM_RUNAS);
            rval = find_path(NewArgv[0], &user_cmnd, user_stat, user_path);
-           set_perms(PERM_ROOT);
+           restore_perms();
            if (rval != FOUND) {
                /* Failed as root, try as invoking user. */
                set_perms(PERM_USER);
                rval = find_path(NewArgv[0], &user_cmnd, user_stat, user_path);
-               set_perms(PERM_ROOT);
+               restore_perms();
            }
        }
 
@@ -855,7 +855,7 @@ open_sudoers(sudoers, doedit, keepopen)
        (void) fcntl(fileno(fp), F_SETFD, 1);
     }
 
-    set_perms(PERM_ROOT);              /* change back to root */
+    restore_perms();           /* change back to root */
     return(fp);
 }
 
index 5a7fc10b900a000f549fa786e67e369180edd0cd..77b121a38e25b451d8393276fb3fd643addbe34e 100644 (file)
@@ -136,13 +136,14 @@ struct sudo_user {
 /*
  * Used with set_perms()
  */
-#define PERM_ROOT                0x00
-#define PERM_USER                0x01
-#define PERM_FULL_USER           0x02
-#define PERM_SUDOERS             0x03
-#define PERM_RUNAS               0x04
-#define PERM_FULL_RUNAS          0x05
-#define PERM_TIMESTAMP           0x06
+#define PERM_INITIAL             0x00
+#define PERM_ROOT                0x01
+#define PERM_USER                0x02
+#define PERM_FULL_USER           0x03
+#define PERM_SUDOERS             0x04
+#define PERM_RUNAS               0x05
+#define PERM_FULL_RUNAS          0x06
+#define PERM_TIMESTAMP           0x07
 #define PERM_NOEXIT              0x10 /* flag */
 #define PERM_MASK                0xf0
 
@@ -236,6 +237,7 @@ int sudo_file_display_defaults(struct sudo_nss *, struct passwd *, struct lbuf *
 int sudo_file_display_bound_defaults(struct sudo_nss *, struct passwd *, struct lbuf *);
 int sudo_file_display_privs(struct sudo_nss *, struct passwd *, struct lbuf *);
 int set_perms(int);
+int restore_perms(void);
 void remove_timestamp(int);
 int check_secureware(char *);
 void sia_attempt_auth(void);