# HG changeset patch # User Timo Sirainen # Date 1297462566 -7200 # Node ID e2605d2d6b33a723a190c3fa4ee2ac227bc94806 # Parent 31b633336ab5615b4fe109684a1289ef47d536f3 lib-storage: Don't allow renaming mailbox under another one with different permissions. This is mainly to avoid any weird situations arising with shared mailboxes. diff -r 31b633336ab5 -r e2605d2d6b33 src/lib-storage/list/mailbox-list-fs.c --- a/src/lib-storage/list/mailbox-list-fs.c Sat Feb 12 00:15:04 2011 +0200 +++ b/src/lib-storage/list/mailbox-list-fs.c Sat Feb 12 00:16:06 2011 +0200 @@ -447,11 +447,11 @@ { struct mail_storage *oldstorage; const char *oldvname, *oldpath, *newpath, *alt_newpath, *root_path; - const char *p, *origin; + const char *p, *origin, *old_origin; enum mailbox_list_path_type path_type, alt_path_type; struct stat st; - mode_t file_mode, dir_mode; - gid_t gid; + mode_t file_mode, dir_mode, old_file_mode, old_dir_mode; + gid_t gid, old_gid; bool rmdir_parent = FALSE; oldvname = mailbox_list_get_vname(oldlist, oldname); @@ -486,11 +486,25 @@ return -1; } + mailbox_list_get_permissions(oldlist, oldname, &old_file_mode, + &old_dir_mode, &old_gid, &old_origin); + mailbox_list_get_permissions(newlist, newname, &file_mode, + &dir_mode, &gid, &origin); + + /* if we're renaming under another mailbox, require its permissions + to be same as ours. */ + if (strchr(newname, mailbox_list_get_hierarchy_sep(newlist)) != NULL && + (file_mode != old_file_mode || + dir_mode != old_dir_mode || gid != old_gid)) { + mailbox_list_set_error(oldlist, MAIL_ERROR_NOTPOSSIBLE, + "Renaming not supported across conflicting " + "directory permissions"); + return -1; + } + /* create the hierarchy */ p = strrchr(newpath, '/'); if (p != NULL) { - mailbox_list_get_root_permissions(newlist, &file_mode, - &dir_mode, &gid, &origin); p = t_strdup_until(newpath, p); if (mkdir_parents_chgrp(p, dir_mode, gid, origin) < 0 && errno != EEXIST) { diff -r 31b633336ab5 -r e2605d2d6b33 src/lib-storage/list/mailbox-list-maildir.c --- a/src/lib-storage/list/mailbox-list-maildir.c Sat Feb 12 00:15:04 2011 +0200 +++ b/src/lib-storage/list/mailbox-list-maildir.c Sat Feb 12 00:16:06 2011 +0200 @@ -574,6 +574,28 @@ return -1; } + /* if we're renaming under another mailbox, require its permissions + to be same as ours. */ + if (strchr(newname, mailbox_list_get_hierarchy_sep(newlist)) != NULL) { + const char *origin, *old_origin; + mode_t file_mode, dir_mode, old_file_mode, old_dir_mode; + gid_t gid, old_gid; + + mailbox_list_get_permissions(oldlist, oldname, &old_file_mode, + &old_dir_mode, &old_gid, &old_origin); + mailbox_list_get_permissions(newlist, newname, &file_mode, + &dir_mode, &gid, &origin); + + if ((file_mode != old_file_mode || + dir_mode != old_dir_mode || gid != old_gid)) { + mailbox_list_set_error(oldlist, MAIL_ERROR_NOTPOSSIBLE, + "Renaming not supported across conflicting " + "directory permissions"); + return -1; + } + } + + ret = rename(oldpath, newpath); if (ret == 0 || errno == ENOENT) { (void)rename_dir(oldlist, oldname, newlist, newname,