Add support for non-root timestamp dirs. This allows the timestamp

dir to be shared via NFS (though this is not recommended).
This commit is contained in:
Todd C. Miller
2002-05-03 22:48:17 +00:00
parent 15965c2ce7
commit a30951d34c
4 changed files with 49 additions and 10 deletions

27
check.c
View File

@@ -145,6 +145,7 @@ update_timestamp(timestampdir, timestampfile)
char *timestampfile; char *timestampfile;
{ {
set_perms(PERM_TIMESTAMP, 0);
if (touch(timestampfile ? timestampfile : timestampdir, time(NULL)) == -1) { if (touch(timestampfile ? timestampfile : timestampdir, time(NULL)) == -1) {
if (timestampfile) { if (timestampfile) {
int fd = open(timestampfile, O_WRONLY|O_CREAT|O_TRUNC, 0600); 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); 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); char *dirparent = def_str(I_TIMESTAMPDIR);
int status = TS_ERROR; /* assume the worst */ int status = TS_ERROR; /* assume the worst */
set_perms(PERM_TIMESTAMP, 0);
/* /*
* Sanity check dirparent and make it if it doesn't already exist. * 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 * 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)) if (!S_ISDIR(sb.st_mode))
log_error(NO_EXIT, "%s exists but is not a directory (0%o)", log_error(NO_EXIT, "%s exists but is not a directory (0%o)",
dirparent, sb.st_mode); dirparent, sb.st_mode);
else if (sb.st_uid != 0) else if (sb.st_uid != timestamp_uid)
log_error(NO_EXIT, "%s owned by uid %ld, should be owned by root", log_error(NO_EXIT, "%s owned by uid %ld, should be uid %ld",
dirparent, (long) sb.st_uid); dirparent, (long) sb.st_uid, (long) timestamp_uid);
else if ((sb.st_mode & 0000022)) else if ((sb.st_mode & 0000022))
log_error(NO_EXIT, log_error(NO_EXIT,
"%s writable by non-owner (0%o), should be mode 0700", "%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; status = TS_MISSING;
} }
} }
if (status == TS_ERROR) if (status == TS_ERROR) {
set_perms(PERM_ROOT, 0);
return(status); return(status);
}
/* /*
* Sanity check the user's ticket dir. We start by downgrading * Sanity check the user's ticket dir. We start by downgrading
@@ -361,9 +367,9 @@ timestamp_status(timestampdir, timestampfile, user, make_dirs)
} else } else
log_error(NO_EXIT, "%s exists but is not a directory (0%o)", log_error(NO_EXIT, "%s exists but is not a directory (0%o)",
timestampdir, sb.st_mode); timestampdir, sb.st_mode);
} else if (sb.st_uid != 0) } else if (sb.st_uid != timestamp_uid)
log_error(NO_EXIT, "%s owned by uid %ld, should be owned by root", log_error(NO_EXIT, "%s owned by uid %ld, should be uid %ld",
timestampdir, (long) sb.st_uid); timestampdir, (long) sb.st_uid, (long) timestamp_uid);
else if ((sb.st_mode & 0000022)) else if ((sb.st_mode & 0000022))
log_error(NO_EXIT, log_error(NO_EXIT,
"%s writable by non-owner (0%o), should be mode 0700", "%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); timestampfile, sb.st_mode);
} else { } else {
/* If bad uid or file mode, complain and kill the bogus file. */ /* 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, log_error(NO_EXIT,
"%s owned by uid %ld, should be owned by root", "%s owned by uid %ld, should be uid %ld",
timestampfile, (long) sb.st_uid); timestampfile, (long) sb.st_uid, (long) timestamp_uid);
(void) unlink(timestampfile); (void) unlink(timestampfile);
} else if ((sb.st_mode & 0000022)) { } else if ((sb.st_mode & 0000022)) {
log_error(NO_EXIT, log_error(NO_EXIT,
@@ -456,6 +462,7 @@ timestamp_status(timestampdir, timestampfile, user, make_dirs)
} }
} }
set_perms(PERM_ROOT, 0);
return(status); return(status);
} }

View File

@@ -145,6 +145,11 @@ set_perms_posix(perm, sudo_mode)
fatal("seteuid(SUDOERS_UID)", 1); fatal("seteuid(SUDOERS_UID)", 1);
} }
break; break;
case PERM_TIMESTAMP:
if (seteuid(timestamp_uid))
fatal("seteuid(timestamp_uid)", 1);
break;
} }
} }
#endif /* !NO_SAVED_IDS && _SC_SAVED_IDS && _SC_VERSION */ #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); fatal("setreuid(0, SUDOERS_UID)", 1);
} }
break; 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); fatal("seteuid(SUDOERS_UID)", 1);
} }
break; break;
case PERM_TIMESTAMP:
if (seteuid(timestamp_uid))
fatal("seteuid(timestamp_uid)", 1);
break;
} }
} }
#endif /* HAVE_SETREUID */ #endif /* HAVE_SETREUID */

17
sudo.c
View File

@@ -131,6 +131,7 @@ FILE *sudoers_fp = NULL;
struct interface *interfaces; struct interface *interfaces;
int num_interfaces; int num_interfaces;
int tgetpass_flags; int tgetpass_flags;
int timestamp_uid;
extern int errorlineno; extern int errorlineno;
#if defined(RLIMIT_CORE) && !defined(SUDO_DEVEL) #if defined(RLIMIT_CORE) && !defined(SUDO_DEVEL)
static struct rlimit corelimit; 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); 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. */ /* This goes after the sudoers parse since we honor sudoers options. */
if (sudo_mode == MODE_KILL || sudo_mode == MODE_INVALIDATE) { if (sudo_mode == MODE_KILL || sudo_mode == MODE_INVALIDATE) {
remove_timestamp((sudo_mode == MODE_KILL)); remove_timestamp((sudo_mode == MODE_KILL));

2
sudo.h
View File

@@ -116,6 +116,7 @@ struct sudo_user {
#define PERM_FULL_USER 0x03 #define PERM_FULL_USER 0x03
#define PERM_SUDOERS 0x04 #define PERM_SUDOERS 0x04
#define PERM_RUNAS 0x05 #define PERM_RUNAS 0x05
#define PERM_TIMESTAMP 0x06
/* /*
* Shortcuts for sudo_user contents. * Shortcuts for sudo_user contents.
@@ -235,6 +236,7 @@ extern int Argc;
extern char **Argv; extern char **Argv;
extern FILE *sudoers_fp; extern FILE *sudoers_fp;
extern int tgetpass_flags; extern int tgetpass_flags;
extern int timestamp_uid;
extern void (*set_perms) __P((int, int)); extern void (*set_perms) __P((int, int));
#endif #endif