]> git.ipfire.org Git - thirdparty/chrony.git/commitdiff
conf: create directory for Unix domain command socket
authorMiroslav Lichvar <mlichvar@redhat.com>
Tue, 11 Aug 2015 15:41:02 +0000 (17:41 +0200)
committerMiroslav Lichvar <mlichvar@redhat.com>
Wed, 12 Aug 2015 12:45:23 +0000 (14:45 +0200)
Try to create the directory where will be the Unix domain command socket
bound to allow starting with empty /var/run. Check the permissions and
owner/group in case the directory already existed. It MUST NOT be
accessible by others as permissions on Unix domain sockets are ignored
on some systems (e.g. Solaris).

conf.c
util.c
util.h

diff --git a/conf.c b/conf.c
index 9ebb268e3cb171f2b7f891d69d53a76ffcbd21a5..c1b62cd5ba054556e82d44c90c0552c804e2650b 100644 (file)
--- a/conf.c
+++ b/conf.c
@@ -1261,8 +1261,26 @@ parse_include(char *line)
 void
 CNF_CreateDirs(uid_t uid, gid_t gid)
 {
+  char *dir;
+
   UTI_CreateDirAndParents(logdir, 0755, uid, gid);
   UTI_CreateDirAndParents(dumpdir, 0755, uid, gid);
+
+  /* Create a directory for the Unix domain command socket */
+  if (bind_cmd_path[0]) {
+    dir = UTI_PathToDir(bind_cmd_path);
+    UTI_CreateDirAndParents(dir, 0770, uid, gid);
+
+    /* Check the permissions and owner/group in case the directory already
+       existed.  It MUST NOT be accessible by others as permissions on Unix
+       domain sockets are ignored on some systems (e.g. Solaris). */
+    if (!UTI_CheckDirPermissions(dir, 0770, uid, gid)) {
+      LOG(LOGS_WARN, LOGF_Configure, "Disabled command socket %s", bind_cmd_path);
+      bind_cmd_path[0] = '\0';
+    }
+
+    Free(dir);
+  }
 }
 
 /* ================================================== */
diff --git a/util.c b/util.c
index 08d3110491bd45998bc6d3b180ff7059748f288c..f03ebaf05f3b89698877cc4b51d131a38587ae0c 100644 (file)
--- a/util.c
+++ b/util.c
@@ -897,6 +897,27 @@ UTI_SetQuitSignalsHandler(void (*handler)(int))
 
 /* ================================================== */
 
+char *
+UTI_PathToDir(const char *path)
+{
+  char *dir, *slash;
+
+  slash = strrchr(path, '/');
+
+  if (!slash)
+    return Strdup(".");
+
+  if (slash == path)
+    return Strdup("/");
+
+  dir = Malloc(slash - path + 1);
+  snprintf(dir, slash - path + 1, "%s", path);
+
+  return dir;
+}
+
+/* ================================================== */
+
 static int
 create_dir(char *p, mode_t mode, uid_t uid, gid_t gid)
 {
@@ -986,3 +1007,33 @@ UTI_CreateDirAndParents(const char *path, mode_t mode, uid_t uid, gid_t gid)
   Free(p);
   return 1;
 }
+
+/* ================================================== */
+
+int
+UTI_CheckDirPermissions(const char *path, mode_t perm, uid_t uid, gid_t gid)
+{
+  struct stat buf;
+
+  if (stat(path, &buf)) {
+    LOG(LOGS_ERR, LOGF_Util, "Could not access %s : %s", path, strerror(errno));
+    return 0;
+  }
+
+  if (!S_ISDIR(buf.st_mode)) {
+    LOG(LOGS_ERR, LOGF_Util, "%s is not directory", path);
+    return 0;
+  }
+
+  if ((buf.st_mode & 0777) & ~perm) {
+    LOG(LOGS_ERR, LOGF_Util, "Wrong permissions on %s", path);
+    return 0;
+  }
+
+  if (buf.st_uid != uid || buf.st_gid != gid) {
+    LOG(LOGS_ERR, LOGF_Util, "Wrong owner/group of %s", path);
+    return 0;
+  }
+
+  return 1;
+}
diff --git a/util.h b/util.h
index 4b4efe4e7190b72043061a82e947a154f5fe790c..360fced2825bf6989c8a6d8294dbd25ea5c7d3cc 100644 (file)
--- a/util.h
+++ b/util.h
@@ -130,10 +130,17 @@ extern int UTI_DecodePasswordFromText(char *key);
 
 extern int UTI_SetQuitSignalsHandler(void (*handler)(int));
 
+/* Get directory (as an allocated string) for a path */
+extern char *UTI_PathToDir(const char *path);
+
 /* Create a directory with a specified mode (umasked) and set its uid/gid
    (if not 0).  Create also any parent directories that don't exist with mode
    755 and default uid/gid.  Returns 1 if created or already exists (even with
    different mode/uid/gid), 0 otherwise. */
 extern int UTI_CreateDirAndParents(const char *path, mode_t mode, uid_t uid, gid_t gid);
 
+/* Check if a directory is secure.  It must not have other than the specified
+   permissions and its uid/gid must match the specified values. */
+extern int UTI_CheckDirPermissions(const char *path, mode_t perm, uid_t uid, gid_t gid);
+
 #endif /* GOT_UTIL_H */