]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
index: Handle better errors where a new file's group can't be changed.
authorTimo Sirainen <tss@iki.fi>
Mon, 1 Jun 2009 02:03:25 +0000 (22:03 -0400)
committerTimo Sirainen <tss@iki.fi>
Mon, 1 Jun 2009 02:03:25 +0000 (22:03 -0400)
--HG--
branch : HEAD

src/lib-index/mail-cache-compress.c
src/lib-index/mail-index-private.h
src/lib-index/mail-index.c
src/lib-index/mail-transaction-log-file.c

index e8933bed68dd3c6f17a1d11a11dc9f0955f819de..3f1a11dba5a84bb9fad155843b31eda9d9bfa43e 100644 (file)
@@ -386,12 +386,8 @@ static int mail_cache_compress_locked(struct mail_cache *cache,
                return mail_cache_reopen(cache);
        }
 
-       if (cache->index->gid != (gid_t)-1 &&
-           fchown(fd, (uid_t)-1, cache->index->gid) < 0) {
-               mail_cache_set_syscall_error(cache, "fchown()");
-               file_dotlock_delete(&dotlock);
-               return -1;
-       }
+       mail_index_fchown(cache->index, fd,
+                         file_dotlock_get_lock_path(dotlock));
 
        if (mail_cache_copy(cache, trans, fd, &file_seq, &ext_offsets) < 0) {
                /* the fields may have been updated in memory already.
index dbd8ae6bc2e6d483e20afbee76fbcb38eae8128b..b918d3f08901a6dc3d16a0771f036b6a4e415b59 100644 (file)
@@ -301,6 +301,7 @@ struct mail_index_map *mail_index_map_clone(const struct mail_index_map *map);
 void mail_index_record_map_move_to_private(struct mail_index_map *map);
 /* Move a mmaped map to memory. */
 void mail_index_map_move_to_memory(struct mail_index_map *map);
+void mail_index_fchown(struct mail_index *index, int fd, const char *path);
 
 bool mail_index_map_lookup_ext(struct mail_index_map *map, const char *name,
                               uint32_t *idx_r);
index 8eb979bece08acd4eac40a99aee570fc4ccc9f1d..03729f2c50e92cbb725d5b9bcf8d8e3af209ad5d 100644 (file)
@@ -319,11 +319,7 @@ int mail_index_create_tmp_file(struct mail_index *index, const char **path_r)
        if (fd == -1)
                return mail_index_file_set_syscall_error(index, path, "open()");
 
-       if (index->gid != (gid_t)-1 && fchown(fd, (uid_t)-1, index->gid) < 0) {
-               mail_index_file_set_syscall_error(index, path, "fchown()");
-               return -1;
-       }
-
+       mail_index_fchown(index, fd, path);
        return fd;
 }
 
@@ -650,6 +646,37 @@ void mail_index_mark_corrupted(struct mail_index *index)
                mail_index_set_syscall_error(index, "unlink()");
 }
 
+void mail_index_fchown(struct mail_index *index, int fd, const char *path)
+{
+       mode_t mode;
+
+       if (index->gid == (gid_t)-1) {
+               /* no gid changing */
+               return;
+       } else if (fchown(fd, (uid_t)-1, index->gid) == 0) {
+               /* success */
+               return;
+       } if ((index->mode & 0066) == 0) {
+               /* group doesn't really matter, ignore silently. */
+               return;
+       } if ((index->mode & 0060) == 0) {
+               /* file access was granted to everyone, except this group.
+                  to make sure we don't expose it to the group, drop the world
+                  permissions too. */
+               mail_index_file_set_syscall_error(index, path, "fchown()");
+               mode = index->mode & 0600;
+       } else {
+               mail_index_file_set_syscall_error(index, path, "fchown()");
+               /* continue, but change group permissions to same as
+                  world-permissions were. */
+               mode = (index->mode & 0606) | ((index->mode & 06) << 3);
+       }
+       if (fchmod(fd, mode) < 0) {
+               mail_index_file_set_syscall_error(index, path,
+                                                 "fchmod()");
+       }
+}
+
 int mail_index_set_syscall_error(struct mail_index *index,
                                 const char *function)
 {
index 54a20ab45b60a79d9b70d365956e9564ce00edfd..b3930f5147b522fdd9e6c61e4166deb5df13850b 100644 (file)
@@ -677,14 +677,7 @@ int mail_transaction_log_file_create(struct mail_transaction_log_file *file,
                                                  "file_dotlock_open()");
                return -1;
        }
-
-       if (index->gid != (gid_t)-1 &&
-           fchown(fd, (uid_t)-1, index->gid) < 0) {
-               mail_index_file_set_syscall_error(index, file->filepath,
-                                                 "fchown()");
-               (void)file_dotlock_delete(&dotlock);
-               return -1;
-       }
+       mail_index_fchown(index, fd, file_dotlock_get_lock_path(dotlock));
 
         /* either fd gets used or the dotlock gets deleted and returned fd
            is for the existing file */