]> granicus.if.org Git - sudo/commitdiff
Add support for non-root timestamp dirs. This allows the timestamp
authorTodd C. Miller <Todd.Miller@courtesan.com>
Fri, 3 May 2002 22:48:17 +0000 (22:48 +0000)
committerTodd C. Miller <Todd.Miller@courtesan.com>
Fri, 3 May 2002 22:48:17 +0000 (22:48 +0000)
dir to be shared via NFS (though this is not recommended).

check.c
set_perms.c
sudo.c
sudo.h

diff --git a/check.c b/check.c
index 837ad5b5a6dfbd6be4580e9b8aad8f16f9d2016c..f673b6222491195679d43bcc9b4835323f2d3ad3 100644 (file)
--- a/check.c
+++ b/check.c
@@ -145,6 +145,7 @@ update_timestamp(timestampdir, timestampfile)
     char *timestampfile;
 {
 
+    set_perms(PERM_TIMESTAMP, 0);
     if (touch(timestampfile ? timestampfile : timestampdir, time(NULL)) == -1) {
        if (timestampfile) {
            int fd = open(timestampfile, O_WRONLY|O_CREAT|O_TRUNC, 0600);
@@ -158,6 +159,7 @@ update_timestamp(timestampdir, timestampfile)
                log_error(NO_EXIT|USE_ERRNO, "Can't mkdir %s", timestampdir);
        }
     }
+    set_perms(PERM_ROOT, 0);
 }
 
 /*
@@ -307,6 +309,8 @@ timestamp_status(timestampdir, timestampfile, user, make_dirs)
     char *dirparent = def_str(I_TIMESTAMPDIR);
     int status = TS_ERROR;             /* assume the worst */
 
+    set_perms(PERM_TIMESTAMP, 0);
+
     /*
      * Sanity check dirparent and make it if it doesn't already exist.
      * We start out assuming the worst (that the dir is not sane) and
@@ -318,9 +322,9 @@ timestamp_status(timestampdir, timestampfile, user, make_dirs)
        if (!S_ISDIR(sb.st_mode))
            log_error(NO_EXIT, "%s exists but is not a directory (0%o)",
                dirparent, sb.st_mode);
-       else if (sb.st_uid != 0)
-           log_error(NO_EXIT, "%s owned by uid %ld, should be owned by root",
-               dirparent, (long) sb.st_uid);
+       else if (sb.st_uid != timestamp_uid)
+           log_error(NO_EXIT, "%s owned by uid %ld, should be uid %ld",
+               dirparent, (long) sb.st_uid, (long) timestamp_uid);
        else if ((sb.st_mode & 0000022))
            log_error(NO_EXIT,
                "%s writable by non-owner (0%o), should be mode 0700",
@@ -342,8 +346,10 @@ timestamp_status(timestampdir, timestampfile, user, make_dirs)
                status = TS_MISSING;
        }
     }
-    if (status == TS_ERROR)
+    if (status == TS_ERROR) {
+       set_perms(PERM_ROOT, 0);
        return(status);
+    }
 
     /*
      * Sanity check the user's ticket dir.  We start by downgrading
@@ -361,9 +367,9 @@ timestamp_status(timestampdir, timestampfile, user, make_dirs)
            } else
                log_error(NO_EXIT, "%s exists but is not a directory (0%o)",
                    timestampdir, sb.st_mode);
-       } else if (sb.st_uid != 0)
-           log_error(NO_EXIT, "%s owned by uid %ld, should be owned by root",
-               timestampdir, (long) sb.st_uid);
+       } else if (sb.st_uid != timestamp_uid)
+           log_error(NO_EXIT, "%s owned by uid %ld, should be uid %ld",
+               timestampdir, (long) sb.st_uid, (long) timestamp_uid);
        else if ((sb.st_mode & 0000022))
            log_error(NO_EXIT,
                "%s writable by non-owner (0%o), should be mode 0700",
@@ -402,10 +408,10 @@ timestamp_status(timestampdir, timestampfile, user, make_dirs)
                    timestampfile, sb.st_mode);
            } else {
                /* If bad uid or file mode, complain and kill the bogus file. */
-               if (sb.st_uid != 0) {
+               if (sb.st_uid != timestamp_uid) {
                    log_error(NO_EXIT,
-                       "%s owned by uid %ld, should be owned by root",
-                       timestampfile, (long) sb.st_uid);
+                       "%s owned by uid %ld, should be uid %ld",
+                       timestampfile, (long) sb.st_uid, (long) timestamp_uid);
                    (void) unlink(timestampfile);
                } else if ((sb.st_mode & 0000022)) {
                    log_error(NO_EXIT,
@@ -456,6 +462,7 @@ timestamp_status(timestampdir, timestampfile, user, make_dirs)
        }
     }
 
+    set_perms(PERM_ROOT, 0);
     return(status);
 }
 
index b34fc95b4ad60a748cd4e71f6fccf73f6235a052..94462e7bbfe27900c87fee55f845d07e59bf191b 100644 (file)
@@ -145,6 +145,11 @@ set_perms_posix(perm, sudo_mode)
                                        fatal("seteuid(SUDOERS_UID)", 1);
                                }
                                break;
+       case PERM_TIMESTAMP:
+                               if (seteuid(timestamp_uid))
+                                   fatal("seteuid(timestamp_uid)", 1);
+                               break;
+
     }
 }
 #endif /* !NO_SAVED_IDS && _SC_SAVED_IDS && _SC_VERSION */
@@ -213,6 +218,10 @@ set_perms_fallback(perm, sudo_mode)
                                        fatal("setreuid(0, SUDOERS_UID)", 1);
                                }
                                break;
+       case PERM_TIMESTAMP:
+                               if (setreuid(0, timestamp_uid))
+                                   fatal("setreuid(0, timestamp_uid)", 1);
+                               break;
     }
 }
 
@@ -276,6 +285,10 @@ set_perms_fallback(perm, sudo_mode)
                                        fatal("seteuid(SUDOERS_UID)", 1);
                                }
                                break;
+       case PERM_TIMESTAMP:
+                               if (seteuid(timestamp_uid))
+                                   fatal("seteuid(timestamp_uid)", 1);
+                               break;
     }
 }
 #endif /* HAVE_SETREUID */
diff --git a/sudo.c b/sudo.c
index b216d8a1898c962696821202c4cb6d027365b058..15aaf9177800d237759ae1e7ddb6819ff9334445 100644 (file)
--- a/sudo.c
+++ b/sudo.c
@@ -131,6 +131,7 @@ FILE *sudoers_fp = NULL;
 struct interface *interfaces;
 int num_interfaces;
 int tgetpass_flags;
+int timestamp_uid;
 extern int errorlineno;
 #if defined(RLIMIT_CORE) && !defined(SUDO_DEVEL)
 static struct rlimit corelimit;
@@ -287,6 +288,22 @@ main(argc, argv, envp)
            log_error(NO_MAIL|MSG_ONLY, "no passwd entry for %s!", *user_runas);
     }
 
+    /*
+     * Look up the timestamp dir owner if one is specified.
+     */
+    if (def_str(I_TIMESTAMPOWNER)) {
+       struct passwd *pw;
+
+       if (*def_str(I_TIMESTAMPOWNER) == '#')
+           pw = getpwuid(atoi(def_str(I_TIMESTAMPOWNER) + 1));
+       else
+           pw = getpwnam(def_str(I_TIMESTAMPOWNER));
+       if (!pw)
+           log_error(0, "timestamp owner (%s): No such user",
+               def_str(I_TIMESTAMPOWNER));
+       timestamp_uid = pw->pw_uid;
+    }
+
     /* This goes after the sudoers parse since we honor sudoers options. */
     if (sudo_mode == MODE_KILL || sudo_mode == MODE_INVALIDATE) {
        remove_timestamp((sudo_mode == MODE_KILL));
diff --git a/sudo.h b/sudo.h
index dc0db0ceb1ef89b9cbd26520cb6170a224c9bbe9..79fe62075f28fc0863dd81926aabf2be890f80cd 100644 (file)
--- a/sudo.h
+++ b/sudo.h
@@ -116,6 +116,7 @@ struct sudo_user {
 #define PERM_FULL_USER           0x03
 #define PERM_SUDOERS             0x04
 #define PERM_RUNAS               0x05
+#define PERM_TIMESTAMP           0x06
 
 /*
  * Shortcuts for sudo_user contents.
@@ -235,6 +236,7 @@ extern int Argc;
 extern char **Argv;
 extern FILE *sudoers_fp;
 extern int tgetpass_flags;
+extern int timestamp_uid;
 
 extern void (*set_perms) __P((int, int));
 #endif