Imported Upstream version 1.8.7
[debian/sudo] / src / sudo_edit.c
index 0be9d31fdfa1b41852427f911041d0a56d888068..90864c604c205598d248c4390ee73ab2fab95772 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * 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;
 }
 
 /*
@@ -98,15 +99,16 @@ sudo_edit(struct command_details *command_details)
        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;
     }
 
     /*
@@ -137,8 +139,8 @@ sudo_edit(struct command_details *command_details)
            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;
     }
 
     /*
@@ -156,11 +158,7 @@ sudo_edit(struct command_details *command_details)
                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,
@@ -169,7 +167,7 @@ sudo_edit(struct command_details *command_details)
            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;
@@ -189,10 +187,10 @@ sudo_edit(struct command_details *command_details)
            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;
@@ -203,7 +201,7 @@ sudo_edit(struct command_details *command_details)
                    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;
                }
            }
@@ -217,18 +215,14 @@ sudo_edit(struct command_details *command_details)
         * 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.
@@ -263,22 +257,18 @@ sudo_edit(struct command_details *command_details)
     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;
@@ -291,7 +281,7 @@ sudo_edit(struct command_details *command_details)
             */
            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;
@@ -303,8 +293,8 @@ sudo_edit(struct command_details *command_details)
        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;
        }
@@ -313,7 +303,7 @@ sudo_edit(struct command_details *command_details)
                if (nwritten == -1)
                    warning("%s", tf[i].ofile);
                else
-                   warningx("%s: short write", tf[i].ofile);
+                   warningx(_("%s: short write"), tf[i].ofile);
                break;
            }
        }
@@ -321,23 +311,25 @@ sudo_edit(struct command_details *command_details)
            /* 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 */
@@ -348,7 +340,8 @@ cleanup:
 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 */