2
0
mirror of https://github.com/sudo-project/sudo.git synced 2025-08-30 13:58:05 +00:00

Keep the temp file open instead of re-opening after the editor has exited.

This commit is contained in:
Todd C. Miller
2004-09-06 16:11:42 +00:00
parent e410bbb589
commit b701107b4e

View File

@@ -70,12 +70,13 @@ int sudo_edit(argc, argv)
const char *tmpdir; const char *tmpdir;
char **nargv, **ap, *editor, *cp; char **nargv, **ap, *editor, *cp;
char buf[BUFSIZ]; char buf[BUFSIZ];
int i, ac, ofd, tfd, nargc, rval; int i, ac, ofd, nargc, rval;
sigaction_t sa; sigaction_t sa;
struct stat sb; struct stat sb;
struct tempfile { struct tempfile {
char *tfile; char *tfile;
char *ofile; char *ofile;
int tfd;
time_t omtime; /* XXX - use st_mtimespec / st_mtim? */ time_t omtime; /* XXX - use st_mtimespec / st_mtim? */
off_t osize; off_t osize;
} *tf; } *tf;
@@ -93,13 +94,13 @@ int sudo_edit(argc, argv)
tmpdir = _PATH_TMP; tmpdir = _PATH_TMP;
/* /*
* For each file specified, by the user, make a tempoary version * For each file specified by the user, make a temporary version
* and copy the contents of the original to it. We make these files * and copy the contents of the original to it. We make these files
* as root so the user can't steal them out from under us until we are * as root so the user can't steal them out from under us until we are
* done writing (and at that point the user will be able to edit the * done writing (and at that point the user will be able to edit the
* file anyway). * file anyway).
* XXX - It would be nice to lock the original files but that means * XXX - It would be nice to lock the original files but that means
* keeping an fd open for each file. * keeping an extra fd open for each file.
*/ */
tf = emalloc2(argc - 1, sizeof(*tf)); tf = emalloc2(argc - 1, sizeof(*tf));
memset(tf, 0, (argc - 1) * sizeof(*tf)); memset(tf, 0, (argc - 1) * sizeof(*tf));
@@ -135,13 +136,13 @@ int sudo_edit(argc, argv)
else else
cp = tf[i].ofile; cp = tf[i].ofile;
easprintf(&tf[i].tfile, "%s%s.XXXXXXXX", tmpdir, cp); easprintf(&tf[i].tfile, "%s%s.XXXXXXXX", tmpdir, cp);
if ((tfd = mkstemp(tf[i].tfile)) == -1) { if ((tf[i].tfd = mkstemp(tf[i].tfile)) == -1) {
warn("mkstemp"); warn("mkstemp");
goto cleanup; goto cleanup;
} }
if (ofd != -1) { if (ofd != -1) {
while ((nread = read(ofd, buf, sizeof(buf))) != 0) { while ((nread = read(ofd, buf, sizeof(buf))) != 0) {
if ((nwritten = write(tfd, buf, nread)) != nread) { if ((nwritten = write(tf[i].tfd, buf, nread)) != nread) {
if (nwritten == -1) if (nwritten == -1)
warn("%s", tf[i].tfile); warn("%s", tf[i].tfile);
else else
@@ -149,15 +150,13 @@ int sudo_edit(argc, argv)
goto cleanup; goto cleanup;
} }
} }
close(ofd);
} }
#ifdef HAVE_FCHOWN #ifdef HAVE_FCHOWN
fchown(tfd, user_uid, user_gid); fchown(tf[i].tfd, user_uid, user_gid);
#else #else
chown(tf[i].tfile, user_uid, user_gid); chown(tf[i].tfile, user_uid, user_gid);
#endif #endif
if (ofd != -1)
close(ofd);
close(tfd);
touch(tf[i].tfile, tf[i].omtime); touch(tf[i].tfile, tf[i].omtime);
} }
if (argc == 1) if (argc == 1)
@@ -214,6 +213,7 @@ int sudo_edit(argc, argv)
(void) sigaction(SIGINT, &saved_sa_int, NULL); (void) sigaction(SIGINT, &saved_sa_int, NULL);
(void) sigaction(SIGQUIT, &saved_sa_quit, NULL); (void) sigaction(SIGQUIT, &saved_sa_quit, NULL);
(void) sigaction(SIGCHLD, &saved_sa_chld, NULL); (void) sigaction(SIGCHLD, &saved_sa_chld, NULL);
closefrom(STDERR_FILENO + 1);
set_perms(PERM_FULL_USER); set_perms(PERM_FULL_USER);
execvp(nargv[0], nargv); execvp(nargv[0], nargv);
warn("unable to execute %s", nargv[0]); warn("unable to execute %s", nargv[0]);
@@ -247,21 +247,21 @@ int sudo_edit(argc, argv)
/* Copy contents of temp files to real ones */ /* Copy contents of temp files to real ones */
for (i = 0; i < argc - 1; i++) { for (i = 0; i < argc - 1; i++) {
/* XXX - open file with PERM_USER for nfs? */ if (lseek(tf[i].tfd, (off_t)0, SEEK_SET) != 0) {
if ((tfd = open(tf[i].tfile, O_RDONLY, 0644)) == -1) { warn("unable to rewind edited file %s, cannot update %s",
warn("unable to read edited file %s, cannot update %s",
tf[i].tfile, tf[i].ofile); tf[i].tfile, tf[i].ofile);
close(tf[i].tfd);
continue; continue;
} }
#ifdef HAVE_FSTAT #ifdef HAVE_FSTAT
if (fstat(tfd, &sb) == 0) { if (fstat(tf[i].tfd, &sb) == 0) {
#else #else
if (stat(tf[i].tfile, &sb) == 0) { if (stat(tf[i].tfile, &sb) == 0) {
#endif #endif
if (tf[i].osize == sb.st_size && tf[i].omtime == sb.st_mtime) { if (tf[i].osize == sb.st_size && tf[i].omtime == sb.st_mtime) {
warnx("%s unchanged", tf[i].ofile); warnx("%s unchanged", tf[i].ofile);
unlink(tf[i].tfile); unlink(tf[i].tfile);
close(tfd); close(tf[i].tfd);
continue; continue;
} }
} }
@@ -271,10 +271,10 @@ int sudo_edit(argc, argv)
if (ofd == -1) { if (ofd == -1) {
warn("unable to write to %s", tf[i].ofile); warn("unable to write to %s", tf[i].ofile);
warnx("contents of edit session left in %s", tf[i].tfile); warnx("contents of edit session left in %s", tf[i].tfile);
close(tfd); close(tf[i].tfd);
continue; continue;
} }
while ((nread = read(tfd, buf, sizeof(buf))) != 0) { while ((nread = read(tf[i].tfd, buf, sizeof(buf))) != 0) {
if ((nwritten = write(ofd, buf, nread)) != nread) { if ((nwritten = write(ofd, buf, nread)) != nread) {
if (nwritten == -1) if (nwritten == -1)
warn("%s", tf[i].ofile); warn("%s", tf[i].ofile);
@@ -290,7 +290,6 @@ int sudo_edit(argc, argv)
warnx("contents of edit session left in %s", tf[i].tfile); warnx("contents of edit session left in %s", tf[i].tfile);
} }
close(ofd); close(ofd);
close(tfd);
} }
return(rval); return(rval);