/*
- * Copyright (c) 2004-2008, 2010-2011 Todd C. Miller <Todd.Miller@courtesan.com>
+ * Copyright (c) 2004-2008, 2010-2013 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
#include <config.h>
-#if defined(HAVE_SETRESUID) || defined(HAVE_SETREUID) || defined(HAVE_SETEUID)
-
#include <sys/types.h>
-#include <sys/param.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/wait.h>
#include "sudo.h"
+#if defined(HAVE_SETRESUID) || defined(HAVE_SETREUID) || defined(HAVE_SETEUID)
+
static void
switch_user(uid_t euid, gid_t egid, int ngroups, GETGROUPS_T *groups)
{
int serrno = errno;
+ debug_decl(switch_user, SUDO_DEBUG_EDIT)
/* When restoring root, change euid first; otherwise change it last. */
if (euid == ROOT_UID) {
if (seteuid(ROOT_UID) != 0)
- error(1, "seteuid(ROOT_UID)");
+ fatal("seteuid(ROOT_UID)");
}
+ if (setegid(egid) != 0)
+ fatal("setegid(%d)", (int)egid);
if (ngroups != -1) {
- if (setgroups(ngroups, groups) != 0)
- error(1, "setgroups");
+ if (sudo_setgroups(ngroups, groups) != 0)
+ fatal("setgroups");
}
- if (setegid(egid) != 0)
- error(1, "setegid(%d)", (int)egid);
if (euid != ROOT_UID) {
if (seteuid(euid) != 0)
- error(1, "seteuid(%d)", (int)euid);
+ fatal("seteuid(%d)", (int)euid);
}
-
errno = serrno;
+
+ debug_return;
}
/*
char *ofile;
struct timeval omtim;
off_t osize;
- } *tf;
+ } *tf = NULL;
+ debug_decl(sudo_edit, SUDO_DEBUG_EDIT)
/*
* Set real, effective and saved uids to root.
* We will change the euid as needed below.
*/
if (setuid(ROOT_UID) != 0) {
- warning("unable to change to uid to root (%u)", ROOT_UID);
- return 1;
+ warning(_("unable to change uid to root (%u)"), ROOT_UID);
+ goto cleanup;
}
/*
editor_argc++;
}
if (nfiles == 0) {
- warningx("plugin error: missing file list for sudoedit");
- return 1;
+ warningx(_("plugin error: missing file list for sudoedit"));
+ goto cleanup;
}
/*
zero_bytes(&sb, sizeof(sb)); /* new file */
rc = 0;
} else {
-#ifdef HAVE_FSTAT
rc = fstat(ofd, &sb);
-#else
- rc = stat(tf[j].ofile, &sb);
-#endif
}
}
switch_user(ROOT_UID, user_details.egid,
if (rc)
warning("%s", files[i]);
else
- warningx("%s: not a regular file", files[i]);
+ warningx(_("%s: not a regular file"), files[i]);
if (ofd != -1)
close(ofd);
continue;
easprintf(&tf[j].tfile, "%.*s/%s.XXXXXXXX", tmplen, tmpdir, cp);
}
if (seteuid(user_details.uid) != 0)
- error(1, "seteuid(%d)", (int)user_details.uid);
+ fatal("seteuid(%d)", (int)user_details.uid);
tfd = mkstemps(tf[j].tfile, suff ? strlen(suff) : 0);
if (seteuid(ROOT_UID) != 0)
- error(1, "seteuid(ROOT_UID)");
+ fatal("seteuid(ROOT_UID)");
if (tfd == -1) {
warning("mkstemps");
goto cleanup;
if (nwritten == -1)
warning("%s", tf[j].tfile);
else
- warningx("%s: short write", tf[j].tfile);
+ warningx(_("%s: short write"), tf[j].tfile);
goto cleanup;
}
}
* to determine whether or not a file has been modified.
*/
(void) touch(tfd, NULL, &tf[j].omtim);
-#ifdef HAVE_FSTAT
rc = fstat(tfd, &sb);
-#else
- rc = stat(tf[j].tfile, &sb);
-#endif
if (!rc)
mtim_get(&sb, &tf[j].omtim);
close(tfd);
j++;
}
if ((nfiles = j) == 0)
- return 1; /* no files readable, you lose */
+ goto cleanup; /* no files readable, you lose */
/*
* Allocate space for the new argument vector and fill it in.
for (i = 0; i < nfiles; i++) {
rc = -1;
if (seteuid(user_details.uid) != 0)
- error(1, "seteuid(%d)", (int)user_details.uid);
+ fatal("seteuid(%d)", (int)user_details.uid);
if ((tfd = open(tf[i].tfile, O_RDONLY, 0644)) != -1) {
-#ifdef HAVE_FSTAT
rc = fstat(tfd, &sb);
-#else
- rc = stat(tf[i].tfile, &sb);
-#endif
}
if (seteuid(ROOT_UID) != 0)
- error(1, "seteuid(ROOT_UID)");
+ fatal("seteuid(ROOT_UID)");
if (rc || !S_ISREG(sb.st_mode)) {
if (rc)
warning("%s", tf[i].tfile);
else
- warningx("%s: not a regular file", tf[i].tfile);
- warningx("%s left unmodified", tf[i].ofile);
+ warningx(_("%s: not a regular file"), tf[i].tfile);
+ warningx(_("%s left unmodified"), tf[i].ofile);
if (tfd != -1)
close(tfd);
continue;
*/
timevalsub(&tv1, &tv2);
if (timevalisset(&tv2)) {
- warningx("%s unchanged", tf[i].ofile);
+ warningx(_("%s unchanged"), tf[i].ofile);
unlink(tf[i].tfile);
close(tfd);
continue;
switch_user(ROOT_UID, user_details.egid,
user_details.ngroups, user_details.groups);
if (ofd == -1) {
- warning("unable to write to %s", tf[i].ofile);
- warningx("contents of edit session left in %s", tf[i].tfile);
+ warning(_("unable to write to %s"), tf[i].ofile);
+ warningx(_("contents of edit session left in %s"), tf[i].tfile);
close(tfd);
continue;
}
if (nwritten == -1)
warning("%s", tf[i].ofile);
else
- warningx("%s: short write", tf[i].ofile);
+ warningx(_("%s: short write"), tf[i].ofile);
break;
}
}
/* success, got EOF */
unlink(tf[i].tfile);
} else if (nread < 0) {
- warning("unable to read temporary file");
- warningx("contents of edit session left in %s", tf[i].tfile);
+ warning(_("unable to read temporary file"));
+ warningx(_("contents of edit session left in %s"), tf[i].tfile);
} else {
- warning("unable to write to %s", tf[i].ofile);
- warningx("contents of edit session left in %s", tf[i].tfile);
+ warning(_("unable to write to %s"), tf[i].ofile);
+ warningx(_("contents of edit session left in %s"), tf[i].tfile);
}
close(ofd);
}
+ debug_return_int(rval);
- return rval;
cleanup:
/* Clean up temp files and return. */
- for (i = 0; i < nfiles; i++) {
- if (tf[i].tfile != NULL)
- unlink(tf[i].tfile);
+ if (tf != NULL) {
+ for (i = 0; i < nfiles; i++) {
+ if (tf[i].tfile != NULL)
+ unlink(tf[i].tfile);
+ }
}
- return 1;
+ debug_return_int(1);
}
#else /* HAVE_SETRESUID || HAVE_SETREUID || HAVE_SETEUID */
int
sudo_edit(struct command_details *command_details)
{
- return 1;
+ debug_decl(sudo_edit, SUDO_DEBUG_EDIT)
+ debug_return_int(1);
}
#endif /* HAVE_SETRESUID || HAVE_SETREUID || HAVE_SETEUID */