Set aux group vector for PERM_RUNAS and restore group vector for
PERM_ROOT if we previously changed it. Stash the runas group vector so we don't have to call initgroups more than once. Also add no-op check to check_perms.
This commit is contained in:
@@ -353,8 +353,7 @@ log_error(flags, fmt, va_alist)
|
|||||||
va_start(ap);
|
va_start(ap);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Become root if we are not already to avoid user control */
|
/* Become root if we are not already to avoid user interference */
|
||||||
if (geteuid() != 0)
|
|
||||||
set_perms(PERM_ROOT);
|
set_perms(PERM_ROOT);
|
||||||
|
|
||||||
/* Expand printf-style format + args. */
|
/* Expand printf-style format + args. */
|
||||||
|
105
set_perms.c
105
set_perms.c
@@ -65,6 +65,10 @@ __unused static const char rcsid[] = "$Sudo$";
|
|||||||
* Prototypes
|
* Prototypes
|
||||||
*/
|
*/
|
||||||
static void runas_setup __P((void));
|
static void runas_setup __P((void));
|
||||||
|
static void runas_setgroups __P((const char *, gid_t));
|
||||||
|
static void restore_groups __P((void));
|
||||||
|
|
||||||
|
static int current_perm = -1;
|
||||||
|
|
||||||
#ifdef HAVE_SETRESUID
|
#ifdef HAVE_SETRESUID
|
||||||
/*
|
/*
|
||||||
@@ -77,11 +81,16 @@ void
|
|||||||
set_perms(perm)
|
set_perms(perm)
|
||||||
int perm;
|
int perm;
|
||||||
{
|
{
|
||||||
|
if (perm == current_perm)
|
||||||
|
return;
|
||||||
|
|
||||||
switch (perm) {
|
switch (perm) {
|
||||||
case PERM_ROOT:
|
case PERM_ROOT:
|
||||||
if (setresuid(ROOT_UID, ROOT_UID, ROOT_UID))
|
if (setresuid(ROOT_UID, ROOT_UID, ROOT_UID))
|
||||||
errorx(1, "setresuid(ROOT_UID, ROOT_UID, ROOT_UID) failed, your operating system may have a broken setresuid() function\nTry running configure with --disable-setresuid");
|
errorx(1, "setresuid(ROOT_UID, ROOT_UID, ROOT_UID) failed, your operating system may have a broken setresuid() function\nTry running configure with --disable-setresuid");
|
||||||
(void) setresgid(-1, user_gid, -1);
|
(void) setresgid(-1, user_gid, -1);
|
||||||
|
if (current_perm == PERM_RUNAS)
|
||||||
|
restore_groups();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PERM_USER:
|
case PERM_USER:
|
||||||
@@ -98,6 +107,7 @@ set_perms(perm)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case PERM_RUNAS:
|
case PERM_RUNAS:
|
||||||
|
runas_setgroups(runas_pw->pw_name, runas_pw->pw_gid);
|
||||||
(void) setresgid(-1, runas_gr ?
|
(void) setresgid(-1, runas_gr ?
|
||||||
runas_gr->gr_gid : runas_pw->pw_gid, -1);
|
runas_gr->gr_gid : runas_pw->pw_gid, -1);
|
||||||
if (setresuid(-1,
|
if (setresuid(-1,
|
||||||
@@ -139,6 +149,8 @@ set_perms(perm)
|
|||||||
error(1, "setresuid(ROOT_UID, timestamp_uid, ROOT_UID)");
|
error(1, "setresuid(ROOT_UID, timestamp_uid, ROOT_UID)");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
current_perm = perm;
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
@@ -154,6 +166,9 @@ void
|
|||||||
set_perms(perm)
|
set_perms(perm)
|
||||||
int perm;
|
int perm;
|
||||||
{
|
{
|
||||||
|
if (perm == current_perm)
|
||||||
|
return;
|
||||||
|
|
||||||
switch (perm) {
|
switch (perm) {
|
||||||
case PERM_ROOT:
|
case PERM_ROOT:
|
||||||
if (setreuid(-1, ROOT_UID))
|
if (setreuid(-1, ROOT_UID))
|
||||||
@@ -161,6 +176,8 @@ set_perms(perm)
|
|||||||
if (setuid(ROOT_UID))
|
if (setuid(ROOT_UID))
|
||||||
error(1, "setuid(ROOT_UID)");
|
error(1, "setuid(ROOT_UID)");
|
||||||
(void) setregid(-1, user_gid);
|
(void) setregid(-1, user_gid);
|
||||||
|
if (current_perm == PERM_RUNAS)
|
||||||
|
restore_groups();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PERM_USER:
|
case PERM_USER:
|
||||||
@@ -177,6 +194,7 @@ set_perms(perm)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case PERM_RUNAS:
|
case PERM_RUNAS:
|
||||||
|
runas_setgroups(runas_pw->pw_name, runas_pw->pw_gid);
|
||||||
(void) setregid(-1, runas_gr ?
|
(void) setregid(-1, runas_gr ?
|
||||||
runas_gr->gr_gid : runas_pw->pw_gid);
|
runas_gr->gr_gid : runas_pw->pw_gid);
|
||||||
if (setreuid(-1,
|
if (setreuid(-1,
|
||||||
@@ -217,6 +235,8 @@ set_perms(perm)
|
|||||||
error(1, "setreuid(ROOT_UID, timestamp_uid)");
|
error(1, "setreuid(ROOT_UID, timestamp_uid)");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
current_perm = perm;
|
||||||
}
|
}
|
||||||
|
|
||||||
# else /* !HAVE_SETRESUID && !HAVE_SETREUID */
|
# else /* !HAVE_SETRESUID && !HAVE_SETREUID */
|
||||||
@@ -230,6 +250,9 @@ void
|
|||||||
set_perms(perm)
|
set_perms(perm)
|
||||||
int perm;
|
int perm;
|
||||||
{
|
{
|
||||||
|
if (perm == current_perm)
|
||||||
|
return;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Since we only have setuid() and seteuid() and semantics
|
* Since we only have setuid() and seteuid() and semantics
|
||||||
* for these calls differ on various systems, we set
|
* for these calls differ on various systems, we set
|
||||||
@@ -244,6 +267,8 @@ 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)
|
||||||
|
restore_groups();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PERM_USER:
|
case PERM_USER:
|
||||||
@@ -260,6 +285,7 @@ set_perms(perm)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case PERM_RUNAS:
|
case PERM_RUNAS:
|
||||||
|
runas_setgroups(runas_pw->pw_name, runas_pw->pw_gid);
|
||||||
(void) setegid(runas_gr ?
|
(void) setegid(runas_gr ?
|
||||||
runas_gr->gr_gid : runas_pw->pw_gid);
|
runas_gr->gr_gid : runas_pw->pw_gid);
|
||||||
if (seteuid(runas_pw ? runas_pw->pw_uid : user_uid))
|
if (seteuid(runas_pw ? runas_pw->pw_uid : user_uid))
|
||||||
@@ -297,6 +323,8 @@ set_perms(perm)
|
|||||||
error(1, "seteuid(timestamp_uid)");
|
error(1, "seteuid(timestamp_uid)");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
current_perm = perm;
|
||||||
}
|
}
|
||||||
|
|
||||||
# else /* !HAVE_SETRESUID && !HAVE_SETREUID && !HAVE_SETEUID */
|
# else /* !HAVE_SETRESUID && !HAVE_SETREUID && !HAVE_SETEUID */
|
||||||
@@ -310,11 +338,15 @@ void
|
|||||||
set_perms(perm)
|
set_perms(perm)
|
||||||
int perm;
|
int perm;
|
||||||
{
|
{
|
||||||
|
if (perm == current_perm)
|
||||||
|
return;
|
||||||
|
|
||||||
switch (perm) {
|
switch (perm) {
|
||||||
case PERM_ROOT:
|
case PERM_ROOT:
|
||||||
if (setuid(ROOT_UID))
|
if (setuid(ROOT_UID))
|
||||||
error(1, "setuid(ROOT_UID)");
|
error(1, "setuid(ROOT_UID)");
|
||||||
|
if (current_perm == PERM_RUNAS)
|
||||||
|
restore_groups();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PERM_FULL_USER:
|
case PERM_FULL_USER:
|
||||||
@@ -336,11 +368,67 @@ set_perms(perm)
|
|||||||
/* Unsupported since we can't set euid. */
|
/* Unsupported since we can't set euid. */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
current_perm = perm;
|
||||||
}
|
}
|
||||||
# endif /* HAVE_SETEUID */
|
# endif /* HAVE_SETEUID */
|
||||||
# endif /* HAVE_SETREUID */
|
# endif /* HAVE_SETREUID */
|
||||||
#endif /* HAVE_SETRESUID */
|
#endif /* HAVE_SETRESUID */
|
||||||
|
|
||||||
|
#ifdef HAVE_INITGROUPS
|
||||||
|
static void
|
||||||
|
runas_setgroups(name, basegid)
|
||||||
|
const char *name;
|
||||||
|
gid_t basegid;
|
||||||
|
{
|
||||||
|
static int ngroups = -1;
|
||||||
|
static gid_t *groups;
|
||||||
|
|
||||||
|
if (def_preserve_groups)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Use stashed copy of runas groups if available, else initgroups and stash.
|
||||||
|
*/
|
||||||
|
if (ngroups == -1) {
|
||||||
|
if (initgroups(name, basegid) < 0)
|
||||||
|
log_error(USE_ERRNO|MSG_ONLY, "can't set runas group vector");
|
||||||
|
if ((ngroups = getgroups(0, NULL)) < 0)
|
||||||
|
log_error(USE_ERRNO|MSG_ONLY, "can't get runas ngroups");
|
||||||
|
groups = emalloc2(ngroups, MAX(sizeof(gid_t), sizeof(int)));
|
||||||
|
if (getgroups(ngroups, groups) < 0)
|
||||||
|
log_error(USE_ERRNO|MSG_ONLY, "can't get runas group vector");
|
||||||
|
} else {
|
||||||
|
if (setgroups(ngroups, groups) < 0)
|
||||||
|
log_error(USE_ERRNO|MSG_ONLY, "can't set runas group vector");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
restore_groups()
|
||||||
|
{
|
||||||
|
if (setgroups(user_ngroups, user_groups) < 0)
|
||||||
|
log_error(USE_ERRNO|MSG_ONLY, "can't reset user group vector");
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
static void
|
||||||
|
runas_setgroups(name, basegid)
|
||||||
|
const char *name;
|
||||||
|
gid_t basegid;
|
||||||
|
{
|
||||||
|
/* STUB */
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
restore_groups()
|
||||||
|
{
|
||||||
|
/* STUB */
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* HAVE_INITGROUPS */
|
||||||
|
|
||||||
static void
|
static void
|
||||||
runas_setup()
|
runas_setup()
|
||||||
{
|
{
|
||||||
@@ -359,10 +447,7 @@ runas_setup()
|
|||||||
#ifdef HAVE_LOGIN_CAP_H
|
#ifdef HAVE_LOGIN_CAP_H
|
||||||
if (def_use_loginclass) {
|
if (def_use_loginclass) {
|
||||||
/*
|
/*
|
||||||
* We don't have setusercontext() set the user since we
|
* We only use setusercontext() set the nice value and rlimits.
|
||||||
* may only want to set the effective uid. Depending on
|
|
||||||
* sudoers and/or command line arguments we may not want
|
|
||||||
* setusercontext() to call initgroups().
|
|
||||||
*/
|
*/
|
||||||
flags = LOGIN_SETRESOURCES|LOGIN_SETPRIORITY;
|
flags = LOGIN_SETRESOURCES|LOGIN_SETPRIORITY;
|
||||||
if (!def_preserve_groups)
|
if (!def_preserve_groups)
|
||||||
@@ -375,19 +460,13 @@ runas_setup()
|
|||||||
else
|
else
|
||||||
warning("unable to set user context");
|
warning("unable to set user context");
|
||||||
}
|
}
|
||||||
} else
|
}
|
||||||
#endif /* HAVE_LOGIN_CAP_H */
|
#endif /* HAVE_LOGIN_CAP_H */
|
||||||
{
|
|
||||||
if (setgid(gid))
|
if (setgid(gid))
|
||||||
warning("cannot set gid to runas gid");
|
warning("cannot set gid to runas gid");
|
||||||
#ifdef HAVE_INITGROUPS
|
|
||||||
/*
|
/*
|
||||||
* Initialize group vector unless asked not to.
|
* Initialize group vector
|
||||||
*/
|
*/
|
||||||
if (!def_preserve_groups &&
|
runas_setgroups(runas_pw->pw_name, runas_pw->pw_gid);
|
||||||
initgroups(runas_pw->pw_name, runas_pw->pw_gid) < 0)
|
|
||||||
warning("cannot set group vector");
|
|
||||||
#endif /* HAVE_INITGROUPS */
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user