Dear misc,

I am playing with rdist for some basic management of config files on remote machines. I have run into an issue with rdistd where it (apparently) has to create two or more directories in succession and then copy files across to those newly created directories.

aspireone: updating host aspireone
aspireone: ./scripts: installing
aspireone: scripts: mkdir
aspireone: ./scripts/util: installing
aspireone: ./scripts/install: installing
aspireone: ./scripts/files: installing
aspireone: ./hosts/aspireone/etc/doas.conf: installing
aspireone: staging: mkdir
aspireone: staging/etc: mkdir
aspireone: REMOTE ERROR: staging/etc/rdistRWoWItah: create failed: Invalid 
argument
aspireone: ./hosts/aspireone/etc/rc.conf.local: installing


In server.c recvfile(), a failed call to mkstemp() can result in a second call to mkstemp() with an invalid template string. This is because the first call to mkstemp() modifies the template string such that it no longer contains the magic "XXXXXXXX".

I have included a diff (below) that seems to correct the behaviour by restoring the template string before the second call to mkstemp(). I haven't looked into why the first call to mkstemp() fails, but given the existing handling of that I am assuming it's not totally unexpected. Here is some log output after applying the patch:

> aspireone: updating host aspireone
> aspireone: ./scripts: installing
> aspireone: scripts: mkdir
> aspireone: ./scripts/util: installing
> aspireone: ./scripts/install: installing
> aspireone: ./scripts/files: installing
> aspireone: ./hosts/aspireone/etc/doas.conf: installing
> aspireone: staging: mkdir
> aspireone: staging/etc: mkdir
> aspireone: ./hosts/aspireone/etc/rc.conf.local: installing


Index: ./src/usr.bin/rdistd/server.c
===================================================================
RCS file: /cvs/src/usr.bin/rdistd/server.c,v
retrieving revision 1.40
diff -u -r1.40 server.c
--- ./src/usr.bin/rdistd/server.c       22 Dec 2015 08:48:39 -0000      1.40
+++ ./src/usr.bin/rdistd/server.c       27 Mar 2016 18:03:14 -0000
@@ -743,16 +743,24 @@
 {
        int f, wrerr, olderrno;
        off_t i;
-       char *cp;
+       char *cp, *tp;
        char *savefile = NULL;
        static struct stat statbuff;

        /*
         * Create temporary file
         */
+       tp = strstr(new, "XXXXXX");
        if ((f = mkstemp(new)) < 0) {
-               if (errno != ENOENT || chkparent(new, opts) < 0 ||
-                   (f = mkstemp(new)) < 0) {
+               if (errno != ENOENT || chkparent(new, opts) < 0) {
+                       error("%s: create failed: %s", new, SYSERR);
+                       return;
+               }
+               /* Restore the original template. */
+               for ( ; *tp; ++tp) {
+                       *tp = 'X';
+               }
+               if ((f = mkstemp(new)) < 0) {
                        error("%s: create failed: %s", new, SYSERR);
                        return;
                }

Reply via email to