fileops.c find_path.c fnmatch.c get_pty.c getcwd.c getprogname.c \
getspwuid.c gettime.c glob.c goodpath.c gram.c gram.y interfaces.c \
iolog.c isblank.c lbuf.c ldap.c linux_audit.c list.c logging.c match.c \
- mksiglist.c mkstemp.c memrchr.c nanosleep.c parse.c parse_args.c \
+ mksiglist.c mkstemps.c memrchr.c nanosleep.c parse.c parse_args.c \
pwutil.c set_perms.c setsid.c sigaction.c snprintf.c strcasecmp.c \
strerror.c strlcat.c strlcpy.c strsignal.c sudo.c sudo_noexec.c \
sudo_edit.c sudo_nss.c term.c testsudoers.c tgetpass.c toke.c toke.l \
$(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(OPTIONS) $(srcdir)/match.c
memrchr.o: $(srcdir)/memrchr.c $(SUDODEP)
$(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(OPTIONS) $(srcdir)/memrchr.c
-mkstemp.o: $(srcdir)/mkstemp.c $(SUDODEP)
- $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(OPTIONS) $(srcdir)/mkstemp.c
+mkstemps.o: $(srcdir)/mkstemps.c $(SUDODEP)
+ $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(OPTIONS) $(srcdir)/mkstemps.c
nanosleep.o: $(srcdir)/nanosleep.c $(srcdir)/compat.h config.h
$(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(OPTIONS) $(srcdir)/nanosleep.c
parse.o: $(srcdir)/parse.c $(SUDODEP) $(srcdir)/parse.h $(srcdir)/list.h $(devdir)/gram.h
/* 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
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
- SUDO_OBJS="${SUDO_OBJS} mkstemp.o"
+ SUDO_OBJS="${SUDO_OBJS} mkstemps.o"
for ac_func in random lrand48
do :
as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
[ #include <limits.h>
#include <fcntl.h> ])
])
-AC_CHECK_FUNCS(mkstemp, [], [SUDO_OBJS="${SUDO_OBJS} mkstemp.o"
+AC_CHECK_FUNCS(mkstemps, [], [SUDO_OBJS="${SUDO_OBJS} mkstemps.o"
AC_CHECK_FUNCS(random lrand48, [break])
])
AC_CHECK_FUNCS(snprintf vsnprintf asprintf vasprintf, , [NEED_SNPRINTF=1])
#ifndef HAVE_MEMRCHR
void *memrchr __P((const void *, int, size_t));
#endif
-#ifndef HAVE_MKSTEMP
-int mkstemp __P((char *));
+#ifndef HAVE_MKSTEMPS
+int mkstemps __P((char *, int));
#endif
#ifndef HAVE_NANOSLEEP
int nanosleep __P((const struct timespec *, struct timespec *));
/*
- * Copyright (c) 2001, 2003, 2008 Todd C. Miller <Todd.Miller@courtesan.com>
+ * 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
* purpose with or without fee is hereby granted, provided that the above
#include <sys/stat.h>
#include <errno.h>
#include <fcntl.h>
+#include <limits.h>
#include <stdio.h>
#ifdef HAVE_STDLIB_H
# include <stdlib.h>
static unsigned int get_random __P((void));
static void seed_random __P((void));
+#define TEMPCHARS "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
+#define NUM_CHARS (sizeof(TEMPCHARS) - 1)
+
+#ifndef INT_MAX
+#define INT_MAX 0x7fffffff
+#endif
+
int
-mkstemp(path)
+mkstemps(path, slen)
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') {
+ for (ep = path; *ep; ep++)
+ ;
+ if (path + slen >= ep) {
errno = EINVAL;
- return(0);
+ return(-1);
}
+ ep -= slen;
- for (cp = path; *cp; cp++)
- ;
- do {
- cp--;
- } while (cp >= path && *cp == 'X');
- start = cp + 1;
+ tries = 1;
+ for (start = ep; start > path && start[-1] == 'X'; start--) {
+ if (tries < INT_MAX / NUM_CHARS)
+ tries *= NUM_CHARS;
+ }
+ tries *= 2;
- for (;;) {
+ 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
seed_random()
{
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);
}
{
ssize_t nread, nwritten;
const char *tmpdir;
- char *cp, **nargv, *editor, **files;
+ char *cp, *suff, **nargv, *editor, **files;
char **editor_argv = NULL;
char buf[BUFSIZ];
int rc, i, j, ac, ofd, tfd, nargc, rval, nfiles, tmplen;
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);
+ }
set_perms(PERM_USER);
- tfd = mkstemp(tf[j].tfile);
+ tfd = mkstemps(tf[j].tfile, suff ? strlen(suff) : 0);
set_perms(PERM_ROOT);
if (tfd == -1) {
- warning("mkstemp");
+ warning("mkstemps");
goto cleanup;
}
if (ofd != -1) {