From: Timo Sirainen Date: Mon, 14 Dec 2009 02:35:28 +0000 (-0500) Subject: dovecot-uidvalidity*: Create files with correct permission. X-Git-Tag: 2.0.beta1~4 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=a920bbb8580be2446af28a77dac9ecf548f3c6f4;p=thirdparty%2Fdovecot%2Fcore.git dovecot-uidvalidity*: Create files with correct permission. --HG-- branch : HEAD --- diff --git a/src/lib-storage/index/dbox-common/dbox-storage.c b/src/lib-storage/index/dbox-common/dbox-storage.c index a10659c4b5..93794c61b7 100644 --- a/src/lib-storage/index/dbox-common/dbox-storage.c +++ b/src/lib-storage/index/dbox-common/dbox-storage.c @@ -36,7 +36,7 @@ uint32_t dbox_get_uidvalidity_next(struct mailbox_list *list) path = mailbox_list_get_path(list, NULL, MAILBOX_LIST_PATH_TYPE_CONTROL); path = t_strconcat(path, "/"DBOX_UIDVALIDITY_FILE_NAME, NULL); - return mailbox_uidvalidity_next(path); + return mailbox_uidvalidity_next(list, path); } void dbox_notify_changes(struct mailbox *box) diff --git a/src/lib-storage/index/maildir/maildir-storage.c b/src/lib-storage/index/maildir/maildir-storage.c index 06c41046e7..91d398c4d1 100644 --- a/src/lib-storage/index/maildir/maildir-storage.c +++ b/src/lib-storage/index/maildir/maildir-storage.c @@ -1084,7 +1084,7 @@ uint32_t maildir_get_uidvalidity_next(struct mailbox_list *list) path = mailbox_list_get_path(list, NULL, MAILBOX_LIST_PATH_TYPE_CONTROL); path = t_strconcat(path, "/"MAILDIR_UIDVALIDITY_FNAME, NULL); - return mailbox_uidvalidity_next(path); + return mailbox_uidvalidity_next(list, path); } static void maildir_storage_add_list(struct mail_storage *storage, diff --git a/src/lib-storage/mailbox-uidvalidity.c b/src/lib-storage/mailbox-uidvalidity.c index 70843c754b..dc99ff584d 100644 --- a/src/lib-storage/mailbox-uidvalidity.c +++ b/src/lib-storage/mailbox-uidvalidity.c @@ -5,6 +5,8 @@ #include "str.h" #include "read-full.h" #include "write-full.h" +#include "eacces-error.h" +#include "mailbox-list.h" #include "mailbox-uidvalidity.h" #include @@ -12,6 +14,7 @@ #include #include #include +#include #define RETRY_COUNT 10 @@ -29,16 +32,34 @@ static uint32_t mailbox_uidvalidity_next_fallback(void) return uid_validity; } -static void mailbox_uidvalidity_write(const char *path, uint32_t uid_validity) +static void mailbox_uidvalidity_write(struct mailbox_list *list, + const char *path, uint32_t uid_validity) { char buf[8+1]; int fd; + mode_t mode, old_mask; + gid_t gid; + const char *gid_origin; + mailbox_list_get_permissions(list, NULL, &mode, &gid, &gid_origin); + + old_mask = umask(0666 & ~mode); fd = open(path, O_RDWR | O_CREAT, 0666); + umask(old_mask); if (fd == -1) { i_error("open(%s) failed: %m", path); return; } + if (gid != (gid_t)-1 && fchown(fd, (uid_t)-1, gid) < 0) { + if (errno == EPERM) { + i_error("%s", eperm_error_get_chgrp("fchown", path, + gid, gid_origin)); + } else { + i_error("fchown(%s, -1, %ld) failed: %m", + path, (long)gid); + } + } + i_snprintf(buf, sizeof(buf), "%08x", uid_validity); if (pwrite_full(fd, buf, strlen(buf), 0) < 0) i_error("write(%s) failed: %m", path); @@ -76,7 +97,8 @@ static int mailbox_uidvalidity_rename(const char *path, uint32_t *uid_validity) return ret; } -static uint32_t mailbox_uidvalidity_next_rescan(const char *path) +static uint32_t +mailbox_uidvalidity_next_rescan(struct mailbox_list *list, const char *path) { DIR *d; struct dirent *dp; @@ -84,6 +106,7 @@ static uint32_t mailbox_uidvalidity_next_rescan(const char *path) char *endp; unsigned int i, prefix_len; uint32_t cur_value, min_value, max_value; + mode_t old_mask; int fd; fname = strrchr(path, '/'); @@ -126,7 +149,10 @@ static uint32_t mailbox_uidvalidity_next_rescan(const char *path) for (i = 0; i < RETRY_COUNT; i++) { cur_value = mailbox_uidvalidity_next_fallback(); tmp = t_strdup_printf("%s.%08x", path, cur_value); - fd = open(tmp, O_RDWR | O_CREAT | O_EXCL, 0666); + /* the file is empty, don't bother with permissions */ + old_mask = umask(0); + fd = open(tmp, O_RDWR | O_CREAT | O_EXCL, 0444); + umask(old_mask); if (fd != -1 || errno != EEXIST) break; /* already exists. although it's quite unlikely we'll @@ -138,7 +164,7 @@ static uint32_t mailbox_uidvalidity_next_rescan(const char *path) return cur_value; } (void)close(fd); - mailbox_uidvalidity_write(path, cur_value); + mailbox_uidvalidity_write(list, path, cur_value); return cur_value; } if (min_value != max_value) { @@ -151,11 +177,11 @@ static uint32_t mailbox_uidvalidity_next_rescan(const char *path) cur_value = max_value; if (mailbox_uidvalidity_rename(path, &cur_value) < 0) return mailbox_uidvalidity_next_fallback(); - mailbox_uidvalidity_write(path, cur_value); + mailbox_uidvalidity_write(list, path, cur_value); return cur_value; } -uint32_t mailbox_uidvalidity_next(const char *path) +uint32_t mailbox_uidvalidity_next(struct mailbox_list *list, const char *path) { char buf[8+1], *endp; uint32_t cur_value; @@ -165,25 +191,25 @@ uint32_t mailbox_uidvalidity_next(const char *path) if (fd == -1) { if (errno != ENOENT) i_error("open(%s) failed: %m", path); - return mailbox_uidvalidity_next_rescan(path); + return mailbox_uidvalidity_next_rescan(list, path); } ret = read_full(fd, buf, sizeof(buf)-1); if (ret < 0) { i_error("read(%s) failed: %m", path); (void)close(fd); - return mailbox_uidvalidity_next_rescan(path); + return mailbox_uidvalidity_next_rescan(list, path); } buf[sizeof(buf)-1] = 0; cur_value = strtoul(buf, &endp, 16); if (ret == 0 || endp != buf+sizeof(buf)-1) { /* broken value */ (void)close(fd); - return mailbox_uidvalidity_next_rescan(path); + return mailbox_uidvalidity_next_rescan(list, path); } /* we now have the current uidvalidity value that's hopefully correct */ if (mailbox_uidvalidity_rename(path, &cur_value) < 0) - return mailbox_uidvalidity_next_rescan(path); + return mailbox_uidvalidity_next_rescan(list, path); /* fast path succeeded. write the current value to the main uidvalidity file. */ diff --git a/src/lib-storage/mailbox-uidvalidity.h b/src/lib-storage/mailbox-uidvalidity.h index 735de5375c..388d78f7c4 100644 --- a/src/lib-storage/mailbox-uidvalidity.h +++ b/src/lib-storage/mailbox-uidvalidity.h @@ -1,6 +1,8 @@ #ifndef MAILBOX_UIDVALIDITY_H #define MAILBOX_UIDVALIDITY_H -uint32_t mailbox_uidvalidity_next(const char *path); +struct mailbox_list; + +uint32_t mailbox_uidvalidity_next(struct mailbox_list *list, const char *path); #endif