summaryrefslogtreecommitdiff
path: root/acls.c
diff options
context:
space:
mode:
authorWayne Davison <wayned@samba.org>2009-04-10 16:09:39 -0700
committerWayne Davison <wayned@samba.org>2009-04-10 16:09:39 -0700
commitea53d161be54a474088df51063df128ff5da5af4 (patch)
treea9b49475719b70b107c4e483f2a59ada57454523 /acls.c
parent7875e6fe63805a3412cb4a8673a2dbf233631110 (diff)
downloadrsync-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.c38
1 files changed, 37 insertions, 1 deletions
diff --git a/acls.c b/acls.c
index 434bc61d..e2bdc4c9 100644
--- a/acls.c
+++ b/acls.c
@@ -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)
{