dovecot-2.0: dict file: Get file's initial permissions based on ...

dovecot at dovecot.org dovecot at dovecot.org
Fri Apr 16 14:43:00 EEST 2010


details:   http://hg.dovecot.org/dovecot-2.0/rev/b3947e64546a
changeset: 11158:b3947e64546a
user:      Timo Sirainen <tss at iki.fi>
date:      Fri Apr 16 14:42:58 2010 +0300
description:
dict file: Get file's initial permissions based on parent directory.

diffstat:

 src/lib-dict/dict-file.c |  76 ++++++++++++++++++++++++++++----------
 1 files changed, 56 insertions(+), 20 deletions(-)

diffs (103 lines):

diff -r af46998fdccf -r b3947e64546a src/lib-dict/dict-file.c
--- a/src/lib-dict/dict-file.c	Fri Apr 16 13:22:19 2010 +0300
+++ b/src/lib-dict/dict-file.c	Fri Apr 16 14:42:58 2010 +0300
@@ -312,36 +312,68 @@
 	}
 }
 
+static int
+fd_copy_stat_permissions(const struct stat *src_st,
+			 int dest_fd, const char *dest_path)
+{
+	struct stat dest_st;
+
+	if (fstat(dest_fd, &dest_st) < 0) {
+		i_error("fstat(%s) failed: %m", dest_path);
+		return -1;
+	}
+
+	if (src_st->st_gid != dest_st.st_gid &&
+	    ((src_st->st_mode & 0070) >> 3 != (src_st->st_mode & 0007))) {
+		/* group has different permissions from world.
+		   preserve the group. */
+		if (fchown(dest_fd, (uid_t)-1, src_st->st_gid) < 0) {
+			i_error("fchown(%s, -1, %s) failed: %m",
+				dest_path, dec2str(src_st->st_gid));
+			return -1;
+		}
+	}
+
+	if ((src_st->st_mode & 07777) != (dest_st.st_mode & 07777)) {
+		if (fchmod(dest_fd, src_st->st_mode & 07777) < 0) {
+			i_error("fchmod(%s, %o) failed: %m",
+				dest_path, (int)(src_st->st_mode & 0777));
+			return -1;
+		}
+	}
+	return 0;
+}
+
 static int fd_copy_permissions(int src_fd, const char *src_path,
 			       int dest_fd, const char *dest_path)
 {
-	struct stat src_st, dest_st;
+	struct stat src_st;
 
 	if (fstat(src_fd, &src_st) < 0) {
 		i_error("fstat(%s) failed: %m", src_path);
 		return -1;
 	}
-	if (fstat(dest_fd, &dest_st) < 0) {
-		i_error("fstat(%s) failed: %m", dest_path);
+	return fd_copy_stat_permissions(&src_st, dest_fd, dest_path);
+}
+
+static int
+fd_copy_parent_dir_permissions(const char *src_path, int dest_fd,
+			       const char *dest_path)
+{
+	struct stat src_st;
+	const char *src_dir, *p;
+
+	p = strrchr(src_path, '/');
+	if (p == NULL)
+		src_dir = ".";
+	else
+		src_dir = t_strdup_until(src_path, p);
+	if (stat(src_dir, &src_st) < 0) {
+		i_error("stat(%s) failed: %m", src_dir);
 		return -1;
 	}
-
-	if (src_st.st_gid != dest_st.st_gid) {
-		if (fchown(dest_fd, (uid_t)-1, src_st.st_gid) < 0) {
-			i_error("fchown(%s, -1, %s) failed: %m",
-				dest_path, dec2str(src_st.st_gid));
-			return -1;
-		}
-	}
-
-	if ((src_st.st_mode & 07777) != (dest_st.st_mode & 07777)) {
-		if (fchmod(dest_fd, src_st.st_mode & 07777) < 0) {
-			i_error("fchmod(%s, %o) failed: %m",
-				dest_path, (int)(src_st.st_mode & 0777));
-			return -1;
-		}
-	}
-	return 0;
+	src_st.st_mode &= 0666;
+	return fd_copy_stat_permissions(&src_st, dest_fd, dest_path);
 }
 
 static int file_dict_write_changes(struct file_dict_transaction_context *ctx)
@@ -369,6 +401,10 @@
 		/* preserve the permissions */
 		(void)fd_copy_permissions(dict->fd, dict->path, fd,
 					  file_dotlock_get_lock_path(dotlock));
+	} else {
+		/* get initial permissions from parent directory */
+		(void)fd_copy_parent_dir_permissions(dict->path, fd,
+					file_dotlock_get_lock_path(dotlock));
 	}
 	file_dict_apply_changes(ctx);
 


More information about the dovecot-cvs mailing list