Primitive set/restore permissions. Will be replaced by a push/pop

model.
This commit is contained in:
Todd C. Miller
2010-04-10 10:34:37 -04:00
parent 711b8d1c04
commit 744eae82e7
6 changed files with 82 additions and 35 deletions

View File

@@ -215,7 +215,7 @@ update_timestamp(timestampdir, timestampfile)
} }
} }
if (timestamp_uid != 0) if (timestamp_uid != 0)
set_perms(PERM_ROOT); restore_perms();
} }
/* /*
@@ -464,11 +464,8 @@ timestamp_status(timestampdir, timestampfile, user, flags)
status = TS_MISSING; status = TS_MISSING;
} }
} }
if (status == TS_ERROR) { if (status == TS_ERROR)
if (timestamp_uid != 0) goto done;
set_perms(PERM_ROOT);
return(status);
}
/* /*
* Sanity check the user's ticket dir. We start by downgrading * Sanity check the user's ticket dir. We start by downgrading
@@ -592,7 +589,7 @@ timestamp_status(timestampdir, timestampfile, user, flags)
done: done:
if (timestamp_uid != 0) if (timestamp_uid != 0)
set_perms(PERM_ROOT); restore_perms();
return(status); return(status);
} }

View File

@@ -406,7 +406,7 @@ log_error(flags, fmt, va_alist)
efree(logline); efree(logline);
set_perms(PERM_USER); restore_perms();
if (!ISSET(flags, NO_EXIT)) { if (!ISSET(flags, NO_EXIT)) {
cleanup(0); cleanup(0);

View File

@@ -257,7 +257,7 @@ sudo_file_lookup(nss, validated, pwflag)
SET(validated, VALIDATE_NOT_OK); SET(validated, VALIDATE_NOT_OK);
CLR(validated, VALIDATE_OK); CLR(validated, VALIDATE_OK);
} }
set_perms(PERM_ROOT); restore_perms();
return(validated); return(validated);
} }

View File

@@ -66,7 +66,38 @@ static void runas_setup(void);
static void runas_setgroups(void); static void runas_setgroups(void);
static void restore_groups(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 #ifdef HAVE_SETRESUID
/* /*
@@ -76,8 +107,7 @@ static int current_perm = -1;
* This version of set_perms() works fine with the "stay_setuid" option. * This version of set_perms() works fine with the "stay_setuid" option.
*/ */
int int
set_perms(perm) set_perms2(int perm, int push_it)
int perm;
{ {
const char *errstr; const char *errstr;
int noexit; int noexit;
@@ -85,17 +115,32 @@ set_perms(perm)
noexit = ISSET(perm, PERM_NOEXIT); noexit = ISSET(perm, PERM_NOEXIT);
CLR(perm, PERM_MASK); CLR(perm, PERM_MASK);
if (perm == current_perm) if (perm_stack_depth == PERM_STACK_MAX) {
return(1); errno = EINVAL;
goto bad;
}
if (perm == perm_current)
goto done;
switch (perm) { 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: case PERM_ROOT:
if (setresuid(ROOT_UID, ROOT_UID, ROOT_UID)) { if (setresuid(ROOT_UID, ROOT_UID, ROOT_UID)) {
errstr = "setresuid(ROOT_UID, ROOT_UID, ROOT_UID)"; errstr = "setresuid(ROOT_UID, ROOT_UID, ROOT_UID)";
goto bad; goto bad;
} }
(void) setresgid(-1, user_gid, -1); (void) setresgid(-1, user_gid, -1);
if (current_perm == PERM_RUNAS) if (perm_current == PERM_RUNAS)
restore_groups(); restore_groups();
break; break;
@@ -172,7 +217,10 @@ set_perms(perm)
break; break;
} }
current_perm = perm; done:
if (push_it)
perm_stack[perm_stack_depth++] = perm_current;
perm_current = perm;
return(1); return(1);
bad: bad:
warningx("%s: %s", errstr, warningx("%s: %s", errstr,
@@ -201,7 +249,7 @@ set_perms(perm)
noexit = ISSET(perm, PERM_NOEXIT); noexit = ISSET(perm, PERM_NOEXIT);
CLR(perm, PERM_MASK); CLR(perm, PERM_MASK);
if (perm == current_perm) if (perm == perm_current)
return(1); return(1);
switch (perm) { switch (perm) {
@@ -215,7 +263,7 @@ set_perms(perm)
goto bad; goto bad;
} }
(void) setregid(-1, user_gid); (void) setregid(-1, user_gid);
if (current_perm == PERM_RUNAS) if (perm_current == PERM_RUNAS)
restore_groups(); restore_groups();
break; break;
@@ -291,7 +339,7 @@ set_perms(perm)
break; break;
} }
current_perm = perm; perm_current = perm;
return(1); return(1);
bad: bad:
warningx("%s: %s", errstr, warningx("%s: %s", errstr,
@@ -318,7 +366,7 @@ set_perms(perm)
noexit = ISSET(perm, PERM_NOEXIT); noexit = ISSET(perm, PERM_NOEXIT);
CLR(perm, PERM_MASK); CLR(perm, PERM_MASK);
if (perm == current_perm) if (perm == perm_current)
return(1); return(1);
/* /*
@@ -339,7 +387,7 @@ set_perms(perm)
case PERM_ROOT: case PERM_ROOT:
/* uid set above */ /* uid set above */
(void) setegid(user_gid); (void) setegid(user_gid);
if (current_perm == PERM_RUNAS) if (perm_current == PERM_RUNAS)
restore_groups(); restore_groups();
break; break;
@@ -412,7 +460,7 @@ set_perms(perm)
break; break;
} }
current_perm = perm; perm_current = perm;
return(1); return(1);
bad: bad:
warningx("%s: %s", errstr, warningx("%s: %s", errstr,
@@ -439,7 +487,7 @@ set_perms(perm)
noexit = ISSET(perm, PERM_NOEXIT); noexit = ISSET(perm, PERM_NOEXIT);
CLR(perm, PERM_MASK); CLR(perm, PERM_MASK);
if (perm == current_perm) if (perm == perm_current)
return(1); return(1);
switch (perm) { switch (perm) {
@@ -448,7 +496,7 @@ set_perms(perm)
errstr = "setuid(ROOT_UID)"; errstr = "setuid(ROOT_UID)";
goto bad; goto bad;
} }
if (current_perm == PERM_RUNAS) if (perm_current == PERM_RUNAS)
restore_groups(); restore_groups();
break; break;
@@ -478,7 +526,7 @@ set_perms(perm)
break; break;
} }
current_perm = perm; perm_current = perm;
return(1); return(1);
bad: bad:
warningx("%s: %s", errstr, warningx("%s: %s", errstr,

View File

@@ -737,12 +737,12 @@ set_cmnd(sudo_mode)
if (ISSET(sudo_mode, MODE_RUN | MODE_CHECK)) { if (ISSET(sudo_mode, MODE_RUN | MODE_CHECK)) {
set_perms(PERM_RUNAS); set_perms(PERM_RUNAS);
rval = find_path(NewArgv[0], &user_cmnd, user_stat, user_path); rval = find_path(NewArgv[0], &user_cmnd, user_stat, user_path);
set_perms(PERM_ROOT); restore_perms();
if (rval != FOUND) { if (rval != FOUND) {
/* Failed as root, try as invoking user. */ /* Failed as root, try as invoking user. */
set_perms(PERM_USER); set_perms(PERM_USER);
rval = find_path(NewArgv[0], &user_cmnd, user_stat, user_path); 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); (void) fcntl(fileno(fp), F_SETFD, 1);
} }
set_perms(PERM_ROOT); /* change back to root */ restore_perms(); /* change back to root */
return(fp); return(fp);
} }

View File

@@ -136,13 +136,14 @@ struct sudo_user {
/* /*
* Used with set_perms() * Used with set_perms()
*/ */
#define PERM_ROOT 0x00 #define PERM_INITIAL 0x00
#define PERM_USER 0x01 #define PERM_ROOT 0x01
#define PERM_FULL_USER 0x02 #define PERM_USER 0x02
#define PERM_SUDOERS 0x03 #define PERM_FULL_USER 0x03
#define PERM_RUNAS 0x04 #define PERM_SUDOERS 0x04
#define PERM_FULL_RUNAS 0x05 #define PERM_RUNAS 0x05
#define PERM_TIMESTAMP 0x06 #define PERM_FULL_RUNAS 0x06
#define PERM_TIMESTAMP 0x07
#define PERM_NOEXIT 0x10 /* flag */ #define PERM_NOEXIT 0x10 /* flag */
#define PERM_MASK 0xf0 #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_bound_defaults(struct sudo_nss *, struct passwd *, struct lbuf *);
int sudo_file_display_privs(struct sudo_nss *, struct passwd *, struct lbuf *); int sudo_file_display_privs(struct sudo_nss *, struct passwd *, struct lbuf *);
int set_perms(int); int set_perms(int);
int restore_perms(void);
void remove_timestamp(int); void remove_timestamp(int);
int check_secureware(char *); int check_secureware(char *);
void sia_attempt_auth(void); void sia_attempt_auth(void);