From: Todd C. Miller Date: Fri, 3 May 2002 22:48:17 +0000 (+0000) Subject: Add support for non-root timestamp dirs. This allows the timestamp X-Git-Tag: SUDO_1_6_7~131 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=a30951d34ce09a934871103a0f03e251b5d68c18;p=sudo Add support for non-root timestamp dirs. This allows the timestamp dir to be shared via NFS (though this is not recommended). --- diff --git a/check.c b/check.c index 837ad5b5a..f673b6222 100644 --- 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); } diff --git a/set_perms.c b/set_perms.c index b34fc95b4..94462e7bb 100644 --- a/set_perms.c +++ b/set_perms.c @@ -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 b216d8a18..15aaf9177 100644 --- 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 dc0db0ceb..79fe62075 100644 --- 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