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

View File

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

View File

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

View File

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

View File

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

View File

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