]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
call fr_mkdir() with only directory arguments
authorAlan T. DeKok <aland@freeradius.org>
Tue, 10 Dec 2024 14:13:29 +0000 (09:13 -0500)
committerAlan T. DeKok <aland@freeradius.org>
Wed, 11 Dec 2024 20:20:26 +0000 (15:20 -0500)
src/lib/bio/fd_open.c

index afc29621a4179b7fc4c0a9b9a8cad7bc53101a53..e74d3f2863c3bd0fa13adb779a64dbe133162e14 100644 (file)
@@ -1231,28 +1231,46 @@ int fr_bio_fd_reopen(fr_bio_t *bio)
                return -1;
        }
 
-       if (cfg->mkdir &&
-           (fr_mkdir(&fd, cfg->filename, strlen(cfg->filename), cfg->perm, fr_mkdir_chown,
-                     &(fr_mkdir_chown_t) {
-                             .uid = cfg->uid,
-                             .gid = cfg->gid,
-                     }) < 0)) {
-               return -1;
-       }
-
        /*
         *      Create it if necessary.
         */
        flags = cfg->flags;
        if (flags != O_RDONLY) flags |= O_CREAT;
 
-       /*
-        *      Client BIOs writing to a file, and therefore need to create it.
-        */
-       fd = open(cfg->filename, flags, cfg->perm);
-       if (fd < 0) {
-               fr_strerror_printf("Failed opening file %s: %s", cfg->filename, fr_syserror(errno));
-               return -1;
+       if (!cfg->mkdir) {
+               /*
+                *      Client BIOs writing to a file, and therefore need to create it.
+                */
+       do_open:
+               fd = open(cfg->filename, flags, cfg->perm);
+               if (fd < 0) {
+               failed_open:
+                       fr_strerror_printf("Failed opening file %s: %s", cfg->filename, fr_syserror(errno));
+                       return -1;
+               }
+       
+       } else {
+               /*
+                *      We make the parent directory if told to, AND if there's a '/' in the path.
+                */
+               char *p = strrchr(cfg->filename, '/');
+               int dir_fd;
+
+               if (!p) goto do_open;
+
+               if (fr_mkdir(&dir_fd, cfg->filename, (size_t) (p - cfg->filename), cfg->perm, fr_mkdir_chown,
+                             &(fr_mkdir_chown_t) {
+                                     .uid = cfg->uid,
+                                     .gid = cfg->gid,
+                             }) < 0) {
+                       return -1;
+               }
+
+               fd = openat(dir_fd, p + 1, flags, cfg->perm);
+               if (fd < 0) {
+                       close(dir_fd);
+                       goto failed_open;
+               }
        }
 
        /*