diff options
| author | David Lamparter <equinox@opensourcerouting.org> | 2017-06-01 18:36:39 +0200 |
|---|---|---|
| committer | David Lamparter <equinox@opensourcerouting.org> | 2017-08-02 23:36:42 +0200 |
| commit | beaa54706a6a18022eac79b3af3d543c21708102 (patch) | |
| tree | 6b2beb2d0189f46db528b9cc7fa740bfe8741667 /lib/libfrr.c | |
| parent | 37a1f2fbb6e05053098a5f1af5eff16ac523dd35 (diff) | |
lib: create pid/vty directories
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>
Diffstat (limited to 'lib/libfrr.c')
| -rw-r--r-- | lib/libfrr.c | 51 |
1 files changed, 51 insertions, 0 deletions
diff --git a/lib/libfrr.c b/lib/libfrr.c index e0bba297e0..6ebf837a1d 100644 --- a/lib/libfrr.c +++ b/lib/libfrr.c @@ -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; |
