dovecot-2.2: fs-posix: Added mode=auto parameter to copy mode fr...
dovecot at dovecot.org
dovecot at dovecot.org
Thu Nov 19 15:44:15 UTC 2015
details: http://hg.dovecot.org/dovecot-2.2/rev/52e0fb4f2693
changeset: 19403:52e0fb4f2693
user: Timo Sirainen <tss at iki.fi>
date: Thu Nov 19 17:43:47 2015 +0200
description:
fs-posix: Added mode=auto parameter to copy mode from parent directory if setgid-bit is set
diffstat:
src/lib-fs/fs-posix.c | 55 ++++++++++++++++++++++++++++++++++++++++++++------
1 files changed, 48 insertions(+), 7 deletions(-)
diffs (108 lines):
diff -r 4564f4300c91 -r 52e0fb4f2693 src/lib-fs/fs-posix.c
--- a/src/lib-fs/fs-posix.c Thu Nov 19 17:19:19 2015 +0200
+++ b/src/lib-fs/fs-posix.c Thu Nov 19 17:43:47 2015 +0200
@@ -34,6 +34,7 @@
unsigned int temp_file_prefix_len;
enum fs_posix_lock_method lock_method;
mode_t mode;
+ bool mode_auto;
};
struct posix_fs_file {
@@ -102,6 +103,8 @@
fs->path_prefix = i_strconcat(arg + 7, "/", NULL);
else
fs->path_prefix = i_strdup(arg + 7);
+ } else if (strcmp(arg, "mode=auto") == 0) {
+ fs->mode_auto = TRUE;
} else if (strncmp(arg, "mode=", 5) == 0) {
unsigned int mode;
if (str_to_uint_oct(arg+5, &mode) < 0) {
@@ -140,21 +143,51 @@
FS_PROPERTY_STAT | FS_PROPERTY_ITER | FS_PROPERTY_RELIABLEITER;
}
+static int
+fs_posix_get_mode(struct posix_fs *fs, const char *path, mode_t *mode_r)
+{
+ struct stat st;
+ const char *p;
+
+ *mode_r = fs->mode;
+
+ while (stat(path, &st) < 0) {
+ if (errno != ENOENT) {
+ fs_set_error(&fs->fs, "stat(%s) failed: %m", path);
+ return -1;
+ }
+ p = strrchr(path, '/');
+ if (p != NULL)
+ path = t_strdup_until(path, p);
+ else if (strcmp(path, ".") != 0)
+ path = ".";
+ else
+ return 0;
+ }
+ if ((st.st_mode & S_ISGID) != 0) {
+ /* setgid set - copy mode from parent */
+ *mode_r = st.st_mode & 0666;
+ }
+ return 0;
+}
+
static int fs_posix_mkdir_parents(struct posix_fs *fs, const char *path)
{
const char *dir, *fname;
- mode_t dir_mode;
+ mode_t mode, dir_mode;
fname = strrchr(path, '/');
if (fname == NULL)
return 1;
+ dir = t_strdup_until(path, fname);
- dir_mode = fs->mode;
+ if (fs_posix_get_mode(fs, dir, &mode) < 0)
+ return -1;
+ dir_mode = mode;
if ((dir_mode & 0600) != 0) dir_mode |= 0100;
if ((dir_mode & 0060) != 0) dir_mode |= 0010;
if ((dir_mode & 0006) != 0) dir_mode |= 0001;
- dir = t_strdup_until(path, fname);
if (mkdir_parents(dir, dir_mode) == 0)
return 0;
else if (errno == EEXIST)
@@ -198,20 +231,28 @@
string_t *str = t_str_new(256);
const char *slash;
unsigned int try_count = 0;
+ mode_t mode;
int fd;
i_assert(file->temp_path == NULL);
- if ((slash = strrchr(file->full_path, '/')) != NULL)
- str_append_n(str, file->full_path, slash - file->full_path + 1);
+ if ((slash = strrchr(file->full_path, '/')) != NULL) {
+ str_append_n(str, file->full_path, slash - file->full_path);
+ if (fs_posix_get_mode(fs, str_c(str), &mode) < 0)
+ return -1;
+ str_append_c(str, '/');
+ } else {
+ if (fs_posix_get_mode(fs, ".", &mode) < 0)
+ return -1;
+ }
str_append(str, fs->temp_file_prefix);
- fd = safe_mkstemp_hostpid(str, fs->mode, (uid_t)-1, (gid_t)-1);
+ fd = safe_mkstemp_hostpid(str, mode, (uid_t)-1, (gid_t)-1);
while (fd == -1 && errno == ENOENT &&
try_count <= MAX_MKDIR_RETRY_COUNT) {
if (fs_posix_mkdir_parents(fs, str_c(str)) < 0)
return -1;
- fd = safe_mkstemp_hostpid(str, fs->mode, (uid_t)-1, (gid_t)-1);
+ fd = safe_mkstemp_hostpid(str, mode, (uid_t)-1, (gid_t)-1);
try_count++;
}
if (fd == -1) {
More information about the dovecot-cvs
mailing list