From: Todd C. Miller Date: Fri, 9 Jul 2010 13:49:33 +0000 (-0400) Subject: Use mkstemps() instead of mkstemp() in sudoedit. This allows sudoedit X-Git-Tag: SUDO_1_7_4~110 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=94d0ac0b26628df8d0b7bc26198a60154b99ae70;p=sudo 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. --HG-- branch : 1.7 --- diff --git a/Makefile.in b/Makefile.in index 0d5cc9711..9170163d0 100644 --- a/Makefile.in +++ b/Makefile.in @@ -107,7 +107,7 @@ SRCS = aix.c alias.c alloc.c audit.c boottime.c bsm_audit.c check.c \ 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 \ @@ -321,8 +321,8 @@ match.o: $(srcdir)/match.c $(SUDODEP) $(srcdir)/parse.h $(srcdir)/list.h $(srcdi $(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 diff --git a/config.h.in b/config.h.in index 728ae27ff..47a7ed3e3 100644 --- a/config.h.in +++ b/config.h.in @@ -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 header file. */ #undef HAVE_MPS_LDAP_SSL_H diff --git a/configure b/configure index 77e74cbbc..6f33c65dd 100755 --- a/configure +++ b/configure @@ -15405,16 +15405,16 @@ 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 - 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` diff --git a/configure.in b/configure.in index f7ead4090..d7ad654de 100644 --- a/configure.in +++ b/configure.in @@ -1972,7 +1972,7 @@ AC_CHECK_FUNCS(closefrom, [], [AC_LIBOBJ(closefrom) [ #include #include ]) ]) -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]) diff --git a/missing.h b/missing.h index a7990c262..749323a94 100644 --- a/missing.h +++ b/missing.h @@ -71,8 +71,8 @@ size_t strlcpy __P((char *, const char *, size_t)); #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 *)); diff --git a/mkstemp.c b/mkstemps.c similarity index 69% rename from mkstemp.c rename to mkstemps.c index 8a6108712..a46b01722 100644 --- a/mkstemp.c +++ b/mkstemps.c @@ -1,5 +1,6 @@ /* - * Copyright (c) 2001, 2003, 2008 Todd C. Miller + * Copyright (c) 2001, 2003, 2004, 2008-2010 + * Todd C. Miller * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -20,6 +21,7 @@ #include #include #include +#include #include #ifdef HAVE_STDLIB_H # include @@ -34,37 +36,51 @@ 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 @@ -87,13 +103,13 @@ static void 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); } diff --git a/sudo_edit.c b/sudo_edit.c index e5e14d496..f8666d955 100644 --- a/sudo_edit.c +++ b/sudo_edit.c @@ -69,7 +69,7 @@ sudo_edit(argc, argv, envp) { 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; @@ -143,12 +143,17 @@ sudo_edit(argc, argv, 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); + } 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) {