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/memrchr.c
|
||||||
compat/mksiglist.c
|
compat/mksiglist.c
|
||||||
compat/mksiglist.h
|
compat/mksiglist.h
|
||||||
compat/mkstemp.c
|
compat/mkstemps.c
|
||||||
compat/nanosleep.c
|
compat/nanosleep.c
|
||||||
compat/setenv.c
|
compat/setenv.c
|
||||||
compat/siglist.in
|
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
|
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
|
isblank.lo: $(compat)/isblank.c $(incdir)/compat.h $(top_builddir)/config.h
|
||||||
memrchr.lo: $(compat)/memrchr.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
|
nanosleep.lo: $(compat)/nanosleep.c $(incdir)/compat.h $(top_builddir)/config.h
|
||||||
sigaction.lo: $(compat)/sigaction.c $(incdir)/compat.h $(incdir)/compat.h
|
sigaction.lo: $(compat)/sigaction.c $(incdir)/compat.h $(incdir)/compat.h
|
||||||
snprintf.lo: $(compat)/snprintf.c $(incdir)/compat.h $(top_builddir)/config.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>
|
* Todd C. Miller <Todd.Miller@courtesan.com>
|
||||||
*
|
*
|
||||||
* Permission to use, copy, modify, and distribute this software for any
|
* Permission to use, copy, modify, and distribute this software for any
|
||||||
@@ -21,6 +21,7 @@
|
|||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
#include <limits.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#ifdef HAVE_STDLIB_H
|
#ifdef HAVE_STDLIB_H
|
||||||
# include <stdlib.h>
|
# include <stdlib.h>
|
||||||
@@ -35,36 +36,49 @@
|
|||||||
static unsigned int get_random(void);
|
static unsigned int get_random(void);
|
||||||
static void seed_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
|
int
|
||||||
mkstemp(char *path)
|
mkstemps(char *path, int slen)
|
||||||
{
|
{
|
||||||
char *start, *cp;
|
char *start, *cp, *ep;
|
||||||
int fd, r;
|
const char *tempchars = TEMPCHARS;
|
||||||
char *alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
|
unsigned int r, tries;
|
||||||
|
int fd;
|
||||||
|
|
||||||
if (*path == '\0') {
|
for (ep = path; *ep; ep++)
|
||||||
errno = EINVAL;
|
|
||||||
return(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (cp = path; *cp; cp++)
|
|
||||||
;
|
;
|
||||||
do {
|
if (path + slen >= ep) {
|
||||||
cp--;
|
errno = EINVAL;
|
||||||
} while (cp >= path && *cp == 'X');
|
return(-1);
|
||||||
start = cp + 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++) {
|
for (cp = start; *cp; cp++) {
|
||||||
r = get_random % (26 + 26);
|
r = get_random() % NUM_CHARS;
|
||||||
*cp = alphabet[r];
|
*cp = tempchars[r];
|
||||||
}
|
}
|
||||||
|
|
||||||
fd = open(path, O_CREAT|O_EXCL|O_RDWR, S_IRUSR|S_IWUSR);
|
fd = open(path, O_CREAT|O_EXCL|O_RDWR, S_IRUSR|S_IWUSR);
|
||||||
if (fd != -1 || errno != EEXIST)
|
if (fd != -1 || errno != EEXIST)
|
||||||
return(fd);
|
return(fd);
|
||||||
}
|
} while (--tries);
|
||||||
/*NOTREACHED*/
|
|
||||||
|
errno = EEXIST;
|
||||||
|
return(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef HAVE_RANDOM
|
#ifdef HAVE_RANDOM
|
||||||
@@ -87,13 +101,13 @@ static void
|
|||||||
seed_random(void)
|
seed_random(void)
|
||||||
{
|
{
|
||||||
SEED_T seed;
|
SEED_T seed;
|
||||||
struct timespec ts;
|
struct timeval tv;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Seed from time of day and process id multiplied by small primes.
|
* Seed from time of day and process id multiplied by small primes.
|
||||||
*/
|
*/
|
||||||
(void) gettime(&ts);
|
(void) gettime(&tv);
|
||||||
seed = (ts.tv_sec % 10000) * 523 + ts.tv_nsec / 1000 * 13 +
|
seed = (tv.tv_sec % 10000) * 523 + tv.tv_usec * 13 +
|
||||||
(getpid() % 1000) * 983;
|
(getpid() % 1000) * 983;
|
||||||
SRAND(seed);
|
SRAND(seed);
|
||||||
}
|
}
|
@@ -337,8 +337,8 @@
|
|||||||
/* Define to 1 if you have the `memset' function. */
|
/* Define to 1 if you have the `memset' function. */
|
||||||
#undef HAVE_MEMSET
|
#undef HAVE_MEMSET
|
||||||
|
|
||||||
/* Define to 1 if you have the `mkstemp' function. */
|
/* Define to 1 if you have the `mkstemps' function. */
|
||||||
#undef HAVE_MKSTEMP
|
#undef HAVE_MKSTEMPS
|
||||||
|
|
||||||
/* Define to 1 if you have the <mps/ldap_ssl.h> header file. */
|
/* Define to 1 if you have the <mps/ldap_ssl.h> header file. */
|
||||||
#undef HAVE_MPS_LDAP_SSL_H
|
#undef HAVE_MPS_LDAP_SSL_H
|
||||||
|
12
configure
vendored
12
configure
vendored
@@ -15459,12 +15459,12 @@ fi
|
|||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
|
||||||
for ac_func in mkstemp
|
for ac_func in mkstemps
|
||||||
do :
|
do :
|
||||||
ac_fn_c_check_func "$LINENO" "mkstemp" "ac_cv_func_mkstemp"
|
ac_fn_c_check_func "$LINENO" "mkstemps" "ac_cv_func_mkstemps"
|
||||||
if test "x$ac_cv_func_mkstemp" = x""yes; then :
|
if test "x$ac_cv_func_mkstemps" = x""yes; then :
|
||||||
cat >>confdefs.h <<_ACEOF
|
cat >>confdefs.h <<_ACEOF
|
||||||
#define HAVE_MKSTEMP 1
|
#define HAVE_MKSTEMPS 1
|
||||||
_ACEOF
|
_ACEOF
|
||||||
|
|
||||||
else
|
else
|
||||||
@@ -15483,8 +15483,8 @@ fi
|
|||||||
done
|
done
|
||||||
|
|
||||||
case " $LIBOBJS " in
|
case " $LIBOBJS " in
|
||||||
*" mkstemp.$ac_objext "* ) ;;
|
*" mkstemps.$ac_objext "* ) ;;
|
||||||
*) LIBOBJS="$LIBOBJS mkstemp.$ac_objext"
|
*) LIBOBJS="$LIBOBJS mkstemps.$ac_objext"
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
|
@@ -1979,9 +1979,9 @@ AC_CHECK_FUNCS(closefrom, [], [AC_LIBOBJ(closefrom)
|
|||||||
[ #include <limits.h>
|
[ #include <limits.h>
|
||||||
#include <fcntl.h> ])
|
#include <fcntl.h> ])
|
||||||
])
|
])
|
||||||
AC_CHECK_FUNCS(mkstemp, [], [
|
AC_CHECK_FUNCS(mkstemps, [], [
|
||||||
AC_CHECK_FUNCS(random lrand48, [break])
|
AC_CHECK_FUNCS(random lrand48, [break])
|
||||||
AC_LIBOBJ(mkstemp)
|
AC_LIBOBJ(mkstemps)
|
||||||
])
|
])
|
||||||
AC_CHECK_FUNCS(snprintf vsnprintf asprintf vasprintf, , [NEED_SNPRINTF=1])
|
AC_CHECK_FUNCS(snprintf vsnprintf asprintf vasprintf, , [NEED_SNPRINTF=1])
|
||||||
if test X"$ac_cv_type_struct_timespec" != X"no"; then
|
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
|
#ifndef HAVE_MEMRCHR
|
||||||
void *memrchr(const void *, int, size_t);
|
void *memrchr(const void *, int, size_t);
|
||||||
#endif
|
#endif
|
||||||
#ifndef HAVE_MKSTEMP
|
#ifndef HAVE_MKSTEMPS
|
||||||
int mkstemp(char *);
|
int mkstemps(char *);
|
||||||
#endif
|
#endif
|
||||||
#ifndef HAVE_NANOSLEEP
|
#ifndef HAVE_NANOSLEEP
|
||||||
int nanosleep(const struct timespec *, struct timespec *);
|
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;
|
struct command_details editor_details;
|
||||||
ssize_t nread, nwritten;
|
ssize_t nread, nwritten;
|
||||||
const char *tmpdir;
|
const char *tmpdir;
|
||||||
char *cp, **nargv, **ap, **files = NULL;
|
char *cp, *suff, **nargv, **ap, **files = NULL;
|
||||||
char buf[BUFSIZ];
|
char buf[BUFSIZ];
|
||||||
int rc, i, j, ac, ofd, tfd, nargc, rval, tmplen;
|
int rc, i, j, ac, ofd, tfd, nargc, rval, tmplen;
|
||||||
int editor_argc = 0, nfiles = 0;
|
int editor_argc = 0, nfiles = 0;
|
||||||
@@ -178,14 +178,20 @@ sudo_edit(struct command_details *command_details, char *argv[], char *envp[])
|
|||||||
cp++;
|
cp++;
|
||||||
else
|
else
|
||||||
cp = tf[j].ofile;
|
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);
|
easprintf(&tf[j].tfile, "%.*s/%s.XXXXXXXX", tmplen, tmpdir, cp);
|
||||||
|
}
|
||||||
if (seteuid(user_details.uid) != 0)
|
if (seteuid(user_details.uid) != 0)
|
||||||
error(1, "seteuid(%d)", (int)user_details.uid);
|
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)
|
if (seteuid(ROOT_UID) != 0)
|
||||||
error(1, "seteuid(ROOT_UID)");
|
error(1, "seteuid(ROOT_UID)");
|
||||||
if (tfd == -1) {
|
if (tfd == -1) {
|
||||||
warning("mkstemp");
|
warning("mkstemps");
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
if (ofd != -1) {
|
if (ofd != -1) {
|
||||||
|
Reference in New Issue
Block a user