Use mkstemps() instead of mkstemp() in sudoedit. This allows sudoedit

to preserve the file extension (if any) which may be used by the editor
(like emacs) to choose the editing mode.
This commit is contained in:
Todd C. Miller
2010-07-09 10:08:05 -04:00
parent 432d27573d
commit ea4298bb54
8 changed files with 61 additions and 41 deletions

View File

@@ -32,7 +32,7 @@ compat/isblank.c
compat/memrchr.c
compat/mksiglist.c
compat/mksiglist.h
compat/mkstemp.c
compat/mkstemps.c
compat/nanosleep.c
compat/setenv.c
compat/siglist.in

View File

@@ -83,7 +83,7 @@ getprogname.lo: $(compat)/getprogname.c $(incdir)/compat.h $(top_builddir)/confi
glob.lo: $(compat)/glob.c $(compat)/glob.h $(compat)/charclass.h $(incdir)/compat.h $(top_builddir)/config.h
isblank.lo: $(compat)/isblank.c $(incdir)/compat.h $(top_builddir)/config.h
memrchr.lo: $(compat)/memrchr.c $(incdir)/compat.h $(top_builddir)/config.h
mkstemp.lo: $(compat)/mkstemp.c $(incdir)/compat.h $(top_builddir)/config.h
mkstemps.lo: $(compat)/mkstemps.c $(incdir)/compat.h $(top_builddir)/config.h
nanosleep.lo: $(compat)/nanosleep.c $(incdir)/compat.h $(top_builddir)/config.h
sigaction.lo: $(compat)/sigaction.c $(incdir)/compat.h $(incdir)/compat.h
snprintf.lo: $(compat)/snprintf.c $(incdir)/compat.h $(top_builddir)/config.h

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2001, 2003, 2008, 2010
* Copyright (c) 2001, 2003, 2004, 2008-2010
* Todd C. Miller <Todd.Miller@courtesan.com>
*
* Permission to use, copy, modify, and distribute this software for any
@@ -21,6 +21,7 @@
#include <sys/stat.h>
#include <errno.h>
#include <fcntl.h>
#include <limits.h>
#include <stdio.h>
#ifdef HAVE_STDLIB_H
# include <stdlib.h>
@@ -35,36 +36,49 @@
static unsigned int get_random(void);
static void seed_random(void);
#define TEMPCHARS "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
#define NUM_CHARS (sizeof(TEMPCHARS) - 1)
#ifndef INT_MAX
#define INT_MAX 0x7fffffff
#endif
int
mkstemp(char *path)
mkstemps(char *path, int slen)
{
char *start, *cp;
int fd, r;
char *alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
char *start, *cp, *ep;
const char *tempchars = TEMPCHARS;
unsigned int r, tries;
int fd;
if (*path == '\0') {
errno = EINVAL;
return(0);
}
for (cp = path; *cp; cp++)
for (ep = path; *ep; ep++)
;
do {
cp--;
} while (cp >= path && *cp == 'X');
start = cp + 1;
if (path + slen >= ep) {
errno = EINVAL;
return(-1);
}
ep -= slen;
for (;;) {
tries = 1;
for (start = ep; start > path && start[-1] == 'X'; start--) {
if (tries < INT_MAX / NUM_CHARS)
tries *= NUM_CHARS;
}
tries *= 2;
do {
for (cp = start; *cp; cp++) {
r = get_random % (26 + 26);
*cp = alphabet[r];
r = get_random() % NUM_CHARS;
*cp = tempchars[r];
}
fd = open(path, O_CREAT|O_EXCL|O_RDWR, S_IRUSR|S_IWUSR);
if (fd != -1 || errno != EEXIST)
return(fd);
}
/*NOTREACHED*/
} while (--tries);
errno = EEXIST;
return(-1);
}
#ifdef HAVE_RANDOM
@@ -87,13 +101,13 @@ static void
seed_random(void)
{
SEED_T seed;
struct timespec ts;
struct timeval tv;
/*
* Seed from time of day and process id multiplied by small primes.
*/
(void) gettime(&ts);
seed = (ts.tv_sec % 10000) * 523 + ts.tv_nsec / 1000 * 13 +
(void) gettime(&tv);
seed = (tv.tv_sec % 10000) * 523 + tv.tv_usec * 13 +
(getpid() % 1000) * 983;
SRAND(seed);
}

View File

@@ -337,8 +337,8 @@
/* Define to 1 if you have the `memset' function. */
#undef HAVE_MEMSET
/* Define to 1 if you have the `mkstemp' function. */
#undef HAVE_MKSTEMP
/* Define to 1 if you have the `mkstemps' function. */
#undef HAVE_MKSTEMPS
/* Define to 1 if you have the <mps/ldap_ssl.h> header file. */
#undef HAVE_MPS_LDAP_SSL_H

12
configure vendored
View File

@@ -15459,12 +15459,12 @@ fi
fi
done
for ac_func in mkstemp
for ac_func in mkstemps
do :
ac_fn_c_check_func "$LINENO" "mkstemp" "ac_cv_func_mkstemp"
if test "x$ac_cv_func_mkstemp" = x""yes; then :
ac_fn_c_check_func "$LINENO" "mkstemps" "ac_cv_func_mkstemps"
if test "x$ac_cv_func_mkstemps" = x""yes; then :
cat >>confdefs.h <<_ACEOF
#define HAVE_MKSTEMP 1
#define HAVE_MKSTEMPS 1
_ACEOF
else
@@ -15483,8 +15483,8 @@ fi
done
case " $LIBOBJS " in
*" mkstemp.$ac_objext "* ) ;;
*) LIBOBJS="$LIBOBJS mkstemp.$ac_objext"
*" mkstemps.$ac_objext "* ) ;;
*) LIBOBJS="$LIBOBJS mkstemps.$ac_objext"
;;
esac

View File

@@ -1979,9 +1979,9 @@ AC_CHECK_FUNCS(closefrom, [], [AC_LIBOBJ(closefrom)
[ #include <limits.h>
#include <fcntl.h> ])
])
AC_CHECK_FUNCS(mkstemp, [], [
AC_CHECK_FUNCS(mkstemps, [], [
AC_CHECK_FUNCS(random lrand48, [break])
AC_LIBOBJ(mkstemp)
AC_LIBOBJ(mkstemps)
])
AC_CHECK_FUNCS(snprintf vsnprintf asprintf vasprintf, , [NEED_SNPRINTF=1])
if test X"$ac_cv_type_struct_timespec" != X"no"; then

View File

@@ -63,8 +63,8 @@ size_t strlcpy(char *, const char *, size_t);
#ifndef HAVE_MEMRCHR
void *memrchr(const void *, int, size_t);
#endif
#ifndef HAVE_MKSTEMP
int mkstemp(char *);
#ifndef HAVE_MKSTEMPS
int mkstemps(char *);
#endif
#ifndef HAVE_NANOSLEEP
int nanosleep(const struct timespec *, struct timespec *);

View File

@@ -87,7 +87,7 @@ sudo_edit(struct command_details *command_details, char *argv[], char *envp[])
struct command_details editor_details;
ssize_t nread, nwritten;
const char *tmpdir;
char *cp, **nargv, **ap, **files = NULL;
char *cp, *suff, **nargv, **ap, **files = NULL;
char buf[BUFSIZ];
int rc, i, j, ac, ofd, tfd, nargc, rval, tmplen;
int editor_argc = 0, nfiles = 0;
@@ -178,14 +178,20 @@ sudo_edit(struct command_details *command_details, char *argv[], char *envp[])
cp++;
else
cp = tf[j].ofile;
suff = strrchr(cp, '.');
if (suff != NULL) {
easprintf(&tf[j].tfile, "%.*s/%.*sXXXXXXXX%s", tmplen, tmpdir,
(int)(size_t)(suff - cp), cp, suff);
} else {
easprintf(&tf[j].tfile, "%.*s/%s.XXXXXXXX", tmplen, tmpdir, cp);
}
if (seteuid(user_details.uid) != 0)
error(1, "seteuid(%d)", (int)user_details.uid);
tfd = mkstemp(tf[j].tfile);
tfd = mkstemps(tf[j].tfile, suff ? strlen(suff) : 0);
if (seteuid(ROOT_UID) != 0)
error(1, "seteuid(ROOT_UID)");
if (tfd == -1) {
warning("mkstemp");
warning("mkstemps");
goto cleanup;
}
if (ofd != -1) {