]> git.netwichtig.de Git - user/henk/code/exim.git/blobdiff - src/src/directory.c
TLS: fix tls_verify_certificates handling of "system"
[user/henk/code/exim.git] / src / src / directory.c
index d6cac2cb8096d6dce6042890f6203054bee17bba..3273eb89b066a23f8ed35dbc7f7f0b3f4e5434f0 100644 (file)
@@ -1,10 +1,9 @@
-/* $Cambridge: exim/src/src/directory.c,v 1.6 2009/11/16 19:50:36 nm4 Exp $ */
-
 /*************************************************
 *     Exim - an Internet mail transport agent    *
 *************************************************/
 
 /* Copyright (c) University of Cambridge 1995 - 2009 */
+/* Copyright (c) The Exim Maintainers 2010 - 2018 */
 /* See the file NOTICE for conditions of use and distribution. */
 
 #include "exim.h"
@@ -40,54 +39,57 @@ directory_make(const uschar *parent, const uschar *name,
                int mode, BOOL panic)
 {
 BOOL use_chown = parent == spool_directory && geteuid() == root_uid;
-uschar *p;
-const uschar *slash;
-int c = 1;
+uschar * p;
+uschar c = 1;
 struct stat statbuf;
-uschar buffer[256];
+uschar * path;
+
+if (is_tainted2(name, LOG_MAIN|LOG_PANIC, "Tainted path '%s' for new directory", name))
+  { p = US"create"; path = US name; errno = EACCES; goto bad; }
 
-if (parent == NULL)
+if (parent)
   {
-  p = buffer + 1;
-  slash = parent = CUS"";
+  path = string_sprintf("%s%s%s", parent, US"/", name);
+  p = path + Ustrlen(parent);
   }
 else
   {
-  p = buffer + Ustrlen(parent);
-  slash = US"/";
+  path = string_copy(name);
+  p = path + 1;
   }
 
-if (!string_format(buffer, sizeof(buffer), "%s%s%s", parent, slash, name))
-  log_write(0, LOG_MAIN|LOG_PANIC_DIE, "name too long in directory_make");
+/* Walk the path creating any missing directories */
 
-while (c != 0 && *p != 0)
+while (c && *p)
   {
-  while (*p != 0 && *p != '/') p++;
+  while (*p && *p != '/') p++;
   c = *p;
-  *p = 0;
-  if (Ustat(buffer, &statbuf) != 0)
+  *p = '\0';
+  if (Ustat(path, &statbuf) != 0)
     {
-    if (mkdir(CS buffer, mode) < 0 && errno != EEXIST)
-      {
-      if (!panic) return FALSE;
-      log_write(0, LOG_MAIN|LOG_PANIC_DIE,
-        "Failed to create directory \"%s\": %s\n", buffer, strerror(errno));
-      }
+    if (mkdir(CS path, mode) < 0 && errno != EEXIST)
+      { p = US"create"; goto bad; }
 
     /* Set the ownership if necessary. */
 
-    if (use_chown) (void)Uchown(buffer, exim_uid, exim_gid);
+    if (use_chown && exim_chown(path, exim_uid, exim_gid))
+      { p = US"set owner on"; goto bad; }
 
     /* It appears that any mode bits greater than 0777 are ignored by
     mkdir(), at least on some operating systems. Therefore, if the mode
     contains any such bits, do an explicit mode setting. */
 
-    if ((mode & 0777000) != 0) (void)Uchmod(buffer, mode);
+    if (mode & 0777000) (void) Uchmod(path, mode);
     }
   *p++ = c;
   }
 
 return TRUE;
+
+bad:
+  if (panic) log_write(0, LOG_MAIN|LOG_PANIC_DIE,
+    "Failed to %s directory \"%s\": %s\n", p, path, exim_errstr(errno));
+  return FALSE;
 }
 
 /* End of directory.c */