diff options
author | Wayne Davison <wayned@samba.org> | 2009-04-10 16:09:39 -0700 |
---|---|---|
committer | Wayne Davison <wayned@samba.org> | 2009-04-10 16:09:39 -0700 |
commit | ea53d161be54a474088df51063df128ff5da5af4 (patch) | |
tree | a9b49475719b70b107c4e483f2a59ada57454523 /acls.c | |
parent | 7875e6fe63805a3412cb4a8673a2dbf233631110 (diff) | |
download | rsync-ea53d161be54a474088df51063df128ff5da5af4.tar.gz rsync-ea53d161be54a474088df51063df128ff5da5af4.tar.bz2 rsync-ea53d161be54a474088df51063df128ff5da5af4.zip |
Fixed an ACL/xattr corruption issue where the --backup option could cause
rsync to associate the wrong ACL/xattr information with received files.
Diffstat (limited to 'acls.c')
-rw-r--r-- | acls.c | 38 |
1 files changed, 37 insertions, 1 deletions
@@ -88,6 +88,9 @@ static const rsync_acl empty_rsync_acl = { static item_list access_acl_list = EMPTY_ITEM_LIST; static item_list default_acl_list = EMPTY_ITEM_LIST; +static size_t prior_access_count = (size_t)-1; +static size_t prior_default_count = (size_t)-1; + /* === Calculations on ACL types === */ static const char *str_acl_type(SMB_ACL_TYPE_T type) @@ -788,17 +791,50 @@ static int cache_rsync_acl(rsync_acl *racl, SMB_ACL_TYPE_T type, item_list *racl /* Turn the ACL data in stat_x into cached ACL data, setting the index * values in the file struct. */ -void cache_acl(struct file_struct *file, stat_x *sxp) +void cache_tmp_acl(struct file_struct *file, stat_x *sxp) { + if (prior_access_count == (size_t)-1) + prior_access_count = access_acl_list.count; + F_ACL(file) = cache_rsync_acl(sxp->acc_acl, SMB_ACL_TYPE_ACCESS, &access_acl_list); if (S_ISDIR(sxp->st.st_mode)) { + if (prior_default_count == (size_t)-1) + prior_default_count = default_acl_list.count; F_DIR_DEFACL(file) = cache_rsync_acl(sxp->def_acl, SMB_ACL_TYPE_DEFAULT, &default_acl_list); } } +static void uncache_duo_acls(item_list *duo_list, size_t start) +{ + acl_duo *duo_item = duo_list->items; + acl_duo *duo_start = duo_item + start; + + duo_item += duo_list->count; + duo_list->count = start; + + while (duo_item-- > duo_start) { + rsync_acl_free(&duo_item->racl); + if (duo_item->sacl) + sys_acl_free_acl(duo_item->sacl); + } +} + +void uncache_tmp_acls(void) +{ + if (prior_access_count != (size_t)-1) { + uncache_duo_acls(&access_acl_list, prior_access_count); + prior_access_count = (size_t)-1; + } + + if (prior_default_count != (size_t)-1) { + uncache_duo_acls(&default_acl_list, prior_default_count); + prior_default_count = (size_t)-1; + } +} + #ifndef HAVE_OSX_ACLS static mode_t change_sacl_perms(SMB_ACL_T sacl, rsync_acl *racl, mode_t old_mode, mode_t mode) { |