]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
fileutils: xmkstemp() interface change
authorDave Reisner <dreisner@archlinux.org>
Sat, 2 Jun 2012 17:31:30 +0000 (19:31 +0200)
committerSami Kerola <kerolasa@iki.fi>
Sat, 2 Jun 2012 18:29:12 +0000 (20:29 +0200)
We can not let the user control where TMPDIR is for this tempfile.
This will be where we write the updated passwd file, and must be
capable of being moved atomically with rename(2).  Therefore, it
cannot be on a different device, or setpwnam() and vipw/vigr programs
will invariably fail with EXDEV.

Signed-off-by: Dave Reisner <dreisner@archlinux.org>
Signed-off-by: Sami Kerola <kerolasa@iki.fi>
include/fileutils.h
lib/fileutils.c
login-utils/setpwnam.c
login-utils/vipw.c
term-utils/wall.c

index 33aba0a0d51a8123b06078ad207d0fa8acdcae9e..cf29e1b83d15a56f7c1eb2e718ee71f01b8a043d 100644 (file)
@@ -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;
        }
index 0d4656f1109f59545dc751d849a365acb888a0ae..ff8bb8617fbf57a26f011a58c15fa664f5252c77 100644 (file)
 
 /* 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);
index 44dda98e73498eaa09f3216ddb16c49a8f0dab8e..23aef532dd13147019778854018a17d4993a34a9 100644 (file)
@@ -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 */
index 66c682dc038ab8fe4fcf46818276f69da81c006a..a5982813bf943cf23107fa51bb075e1ece6bf864 100644 (file)
@@ -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"));
        }
index 0291a5b609b1004a5d228513407ce8cf4f5a0665..3255a516682e0d36fca157e7d6977cbf3e4cb3d2 100644 (file)
@@ -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);