Replace tty_tickets option with timestamp_type which can be

global, ppid or tty.  Defaults to tty (no change in behavior).
Some users want the ppid behavior.
This commit is contained in:
Todd C. Miller
2017-08-01 16:14:54 -06:00
parent c3b3e501b9
commit 63d954d1fc
14 changed files with 308 additions and 98 deletions

View File

@@ -312,15 +312,15 @@ ts_write(int fd, const char *fname, struct timestamp_entry *entry, off_t offset)
* based on auth user pw. Does not set the time stamp.
*/
static void
ts_fill4(struct timestamp_entry *entry, struct passwd *pw, int flags, bool tty_tickets)
ts_init_key(struct timestamp_entry *entry, struct passwd *pw, int flags,
enum def_tuple ticket_type)
{
struct stat sb;
debug_decl(ts_fill4, SUDOERS_DEBUG_AUTH)
debug_decl(ts_init_key, SUDOERS_DEBUG_AUTH)
memset(entry, 0, sizeof(*entry));
entry->version = TS_VERSION;
entry->size = sizeof(*entry);
entry->type = TS_GLOBAL; /* may be overriden below */
entry->flags = flags;
if (pw != NULL) {
entry->auth_uid = pw->pw_uid;
@@ -328,31 +328,38 @@ ts_fill4(struct timestamp_entry *entry, struct passwd *pw, int flags, bool tty_t
entry->flags |= TS_ANYUID;
}
entry->sid = user_sid;
if (tty_tickets) {
switch (ticket_type) {
case tty:
if (user_ttypath != NULL && stat(user_ttypath, &sb) == 0) {
/* tty-based time stamp */
entry->type = TS_TTY;
entry->u.ttydev = sb.st_rdev;
} else {
/* ppid-based time stamp */
entry->type = TS_PPID;
entry->u.ppid = getppid();
break;
}
/* FALLTHROUGH */
case ppid:
/* ppid-based time stamp */
entry->type = TS_PPID;
entry->u.ppid = getppid();
break;
default:
/* global time stamp */
entry->type = TS_GLOBAL;
break;
}
debug_return;
}
static void
ts_fill(struct timestamp_entry *entry, struct passwd *pw, int flags)
ts_init_key_nonglobal(struct timestamp_entry *entry, struct passwd *pw, int flags)
{
ts_fill4(entry, pw, flags, def_tty_tickets);
}
static void
ts_fill_tty(struct timestamp_entry *entry, struct passwd *pw, int flags)
{
ts_fill4(entry, pw, flags, true);
/*
* Even if the timestamp type is global we still want to do per-tty
* or per-ppid locking so sudo works predictably in a pipeline.
*/
ts_init_key(entry, pw, flags,
def_timestamp_type != global ? def_timestamp_type : tty);
}
/*
@@ -602,13 +609,15 @@ timestamp_lock(void *vcookie, struct passwd *pw)
debug_return_bool(false);
}
/* Search for a tty-based record or append a new one. */
/* Search for a tty/ppid-based record or append a new one. */
sudo_debug_printf(SUDO_DEBUG_DEBUG|SUDO_DEBUG_LINENO,
"searching for tty time stamp record");
ts_fill_tty(&cookie->key, pw, TS_DISABLED);
"searching for %s time stamp record",
def_timestamp_type == ppid ? "ppid" : "tty");
ts_init_key_nonglobal(&cookie->key, pw, TS_DISABLED);
if (ts_find_record(cookie->fd, &cookie->key, &entry)) {
sudo_debug_printf(SUDO_DEBUG_DEBUG|SUDO_DEBUG_LINENO,
"found existing tty time stamp record");
"found existing %s time stamp record",
def_timestamp_type == ppid ? "ppid" : "tty");
lock_pos = lseek(cookie->fd, 0, SEEK_CUR) - (off_t)entry.size;
} else {
sudo_debug_printf(SUDO_DEBUG_DEBUG|SUDO_DEBUG_LINENO,
@@ -618,19 +627,16 @@ timestamp_lock(void *vcookie, struct passwd *pw)
debug_return_bool(false);
}
sudo_debug_printf(SUDO_DEBUG_DEBUG|SUDO_DEBUG_LINENO,
"tty time stamp position is %lld", (long long)lock_pos);
"%s time stamp position is %lld",
def_timestamp_type == ppid ? "ppid" : "tty", (long long)lock_pos);
if (def_tty_tickets) {
/* For tty tickets the tty lock is the same as the record lock. */
cookie->pos = lock_pos;
cookie->locked = true;
} else {
if (def_timestamp_type == global) {
/*
* For non-tty tickets we use a separate record lock that we
* For global tickets we use a separate record lock that we
* cannot hold long-term since it is shared between all ttys.
*/
cookie->locked = false;
cookie->key.type = TS_GLOBAL; /* find a non-tty record */
cookie->key.type = TS_GLOBAL; /* find a global record */
if (lseek(cookie->fd, 0, SEEK_SET) == -1) {
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_ERRNO|SUDO_DEBUG_LINENO,
@@ -648,6 +654,10 @@ timestamp_lock(void *vcookie, struct passwd *pw)
if (ts_write(cookie->fd, cookie->fname, &cookie->key, -1) == -1)
debug_return_bool(false);
}
} else {
/* For tty/ppid tickets the tty lock is the same as the record lock. */
cookie->pos = lock_pos;
cookie->locked = true;
}
/* Unlock the TS_LOCKEXCL record. */
@@ -872,7 +882,7 @@ timestamp_remove(bool unlink_it)
/*
* Find matching entries and invalidate them.
*/
ts_fill(&key, NULL, 0);
ts_init_key(&key, NULL, 0, def_timestamp_type);
while (ts_find_record(fd, &key, &entry)) {
/* Back up and disable the entry. */
if (!ISSET(entry.flags, TS_DISABLED)) {