diff options
-rw-r--r-- | include/fileutils.h | 6 | ||||
-rw-r--r-- | lib/fileutils.c | 12 | ||||
-rw-r--r-- | login-utils/setpwnam.c | 3 | ||||
-rw-r--r-- | login-utils/vipw.c | 3 | ||||
-rw-r--r-- | term-utils/wall.c | 2 |
5 files changed, 17 insertions, 9 deletions
diff --git a/include/fileutils.h b/include/fileutils.h index 33aba0a0d..cf29e1b83 100644 --- a/include/fileutils.h +++ b/include/fileutils.h @@ -1,13 +1,13 @@ #ifndef UTIL_LINUX_FILEUTILS #define UTIL_LINUX_FILEUTILS -extern int xmkstemp(char **tmpname); +extern int xmkstemp(char **tmpname, char *dir); -static inline FILE *xfmkstemp(char **tmpname) +static inline FILE *xfmkstemp(char **tmpname, char *dir) { int fd; FILE *ret; - fd = xmkstemp(tmpname); + fd = xmkstemp(tmpname, dir); if (fd == -1) { return NULL; } diff --git a/lib/fileutils.c b/lib/fileutils.c index 0d4656f11..ff8bb8617 100644 --- a/lib/fileutils.c +++ b/lib/fileutils.c @@ -16,14 +16,20 @@ /* Create open temporary file in safe way. Please notice that the * file permissions are -rw------- by default. */ -int xmkstemp(char **tmpname) +int xmkstemp(char **tmpname, char *dir) { char *localtmp; char *tmpenv; mode_t old_mode; int fd; - tmpenv = getenv("TMPDIR"); + /* Some use cases must be capable of being moved atomically + * with rename(2), which is the reason why dir is here. */ + if (dir != NULL) + tmpenv = dir; + else + tmpenv = getenv("TMPDIR"); + if (tmpenv) xasprintf(&localtmp, "%s/%s.XXXXXX", tmpenv, program_invocation_short_name); @@ -68,7 +74,7 @@ int main(void) { FILE *f; char *tmpname; - f = xfmkstemp(&tmpname); + f = xfmkstemp(&tmpname, NULL); unlink(tmpname); free(tmpname); fclose(f); diff --git a/login-utils/setpwnam.c b/login-utils/setpwnam.c index 44dda98e7..23aef532d 100644 --- a/login-utils/setpwnam.c +++ b/login-utils/setpwnam.c @@ -81,10 +81,11 @@ int setpwnam(struct passwd *pwd) int contlen, rc; char *linebuf = NULL; char *tmpname = NULL; + char *atomic_dir = "/etc"; pw_init(); - if ((fp = xfmkstemp(&tmpname)) == NULL) + if ((fp = xfmkstemp(&tmpname, atomic_dir)) == NULL) return -1; /* ptmp should be owned by root.root or root.wheel */ diff --git a/login-utils/vipw.c b/login-utils/vipw.c index 66c682dc0..a5982813b 100644 --- a/login-utils/vipw.c +++ b/login-utils/vipw.c @@ -143,8 +143,9 @@ static FILE * pw_tmpfile(int lockfd) { FILE *fd; char *tmpname = NULL; + char *dir = "/etc"; - if ((fd = xfmkstemp(&tmpname)) == NULL) { + if ((fd = xfmkstemp(&tmpname, dir)) == NULL) { ulckpwdf(); err(EXIT_FAILURE, _("can't open temporary file")); } diff --git a/term-utils/wall.c b/term-utils/wall.c index 0291a5b60..3255a5166 100644 --- a/term-utils/wall.c +++ b/term-utils/wall.c @@ -190,7 +190,7 @@ makemsg(char *fname, size_t *mbufsize, int print_banner) line_max = sysconf(_SC_LINE_MAX); lbuf = xmalloc(line_max); - if ((fp = xfmkstemp(&tmpname)) == NULL) + if ((fp = xfmkstemp(&tmpname, NULL)) == NULL) err(EXIT_FAILURE, _("can't open temporary file")); unlink(tmpname); free(tmpname); |