Mercurial > dovecot > original-hg > dovecot-1.2
changeset 9000:b02c642b4e51 HEAD
dict-file: When replacing the dict file, preserve its permissions.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Thu, 30 Apr 2009 20:22:49 -0400 |
parents | afc1b0ef120d |
children | 5302ce189a70 |
files | src/lib-dict/dict-file.c |
diffstat | 1 files changed, 37 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- a/src/lib-dict/dict-file.c Thu Apr 30 20:00:09 2009 -0400 +++ b/src/lib-dict/dict-file.c Thu Apr 30 20:22:49 2009 -0400 @@ -280,6 +280,38 @@ } } +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; + + 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 -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; +} + static int file_dict_write_changes(struct file_dict_transaction_context *ctx) { struct file_dict *dict = (struct file_dict *)ctx->ctx.dict; @@ -301,6 +333,11 @@ file_dotlock_delete(&dotlock); return -1; } + if (dict->fd != -1) { + /* preserve the permissions */ + (void)fd_copy_permissions(dict->fd, dict->path, fd, + file_dotlock_get_lock_path(dotlock)); + } file_dict_apply_changes(ctx); output = o_stream_create_fd(fd, 0, FALSE);