dovecot-1.2: Use permissions based on mail root directory when c...
dovecot at dovecot.org
dovecot at dovecot.org
Sun Jul 20 23:20:23 EEST 2008
details: http://hg.dovecot.org/dovecot-1.2/rev/ab1c170b1559
changeset: 8037:ab1c170b1559
user: Timo Sirainen <tss at iki.fi>
date: Sun Jul 20 23:20:19 2008 +0300
description:
Use permissions based on mail root directory when creating new files/dirs under it.
diffstat:
11 files changed, 132 insertions(+), 49 deletions(-)
src/lib-storage/index/cydir/cydir-storage.c | 7 ++
src/lib-storage/index/dbox/dbox-storage.c | 7 ++
src/lib-storage/index/index-storage.c | 38 +++++++++++++--
src/lib-storage/index/maildir/maildir-storage.c | 58 +++++++++--------------
src/lib-storage/index/maildir/maildir-util.c | 3 -
src/lib-storage/index/mbox/mbox-storage.c | 7 +-
src/lib-storage/list/mailbox-list-fs.c | 7 +-
src/lib-storage/list/subscription-file.c | 13 +++--
src/lib-storage/mailbox-list.c | 15 +++++
src/lib-storage/mailbox-list.h | 4 +
src/plugins/quota/quota-maildir.c | 22 +++++++-
diffs (truncated from 425 to 300 lines):
diff -r b3303b65c3f2 -r ab1c170b1559 src/lib-storage/index/cydir/cydir-storage.c
--- a/src/lib-storage/index/cydir/cydir-storage.c Sun Jul 20 23:19:34 2008 +0300
+++ b/src/lib-storage/index/cydir/cydir-storage.c Sun Jul 20 23:20:19 2008 +0300
@@ -130,7 +130,12 @@ static int cydir_create(struct mail_stor
static int create_cydir(struct mail_storage *storage, const char *path)
{
- if (mkdir_parents(path, CREATE_MODE) < 0 && errno != EEXIST) {
+ mode_t mode;
+ gid_t gid;
+
+ mailbox_list_get_dir_permissions(storage->list, &mode, &gid);
+ if (mkdir_parents_chown(path, mode, (uid_t)-1, gid) < 0 &&
+ errno != EEXIST) {
if (!mail_storage_set_error_from_errno(storage)) {
mail_storage_set_critical(storage,
"mkdir(%s) failed: %m", path);
diff -r b3303b65c3f2 -r ab1c170b1559 src/lib-storage/index/dbox/dbox-storage.c
--- a/src/lib-storage/index/dbox/dbox-storage.c Sun Jul 20 23:19:34 2008 +0300
+++ b/src/lib-storage/index/dbox/dbox-storage.c Sun Jul 20 23:20:19 2008 +0300
@@ -146,7 +146,12 @@ static int dbox_create(struct mail_stora
static int create_dbox(struct mail_storage *storage, const char *path)
{
- if (mkdir_parents(path, CREATE_MODE) < 0 && errno != EEXIST) {
+ mode_t mode;
+ gid_t gid;
+
+ mailbox_list_get_dir_permissions(storage->list, &mode, &gid);
+ if (mkdir_parents_chown(path, mode, (uid_t)-1, gid) < 0 &&
+ errno != EEXIST) {
if (!mail_storage_set_error_from_errno(storage)) {
mail_storage_set_critical(storage,
"mkdir(%s) failed: %m", path);
diff -r b3303b65c3f2 -r ab1c170b1559 src/lib-storage/index/index-storage.c
--- a/src/lib-storage/index/index-storage.c Sun Jul 20 23:19:34 2008 +0300
+++ b/src/lib-storage/index/index-storage.c Sun Jul 20 23:20:19 2008 +0300
@@ -17,8 +17,6 @@
#include <unistd.h>
#include <sys/stat.h>
-#define CREATE_MODE 0770 /* umask() should limit it more */
-
#define DEFAULT_CACHE_FIELDS ""
#define DEFAULT_NEVER_CACHE_FIELDS "imap.envelope"
@@ -69,9 +67,38 @@ static void index_list_free(struct index
i_free(list);
}
+static int stat_parent(struct mail_storage *storage, const char *path,
+ mode_t *mode_r, gid_t *gid_r)
+{
+ struct stat st;
+ const char *p;
+
+ while ((p = strrchr(path, '/')) != NULL) {
+ path = t_strdup_until(path, p);
+ if (stat(path, &st) == 0) {
+ *mode_r = st.st_mode;
+ *gid_r = (st.st_mode & S_ISGID) != 0 ||
+ st.st_gid == getegid() ?
+ (gid_t)-1 : st.st_gid;
+ return 0;
+ }
+ if (errno != ENOENT) {
+ mail_storage_set_critical(storage,
+ "stat(%s) failed: %m", path);
+ return -1;
+ }
+ }
+ /* use default permissions */
+ *mode_r = 0700;
+ *gid_r = (gid_t)-1;
+ return 0;
+}
+
static int create_index_dir(struct mail_storage *storage, const char *name)
{
const char *root_dir, *index_dir;
+ mode_t mode;
+ gid_t gid;
root_dir = mailbox_list_get_path(storage->list, name,
MAILBOX_LIST_PATH_TYPE_MAILBOX);
@@ -80,7 +107,12 @@ static int create_index_dir(struct mail_
if (strcmp(index_dir, root_dir) == 0 || *index_dir == '\0')
return 0;
- if (mkdir_parents(index_dir, CREATE_MODE) < 0 && errno != EEXIST) {
+ /* get permissions from the parent directory */
+ if (stat_parent(storage, index_dir, &mode, &gid) < 0)
+ return -1;
+
+ if (mkdir_parents_chown(index_dir, mode, (uid_t)-1, gid) < 0 &&
+ errno != EEXIST) {
mail_storage_set_critical(storage, "mkdir(%s) failed: %m",
index_dir);
return -1;
diff -r b3303b65c3f2 -r ab1c170b1559 src/lib-storage/index/maildir/maildir-storage.c
--- a/src/lib-storage/index/maildir/maildir-storage.c Sun Jul 20 23:19:34 2008 +0300
+++ b/src/lib-storage/index/maildir/maildir-storage.c Sun Jul 20 23:20:19 2008 +0300
@@ -20,8 +20,6 @@
#include <dirent.h>
#include <unistd.h>
#include <sys/stat.h>
-
-#define CREATE_MODE 0777 /* umask() should limit it more */
#define MAILDIR_PLUSPLUS_DRIVER_NAME "maildir++"
#define MAILDIR_SUBFOLDER_FILENAME "maildirfolder"
@@ -290,7 +288,7 @@ static bool maildir_autodetect(const cha
}
static int mkdir_verify(struct mail_storage *storage,
- const char *dir, bool verify)
+ const char *dir, mode_t mode, gid_t gid, bool verify)
{
struct stat st;
@@ -305,7 +303,7 @@ static int mkdir_verify(struct mail_stor
}
}
- if (mkdir_parents(dir, CREATE_MODE) == 0)
+ if (mkdir_parents_chown(dir, mode, (uid_t)-1, gid) == 0)
return 0;
if (errno == EEXIST) {
@@ -355,8 +353,10 @@ static int maildir_check_tmp(struct mail
/* create or fix maildir, ignore if it already exists */
static int create_maildir(struct mail_storage *storage,
- const char *dir, bool verify)
-{
+ const char *dir, mode_t mode, gid_t gid, bool verify)
+{
+ const char *path;
+ unsigned int i;
int ret;
ret = maildir_check_tmp(storage, dir);
@@ -372,12 +372,11 @@ static int create_maildir(struct mail_st
return -1;
/* doesn't exist, create */
- if (mkdir_verify(storage, t_strconcat(dir, "/cur", NULL), verify) < 0)
- return -1;
- if (mkdir_verify(storage, t_strconcat(dir, "/new", NULL), verify) < 0)
- return -1;
- if (mkdir_verify(storage, t_strconcat(dir, "/tmp", NULL), verify) < 0)
- return -1;
+ for (i = 0; i < N_ELEMENTS(maildir_subdirs); i++) {
+ path = t_strconcat(dir, "/", maildir_subdirs[i], NULL);
+ if (mkdir_verify(storage, path, mode, gid, verify) < 0)
+ return -1;
+ }
return 0;
}
@@ -474,6 +473,8 @@ maildir_mailbox_open(struct mail_storage
struct maildir_storage *storage = (struct maildir_storage *)_storage;
const char *path;
struct stat st;
+ mode_t mode;
+ gid_t gid;
int ret;
if (input != NULL) {
@@ -488,7 +489,8 @@ maildir_mailbox_open(struct mail_storage
if (strcmp(name, "INBOX") == 0 &&
(_storage->ns->flags & NAMESPACE_FLAG_INBOX) != 0) {
/* INBOX always exists */
- if (create_maildir(_storage, path, TRUE) < 0)
+ mailbox_list_get_dir_permissions(_storage->list, &mode, &gid);
+ if (create_maildir(_storage, path, mode, gid, TRUE) < 0)
return NULL;
return maildir_open(storage, "INBOX", flags);
}
@@ -506,7 +508,8 @@ maildir_mailbox_open(struct mail_storage
/* tmp/ directory doesn't exist. does the maildir? */
if (stat(path, &st) == 0) {
/* yes, we'll need to create the missing dirs */
- if (create_maildir(_storage, path, TRUE) < 0)
+ mailbox_list_get_dir_permissions(_storage->list, &mode, &gid);
+ if (create_maildir(_storage, path, mode, gid, TRUE) < 0)
return NULL;
return maildir_open(storage, name, flags);
@@ -526,7 +529,6 @@ static int maildir_create_shared(struct
{
const char *path;
mode_t old_mask;
- unsigned int i;
int fd;
/* add the execute bit if either read or write bit is set */
@@ -534,23 +536,10 @@ static int maildir_create_shared(struct
if ((mode & 0060) != 0) mode |= 0010;
if ((mode & 0006) != 0) mode |= 0001;
+ if (create_maildir(storage, dir, mode, gid, FALSE) < 0)
+ return -1;
+
old_mask = umask(0777 ^ mode);
- if (create_maildir(storage, dir, FALSE) < 0) {
- umask(old_mask);
- return -1;
- }
- if (chown(dir, (uid_t)-1, gid) < 0) {
- mail_storage_set_critical(storage,
- "chown(%s) failed: %m", dir);
- }
- for (i = 0; i < N_ELEMENTS(maildir_subdirs); i++) {
- path = t_strconcat(dir, "/", maildir_subdirs[i], NULL);
- if (chown(path, (uid_t)-1, gid) < 0) {
- mail_storage_set_critical(storage,
- "chown(%s) failed: %m", path);
- }
- }
-
path = t_strconcat(dir, "/dovecot-shared", NULL);
fd = open(path, O_WRONLY | O_CREAT, mode & 0666);
umask(old_mask);
@@ -590,9 +579,10 @@ static int maildir_mailbox_create(struct
st.st_mode & 0666, st.st_gid) < 0)
return -1;
} else {
- st.st_mode = CREATE_MODE;
- st.st_gid = (gid_t)-1;
- if (create_maildir(_storage, path, FALSE) < 0)
+ mailbox_list_get_dir_permissions(_storage->list,
+ &st.st_mode, &st.st_gid);
+ if (create_maildir(_storage, path, st.st_mode, st.st_gid,
+ FALSE) < 0)
return -1;
}
diff -r b3303b65c3f2 -r ab1c170b1559 src/lib-storage/index/maildir/maildir-util.c
--- a/src/lib-storage/index/maildir/maildir-util.c Sun Jul 20 23:19:34 2008 +0300
+++ b/src/lib-storage/index/maildir/maildir-util.c Sun Jul 20 23:20:19 2008 +0300
@@ -115,7 +115,8 @@ static int maildir_create_subdirs(struct
"stat(%s) failed: %m", path);
break;
}
- if (mkdir_parents(path, box->dir_create_mode) < 0 &&
+ if (mkdir_parents_chown(path, box->dir_create_mode,
+ (uid_t)-1, box->file_create_gid) < 0 &&
errno != EEXIST) {
if (errno == ENOENT) {
/* mailbox was being deleted just now */
diff -r b3303b65c3f2 -r ab1c170b1559 src/lib-storage/index/mbox/mbox-storage.c
--- a/src/lib-storage/index/mbox/mbox-storage.c Sun Jul 20 23:19:34 2008 +0300
+++ b/src/lib-storage/index/mbox/mbox-storage.c Sun Jul 20 23:20:19 2008 +0300
@@ -692,8 +692,9 @@ static int mbox_mailbox_create(struct ma
{
const char *path, *p;
struct stat st;
+ mode_t mode;
+ gid_t gid;
int fd;
-
/* make sure it doesn't exist already */
path = mailbox_list_get_path(_storage->list, name,
@@ -719,7 +720,9 @@ static int mbox_mailbox_create(struct ma
p = directory ? path + strlen(path) : strrchr(path, '/');
if (p != NULL) {
p = t_strdup_until(path, p);
- if (mkdir_parents(p, CREATE_MODE) < 0 && errno != EEXIST) {
+ mailbox_list_get_dir_permissions(_storage->list, &mode, &gid);
+ if (mkdir_parents_chown(p, mode, (uid_t)-1, gid) < 0 &&
+ errno != EEXIST) {
if (!mail_storage_set_error_from_errno(_storage)) {
mail_storage_set_critical(_storage,
"mkdir_parents(%s) failed: %m", p);
diff -r b3303b65c3f2 -r ab1c170b1559 src/lib-storage/list/mailbox-list-fs.c
--- a/src/lib-storage/list/mailbox-list-fs.c Sun Jul 20 23:19:34 2008 +0300
+++ b/src/lib-storage/list/mailbox-list-fs.c Sun Jul 20 23:20:19 2008 +0300
@@ -11,7 +11,6 @@
#include <unistd.h>
#include <sys/stat.h>
-#define CREATE_MODE 0770 /* umask() should limit it more */
#define GLOBAL_TEMP_PREFIX ".temp."
extern struct mailbox_list fs_mailbox_list;
@@ -283,6 +282,8 @@ static int fs_list_rename_mailbox(struct
{
const char *oldpath, *newpath, *old_indexdir, *new_indexdir, *p;
struct stat st;
+ mode_t mode;
+ gid_t gid;
oldpath = mailbox_list_get_path(list, oldname,
MAILBOX_LIST_PATH_TYPE_DIR);
@@ -292,8 +293,10 @@ static int fs_list_rename_mailbox(struct
/* create the hierarchy */
p = strrchr(newpath, '/');
if (p != NULL) {
More information about the dovecot-cvs
mailing list