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