From 90a50860ebdcdeb5b7dc85790b18bed23c97ec32 Mon Sep 17 00:00:00 2001 From: Vincent Bernat Date: Wed, 8 Aug 2018 23:06:39 +0200 Subject: [PATCH] daemon: implement mkdir -p directly in lldpd It's difficult to know the path to mkdir. If we use the one from autoconf (@mkdir_p@), we get the path from the host, not the target. If we hardcode `/bin/mkdir`, we may not work on platforms like NixOS. See https://github.com/NixOS/nixpkgs/issues/44507. --- src/daemon/lldpd.service.in | 1 - src/daemon/priv.c | 34 ++++++++++++++++++++++++++++------ 2 files changed, 28 insertions(+), 7 deletions(-) diff --git a/src/daemon/lldpd.service.in b/src/daemon/lldpd.service.in index 42918303..920a1311 100644 --- a/src/daemon/lldpd.service.in +++ b/src/daemon/lldpd.service.in @@ -9,7 +9,6 @@ Type=notify NotifyAccess=main EnvironmentFile=-/etc/default/lldpd EnvironmentFile=-/etc/sysconfig/lldpd -ExecStartPre=/bin/mkdir -p @PRIVSEP_CHROOT@ ExecStart=@sbindir@/lldpd $DAEMON_ARGS $LLDPD_OPTIONS Restart=on-failure PrivateTmp=yes diff --git a/src/daemon/priv.c b/src/daemon/priv.c index 2b28bbd6..bf9fb550 100644 --- a/src/daemon/priv.c +++ b/src/daemon/priv.c @@ -510,18 +510,40 @@ sig_chld(int sig) priv_exit_rc_status(rc, status); } +/* Create a directory recursively. */ +static int mkdir_p(const char *pathname, mode_t mode) +{ + char path[PATH_MAX+1], current[PATH_MAX+1]; + char *tok; + + if (strlcpy(path, pathname, sizeof(path)) >= sizeof(path)) { + errno = ENAMETOOLONG; + return -1; + } + + /* Use strtok which will provides non-empty tokens only. */ + if (path[0] == '/') current[0] = '/'; + tok = strtok(path, "/"); + while (tok) { + strcat(current, tok); + if (mkdir(current, mode) != 0 && errno != EEXIST) + return -1; + strcat(current, "/"); + tok = strtok(NULL, "/"); + } + + errno = 0; + return 0; +} + /* Initialization */ #define LOCALTIME "/etc/localtime" static void priv_setup_chroot(const char *chrootdir) { /* Create chroot if it does not exist */ - if (mkdir(chrootdir, 0755) == -1) { - if (errno != EEXIST) - fatal("privsep", "unable to create chroot directory"); - } else { - log_info("privsep", "created chroot directory %s", - chrootdir); + if (mkdir_p(chrootdir, 0755) == -1) { + fatal("privsep", "unable to create chroot directory"); } /* Check if /etc/localtime exists in chroot or outside chroot */ -- 2.39.5