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:
2
MANIFEST
2
MANIFEST
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -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);
|
||||
}
|
@@ -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
12
configure
vendored
@@ -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
|
||||
|
||||
|
@@ -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
|
||||
|
@@ -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 *);
|
||||
|
@@ -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;
|
||||
easprintf(&tf[j].tfile, "%.*s/%s.XXXXXXXX", tmplen, tmpdir, cp);
|
||||
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) {
|
||||
|
Reference in New Issue
Block a user