]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lda: If temp file can't be created because home dir doesn't exist, create it.
authortimo@timo-desktop <timo@timo-desktop>
Tue, 26 May 2009 02:38:26 +0000 (22:38 -0400)
committertimo@timo-desktop <timo@timo-desktop>
Tue, 26 May 2009 02:38:26 +0000 (22:38 -0400)
--HG--
branch : HEAD

src/lda/main.c

index d996c9f1be86c2f47ff541fc296f3884300d4645..4ae61a022b43653971572b6e33f4cf18db50a406 100644 (file)
@@ -8,6 +8,8 @@
 #include "istream.h"
 #include "istream-seekable.h"
 #include "safe-mkstemp.h"
+#include "eacces-error.h"
+#include "mkdir-parents.h"
 #include "str.h"
 #include "str-sanitize.h"
 #include "strescape.h"
@@ -39,7 +41,8 @@
 
 /* After buffer grows larger than this, create a temporary file to /tmp
    where to read the mail. */
-#define MAIL_MAX_MEMORY_BUFFER (1024*128)
+//#define MAIL_MAX_MEMORY_BUFFER (1024*128)
+#define MAIL_MAX_MEMORY_BUFFER 10
 
 static const char *wanted_headers[] = {
        "From", "To", "Message-ID", "Subject", "Return-Path",
@@ -84,15 +87,50 @@ static const char *address_sanitize(const char *address)
        return ret;
 }
 
+static int deliver_create_dir(struct mail_user *user, const char *dir)
+{
+       struct mail_namespace *ns;
+       mode_t mode;
+       gid_t gid;
+
+       ns = mail_namespace_find_inbox(user->namespaces);
+       if (ns == NULL)
+               ns = user->namespaces;
+
+       mailbox_list_get_dir_permissions(ns->list, NULL, &mode, &gid);
+       if (mkdir_parents_chown(dir, mode, (uid_t)-1, gid) == 0) {
+               return 0;
+       } else if (errno == EACCES) {
+               i_error("%s", eacces_error_get_creating("mkdir_parents_chown",
+                                                       dir));
+               return -1;
+       } else {
+               i_error("mkdir_parents_chown(%s, gid=%s) failed: %m",
+                       dir, dec2str(gid));
+               return -1;
+       }
+}
+
 static int seekable_fd_callback(const char **path_r, void *context)
 {
        struct mail_deliver_context *ctx = context;
+       const char *dir, *p;
        string_t *path;
        int fd;
 
        path = t_str_new(128);
        str_append(path, mail_user_get_temp_prefix(ctx->dest_user));
        fd = safe_mkstemp(path, 0600, (uid_t)-1, (gid_t)-1);
+       if (fd == -1 && errno == ENOENT) {
+               dir = str_c(path);
+               p = strrchr(dir, '/');
+               if (p != NULL) {
+                       dir = t_strdup_until(dir, p);
+                       if (deliver_create_dir(ctx->dest_user, dir) < 0)
+                               return -1;
+                       fd = safe_mkstemp(path, 0600, (uid_t)-1, (gid_t)-1);
+               }
+       }
        if (fd == -1) {
                i_error("safe_mkstemp(%s) failed: %m", str_c(path));
                return -1;