dovecot-1.2: index: Handle better errors where a new file's grou...

dovecot at dovecot.org dovecot at dovecot.org
Mon Jun 1 05:03:33 EEST 2009


details:   http://hg.dovecot.org/dovecot-1.2/rev/0f2f9e207644
changeset: 9107:0f2f9e207644
user:      Timo Sirainen <tss at iki.fi>
date:      Sun May 31 22:03:25 2009 -0400
description:
index: Handle better errors where a new file's group can't be changed.

diffstat:

4 files changed, 36 insertions(+), 19 deletions(-)
src/lib-index/mail-cache-compress.c       |    8 +-----
src/lib-index/mail-index-private.h        |    1 
src/lib-index/mail-index.c                |   37 +++++++++++++++++++++++++----
src/lib-index/mail-transaction-log-file.c |    9 -------

diffs (102 lines):

diff -r 940dc274068c -r 0f2f9e207644 src/lib-index/mail-cache-compress.c
--- a/src/lib-index/mail-cache-compress.c	Sun May 31 21:32:17 2009 -0400
+++ b/src/lib-index/mail-cache-compress.c	Sun May 31 22:03:25 2009 -0400
@@ -386,12 +386,8 @@ static int mail_cache_compress_locked(st
 		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.
diff -r 940dc274068c -r 0f2f9e207644 src/lib-index/mail-index-private.h
--- a/src/lib-index/mail-index-private.h	Sun May 31 21:32:17 2009 -0400
+++ b/src/lib-index/mail-index-private.h	Sun May 31 22:03:25 2009 -0400
@@ -299,6 +299,7 @@ void mail_index_record_map_move_to_priva
 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);
diff -r 940dc274068c -r 0f2f9e207644 src/lib-index/mail-index.c
--- a/src/lib-index/mail-index.c	Sun May 31 21:32:17 2009 -0400
+++ b/src/lib-index/mail-index.c	Sun May 31 22:03:25 2009 -0400
@@ -319,11 +319,7 @@ int mail_index_create_tmp_file(struct ma
 	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;
 }
 
@@ -632,6 +628,37 @@ void mail_index_mark_corrupted(struct ma
 		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)
 {
diff -r 940dc274068c -r 0f2f9e207644 src/lib-index/mail-transaction-log-file.c
--- a/src/lib-index/mail-transaction-log-file.c	Sun May 31 21:32:17 2009 -0400
+++ b/src/lib-index/mail-transaction-log-file.c	Sun May 31 22:03:25 2009 -0400
@@ -675,14 +675,7 @@ int mail_transaction_log_file_create(str
 						  "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 */


More information about the dovecot-cvs mailing list