calling exit() on failure.
old_ccname = sudo_krb5_ccname_path(old_ccname);
if (old_ccname != NULL) {
/* Open credential cache as user to prevent stolen creds. */
- set_perms(PERM_USER);
+ if (!set_perms(PERM_USER))
+ goto done;
ofd = open(old_ccname, O_RDONLY|O_NONBLOCK);
- restore_perms();
+ if (!restore_perms())
+ goto done;
if (ofd != -1) {
(void) fcntl(ofd, F_SETFL, 0);
"unable to open %s", old_ccname);
}
}
+done:
debug_return_str(ret);
}
/*
- * Copyright (c) 1994-1996, 1998-2013 Todd C. Miller <Todd.Miller@courtesan.com>
+ * Copyright (c) 1994-1996, 1998-2014 Todd C. Miller <Todd.Miller@courtesan.com>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
const char *message;
char *logline;
int oldlocale;
+ bool uid_changed;
debug_decl(log_denial, SUDO_DEBUG_LOGGING)
/* Handle auditing first (audit_failure() handles the locale itself). */
debug_return;
/* Become root if we are not already. */
- set_perms(PERM_ROOT|PERM_NOEXIT);
+ uid_changed = set_perms(PERM_ROOT);
if (should_mail(status))
send_mail("%s", logline); /* send mail based on status */
if (def_logfile)
do_logfile(logline);
- restore_perms();
+ if (uid_changed)
+ restore_perms();
efree(logline);
{
char *logline;
int oldlocale;
+ bool uid_changed;
debug_decl(log_allowed, SUDO_DEBUG_LOGGING)
/* Log and mail messages should be in the sudoers locale. */
logline = new_logline(NULL, 0);
/* Become root if we are not already. */
- set_perms(PERM_ROOT|PERM_NOEXIT);
+ uid_changed = set_perms(PERM_ROOT);
if (should_mail(status))
send_mail("%s", logline); /* send mail based on status */
if (def_logfile)
do_logfile(logline);
- restore_perms();
+ if (uid_changed)
+ restore_perms();
efree(logline);
{
int oldlocale, serrno = errno;
char *logline, *message;
+ bool uid_changed;
va_list ap2;
debug_decl(vlog_error, SUDO_DEBUG_LOGGING)
}
/* Become root if we are not already. */
- set_perms(PERM_ROOT|PERM_NOEXIT);
+ uid_changed = set_perms(PERM_ROOT);
/*
* Send a copy of the error via mail.
do_logfile(logline);
}
- restore_perms();
+ if (uid_changed)
+ restore_perms();
efree(logline);
* (so user cannot kill it) or as the user (for the paranoid).
*/
#ifndef NO_ROOT_MAILER
- set_perms(PERM_ROOT|PERM_NOEXIT);
+ (void) set_perms(PERM_ROOT);
execve(mpath, argv, root_envp);
#else
- set_perms(PERM_FULL_USER|PERM_NOEXIT);
+ (void) set_perms(PERM_FULL_USER);
execv(mpath, argv);
#endif /* NO_ROOT_MAILER */
mysyslog(LOG_ERR, _("unable to execute %s: %m"), mpath);
/*
- * Copyright (c) 2004-2005, 2007-2013 Todd C. Miller <Todd.Miller@courtesan.com>
+ * Copyright (c) 2004-2005, 2007-2014 Todd C. Miller <Todd.Miller@courtesan.com>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
}
/* Need to be runas user while stat'ing things. */
- set_perms(PERM_RUNAS);
+ if (!set_perms(PERM_RUNAS))
+ debug_return_int(validated);
match = UNSPEC;
TAILQ_FOREACH_REVERSE(us, &userspecs, userspec_list, entries) {
if (tags != NULL && tags->nopasswd != UNSPEC)
def_authenticate = !tags->nopasswd;
}
- restore_perms();
+ (void) restore_perms();
debug_return_int(validated);
}
if (fatal_setjmp() != 0) {
/* called via fatal(), fatalx() or log_fatal() */
- rewind_perms();
+ (void) rewind_perms();
fatal_disable_setjmp();
debug_return_bool(-1);
}
#undef OID
#define OID(x) (ostate->x == state->x ? (uid_t)-1 : ostate->x)
-void
+bool
rewind_perms(void)
{
debug_decl(rewind_perms, SUDO_DEBUG_PERMS)
if (perm_stack_depth != 0) {
- while (perm_stack_depth > 1)
- restore_perms();
+ while (perm_stack_depth > 1) {
+ if (!restore_perms())
+ debug_return_bool(false);
+ }
sudo_grlist_delref(perm_stack[0].grlist);
}
- debug_return;
+ debug_return_bool(true);
}
#if defined(HAVE_SETRESUID)
* We only flip the effective gid since it only changes for PERM_SUDOERS.
* This version of set_perms() works fine with the "stay_setuid" option.
*/
-int
+bool
set_perms(int perm)
{
struct perm_state *state, *ostate = NULL;
char errbuf[1024];
const char *errstr = errbuf;
- int noexit;
debug_decl(set_perms, SUDO_DEBUG_PERMS)
- noexit = ISSET(perm, PERM_NOEXIT);
- CLR(perm, PERM_MASK);
-
if (perm_stack_depth == PERM_STACK_MAX) {
errstr = N_("perm stack overflow");
errno = EINVAL;
}
perm_stack_depth++;
- debug_return_bool(1);
+ debug_return_bool(true);
bad:
if (errno == EAGAIN)
warningx(U_("%s: %s"), U_(errstr), U_("too many processes"));
else
warning("%s", U_(errstr));
- if (noexit)
- debug_return_bool(0);
- exit(1);
+ debug_return_bool(false);
}
-void
+bool
restore_perms(void)
{
struct perm_state *state, *ostate;
debug_decl(restore_perms, SUDO_DEBUG_PERMS)
- if (perm_stack_depth < 2)
- debug_return;
+ if (perm_stack_depth < 2) {
+ warningx(U_("perm stack underflow"));
+ debug_return_bool(true);
+ }
state = &perm_stack[perm_stack_depth - 1];
ostate = &perm_stack[perm_stack_depth - 2];
}
}
sudo_grlist_delref(state->grlist);
- debug_return;
+ debug_return_bool(true);
bad:
- exit(1);
+ debug_return_bool(false);
}
#elif defined(_AIX) && defined(ID_SAVED)
* We only flip the effective gid since it only changes for PERM_SUDOERS.
* This version of set_perms() works fine with the "stay_setuid" option.
*/
-int
+bool
set_perms(int perm)
{
struct perm_state *state, *ostate = NULL;
char errbuf[1024];
const char *errstr = errbuf;
- int noexit;
debug_decl(set_perms, SUDO_DEBUG_PERMS)
- noexit = ISSET(perm, PERM_NOEXIT);
- CLR(perm, PERM_MASK);
-
if (perm_stack_depth == PERM_STACK_MAX) {
errstr = N_("perm stack overflow");
errno = EINVAL;
}
perm_stack_depth++;
- debug_return_bool(1);
+ debug_return_bool(true);
bad:
if (errno == EAGAIN)
warningx(U_("%s: %s"), U_(errstr), U_("too many processes"));
else
warning("%s", U_(errstr));
- if (noexit)
- debug_return_bool(0);
- exit(1);
+ debug_return_bool(false);
}
-void
+bool
restore_perms(void)
{
struct perm_state *state, *ostate;
debug_decl(restore_perms, SUDO_DEBUG_PERMS)
- if (perm_stack_depth < 2)
- debug_return;
+ if (perm_stack_depth < 2) {
+ warningx(U_("perm stack underflow"));
+ debug_return_bool(true);
+ }
state = &perm_stack[perm_stack_depth - 1];
ostate = &perm_stack[perm_stack_depth - 2];
}
}
sudo_grlist_delref(state->grlist);
- debug_return;
+ debug_return_bool(true);
bad:
- exit(1);
+ debug_return_bool(false);
}
#elif defined(HAVE_SETREUID)
* We only flip the effective gid since it only changes for PERM_SUDOERS.
* This version of set_perms() works fine with the "stay_setuid" option.
*/
-int
+bool
set_perms(int perm)
{
struct perm_state *state, *ostate = NULL;
char errbuf[1024];
const char *errstr = errbuf;
- int noexit;
debug_decl(set_perms, SUDO_DEBUG_PERMS)
- noexit = ISSET(perm, PERM_NOEXIT);
- CLR(perm, PERM_MASK);
-
if (perm_stack_depth == PERM_STACK_MAX) {
errstr = N_("perm stack overflow");
errno = EINVAL;
}
perm_stack_depth++;
- debug_return_bool(1);
+ debug_return_bool(true);
bad:
if (errno == EAGAIN)
warningx(U_("%s: %s"), U_(errstr), U_("too many processes"));
else
warning("%s", U_(errstr));
- if (noexit)
- debug_return_bool(0);
- exit(1);
+ debug_return_bool(false);
}
-void
+bool
restore_perms(void)
{
struct perm_state *state, *ostate;
debug_decl(restore_perms, SUDO_DEBUG_PERMS)
- if (perm_stack_depth < 2)
- debug_return;
+ if (perm_stack_depth < 2) {
+ warningx(U_("perm stack underflow"));
+ debug_return_bool(true);
+ }
state = &perm_stack[perm_stack_depth - 1];
ostate = &perm_stack[perm_stack_depth - 2];
}
}
sudo_grlist_delref(state->grlist);
- debug_return;
+ debug_return_bool(true);
bad:
- exit(1);
+ debug_return_bool(false);
}
#elif defined(HAVE_SETEUID)
* we are headed for an exec().
* This version of set_perms() works fine with the "stay_setuid" option.
*/
-int
+bool
set_perms(int perm)
{
struct perm_state *state, *ostate = NULL;
char errbuf[1024];
const char *errstr = errbuf;
- int noexit;
debug_decl(set_perms, SUDO_DEBUG_PERMS)
- noexit = ISSET(perm, PERM_NOEXIT);
- CLR(perm, PERM_MASK);
-
if (perm_stack_depth == PERM_STACK_MAX) {
errstr = N_("perm stack overflow");
errno = EINVAL;
}
perm_stack_depth++;
- debug_return_bool(1);
+ debug_return_bool(true);
bad:
if (errno == EAGAIN)
warningx(U_("%s: %s"), U_(errstr), U_("too many processes"));
else
warning("%s", U_(errstr));
- if (noexit)
- debug_return_bool(0);
- exit(1);
+ debug_return_bool(false);
}
-void
+bool
restore_perms(void)
{
struct perm_state *state, *ostate;
debug_decl(restore_perms, SUDO_DEBUG_PERMS)
- if (perm_stack_depth < 2)
- debug_return;
+ if (perm_stack_depth < 2) {
+ warningx(U_("perm stack underflow"));
+ debug_return_bool(true);
+ }
state = &perm_stack[perm_stack_depth - 1];
ostate = &perm_stack[perm_stack_depth - 2];
goto bad;
}
sudo_grlist_delref(state->grlist);
- debug_return;
+ debug_return_bool(true);
bad:
- exit(1);
+ debug_return_bool(false);
}
#else /* !HAVE_SETRESUID && !HAVE_SETREUID && !HAVE_SETEUID */
* NOTE: does not support the "stay_setuid" or timestampowner options.
* Also, sudoers_uid and sudoers_gid are not used.
*/
-int
+bool
set_perms(int perm)
{
struct perm_state *state, *ostate = NULL;
char errbuf[1024];
const char *errstr = errbuf;
- int noexit;
debug_decl(set_perms, SUDO_DEBUG_PERMS)
- noexit = ISSET(perm, PERM_NOEXIT);
- CLR(perm, PERM_MASK);
-
if (perm_stack_depth == PERM_STACK_MAX) {
errstr = N_("perm stack overflow");
errno = EINVAL;
}
perm_stack_depth++;
- debug_return_bool(1);
+ debug_return_bool(true);
bad:
if (errno == EAGAIN)
warningx(U_("%s: %s"), U_(errstr), U_("too many processes"));
else
warning("%s", U_(errstr));
- if (noexit)
- debug_return_bool(0);
- exit(1);
+ debug_return_bool(false);
}
-void
+boll
restore_perms(void)
{
struct perm_state *state, *ostate;
debug_decl(restore_perms, SUDO_DEBUG_PERMS)
- if (perm_stack_depth < 2)
- debug_return;
+ if (perm_stack_depth < 2) {
+ warningx(U_("perm stack underflow"));
+ debug_return_bool(true);
+ }
state = &perm_stack[perm_stack_depth - 1];
ostate = &perm_stack[perm_stack_depth - 2];
warning("setuid(%d)", (int)ostate->ruid);
goto bad;
}
- debug_return;
+ debug_return_bool(true);
bad:
- exit(1);
+ debug_return_bool(false);
}
#endif /* HAVE_SETRESUID || HAVE_SETREUID || HAVE_SETEUID */
snl = sudo_read_nss();
/* LDAP or NSS may modify the euid so we need to be root for the open. */
- set_perms(PERM_ROOT);
+ if (!set_perms(PERM_ROOT))
+ debug_return_bool(-1);
/* Open and parse sudoers, set global defaults */
TAILQ_FOREACH_SAFE(nss, snl, entries, nss_next) {
rval = true;
cleanup:
- restore_perms();
+ if (!restore_perms())
+ rval = -1;
debug_return_bool(rval);
}
goto bad;
}
- set_perms(PERM_INITIAL);
+ if (!set_perms(PERM_INITIAL))
+ goto bad;
/* Environment variables specified on the command line. */
if (env_add != NULL && env_add[0] != NULL)
done:
fatal_disable_setjmp();
- rewind_perms();
+ if (!rewind_perms())
+ rval = -1;
/* Close the password and group files and free up memory. */
sudo_endpwent();
*/
if (user_group_list == NULL)
user_group_list = sudo_get_grlist(sudo_user.pw);
- set_perms(PERM_INITIAL);
+ if (!set_perms(PERM_INITIAL))
+ debug_return_bool(false);
/* Set runas callback. */
sudo_defs_table[I_RUNAS_DEFAULT].callback = cb_runas_default;
if (ISSET(sudo_mode, MODE_RUN | MODE_CHECK)) {
if (def_secure_path && !user_is_exempt())
path = def_secure_path;
- set_perms(PERM_RUNAS);
+ if (!set_perms(PERM_RUNAS))
+ debug_return_int(-1);
rval = find_path(NewArgv[0], &user_cmnd, user_stat, path,
def_ignore_dot);
- restore_perms();
+ if (!restore_perms())
+ debug_return_int(-1);
if (rval == NOT_FOUND) {
/* Failed as root, try as invoking user. */
- set_perms(PERM_USER);
+ if (!set_perms(PERM_USER))
+ debug_return_int(-1);
rval = find_path(NewArgv[0], &user_cmnd, user_stat, path,
def_ignore_dot);
- restore_perms();
+ if (!restore_perms())
+ debug_return_int(-1);
}
if (rval == NOT_FOUND_ERROR) {
if (errno == ENAMETOOLONG)
FILE *fp = NULL;
debug_decl(open_sudoers, SUDO_DEBUG_PLUGIN)
- set_perms(PERM_SUDOERS);
+ if (!set_perms(PERM_SUDOERS))
+ debug_return_ptr(NULL);
switch (sudo_secure_file(sudoers, sudoers_uid, sudoers_gid, &sb)) {
case SUDO_PATH_SECURE:
*/
if (sudoers_uid == ROOT_UID && ISSET(sudoers_mode, S_IRGRP)) {
if (!ISSET(sb.st_mode, S_IRGRP) || sb.st_gid != SUDOERS_GID) {
- restore_perms();
- set_perms(PERM_ROOT);
+ if (!restore_perms() || !set_perms(PERM_ROOT))
+ debug_return_ptr(NULL);
}
}
/*
break;
}
- restore_perms(); /* change back to root */
+ if (!restore_perms()) {
+ /* unable to change back to root */
+ fclose(fp);
+ fp = NULL;
+ }
debug_return_ptr(fp);
}
debug_return;
/* Create admin flag file if it doesn't already exist. */
- set_perms(PERM_USER);
- if (stat(flagfile, &statbuf) != 0) {
- fd = open(flagfile, O_CREAT|O_WRONLY|O_EXCL, 0644);
- close(fd);
+ if (set_perms(PERM_USER)) {
+ if (stat(flagfile, &statbuf) != 0) {
+ fd = open(flagfile, O_CREAT|O_WRONLY|O_EXCL, 0644);
+ close(fd);
+ }
+ (void) restore_perms();
}
- restore_perms();
debug_return;
}
#else /* !USE_ADMIN_FLAG */
#define PERM_SUDOERS 0x04
#define PERM_RUNAS 0x05
#define PERM_TIMESTAMP 0x06
-#define PERM_NOEXIT 0x10 /* flag */
-#define PERM_MASK 0xf0
/*
* Shortcuts for sudo_user contents.
int sudo_file_display_privs(struct sudo_nss *, struct passwd *, struct lbuf *);
/* set_perms.c */
-void rewind_perms(void);
-int set_perms(int);
-void restore_perms(void);
+bool rewind_perms(void);
+bool set_perms(int);
+bool restore_perms(void);
int pam_prep_user(struct passwd *);
/* gram.y */
return;
}
-int
+bool
set_perms(int perm)
{
- return 1;
+ return true;
}
-void
+bool
restore_perms(void)
{
+ return true;
}
void
update_timestamp(struct passwd *pw)
{
struct timestamp_entry entry;
+ bool uid_changed = false;
bool rval = false;
int fd;
debug_decl(update_timestamp, SUDO_DEBUG_AUTH)
/* Open time stamp file and lock it for exclusive access. */
if (timestamp_uid != 0)
- set_perms(PERM_TIMESTAMP);
+ uid_changed = set_perms(PERM_TIMESTAMP);
fd = open(timestamp_file, O_RDWR|O_CREAT, 0600);
- if (timestamp_uid != 0)
- restore_perms();
+ if (uid_changed)
+ (void) restore_perms();
if (fd == -1) {
log_warning(USE_ERRNO, N_("unable to open %s"), timestamp_file);
goto done;
{
struct timestamp_entry entry;
struct timespec diff, timeout;
+ bool uid_changed = false;
int status = TS_ERROR; /* assume the worst */
struct stat sb;
int fd = -1;
/* Open time stamp file and lock it for exclusive access. */
if (timestamp_uid != 0)
- set_perms(PERM_TIMESTAMP);
+ uid_changed = set_perms(PERM_TIMESTAMP);
fd = open(timestamp_file, O_RDWR);
- if (timestamp_uid != 0)
- restore_perms();
+ if (uid_changed)
+ (void) restore_perms();
if (fd == -1) {
status = TS_MISSING;
goto done;
remove_timestamp(bool unlink_it)
{
struct timestamp_entry entry;
+ bool uid_changed = false;
int fd = -1;
debug_decl(remove_timestamp, SUDO_DEBUG_AUTH)
/* Open time stamp file and lock it for exclusive access. */
if (timestamp_uid != 0)
- set_perms(PERM_TIMESTAMP);
+ uid_changed = set_perms(PERM_TIMESTAMP);
fd = open(timestamp_file, O_RDWR);
- if (timestamp_uid != 0)
- restore_perms();
+ if (uid_changed)
+ (void) restore_perms();
if (fd == -1)
goto done;
lock_file(fd, SUDO_LOCK);
set_lectured(void)
{
char lecture_status[PATH_MAX];
+ bool uid_changed = false;
int len, fd = -1;
debug_decl(set_lectured, SUDO_DEBUG_AUTH)
/* Create lecture file. */
if (timestamp_uid != 0)
- set_perms(PERM_TIMESTAMP);
+ uid_changed = set_perms(PERM_TIMESTAMP);
fd = open(lecture_status, O_WRONLY|O_CREAT|O_TRUNC, 0600);
- if (timestamp_uid != 0)
- restore_perms();
+ if (uid_changed)
+ (void) restore_perms();
if (fd != -1)
close(fd);