]> git.puffer.fish Git - mirror/frr.git/commitdiff
lib: create pid/vty directories
authorDavid Lamparter <equinox@opensourcerouting.org>
Thu, 1 Jun 2017 16:36:39 +0000 (18:36 +0200)
committerDavid Lamparter <equinox@opensourcerouting.org>
Wed, 2 Aug 2017 21:36:42 +0000 (23:36 +0200)
If the paths for pid or vty don't exist, try creating them.  Failure is
ignored (on EEXIST) or prints a non-fatal warning (other errors).

Fixes: #507
Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
lib/libfrr.c

index e0bba297e04cdde12ef39ae7c60ad33c05dd3f8b..6ebf837a1d86e945fdb8125bf93c7addb6e38bfd 100644 (file)
@@ -25,6 +25,7 @@
 
 #include "libfrr.h"
 #include "getopt.h"
+#include "privs.h"
 #include "vty.h"
 #include "command.h"
 #include "version.h"
@@ -332,6 +333,49 @@ int frr_getopt(int argc, char *const argv[], int *longindex)
        return opt;
 }
 
+static void frr_mkdir(const char *path, bool strip)
+{
+       char buf[256];
+       mode_t prev;
+       int ret;
+       struct zprivs_ids_t ids;
+
+       if (strip) {
+               char *slash = strrchr(path, '/');
+               size_t plen;
+               if (!slash)
+                       return;
+               plen = slash - path;
+               if (plen > sizeof(buf) - 1)
+                       return;
+               memcpy(buf, path, plen);
+               buf[plen] = '\0';
+               path = buf;
+       }
+
+       /* o+rx (..5) is needed for the frrvty group to work properly;
+        * without it, users in the frrvty group can't access the vty sockets.
+        */
+       prev = umask(0022);
+       ret = mkdir(path, 0755);
+       umask(prev);
+
+       if (ret != 0) {
+               /* if EEXIST, return without touching the permissions,
+                * so user-set custom permissions are left in place
+                */
+               if (errno == EEXIST)
+                       return;
+
+               zlog_warn("failed to mkdir \"%s\": %s", path, strerror(errno));
+               return;
+       }
+
+       zprivs_get_ids(&ids);
+       if (chown(path, ids.uid_normal, ids.gid_normal))
+               zlog_warn("failed to chown \"%s\": %s", path, strerror(errno));
+}
+
 static struct thread_master *master;
 struct thread_master *frr_init(void)
 {
@@ -355,6 +399,13 @@ struct thread_master *frr_init(void)
        zlog_set_level(ZLOG_DEST_SYSLOG, zlog_default->default_lvl);
 #endif
 
+       if (!di->pid_file || !di->vty_path)
+               frr_mkdir(frr_vtydir, false);
+       if (di->pid_file)
+               frr_mkdir(di->pid_file, true);
+       if (di->vty_path)
+               frr_mkdir(di->vty_path, true);
+
        frrmod_init(di->module);
        while (modules) {
                modules = (oc = modules)->next;