mirror of
https://github.com/RsyncProject/rsync.git
synced 2026-10-23 06:14:18 -04:00
Fixed an ACL/xattr corruption issue where the --backup option could cause
rsync to associate the wrong ACL/xattr information with received files.
This commit is contained in:
1 parent
a055dbdd88
commit
cb197514d9
3 files changed
+85
-6
No files matched your search
@@ -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)
|
||||
{
|
||||
|
||||
@@ -106,19 +106,25 @@ int make_bak_dir(const char *fullpath)
|
||||
#ifdef SUPPORT_ACLS
|
||||
if (preserve_acls && !S_ISLNK(file->mode)) {
|
||||
get_acl(rel, &sx);
|
||||
cache_acl(file, &sx);
|
||||
cache_tmp_acl(file, &sx);
|
||||
free_acl(&sx);
|
||||
}
|
||||
#endif
|
||||
#ifdef SUPPORT_XATTRS
|
||||
if (preserve_xattrs) {
|
||||
get_xattr(rel, &sx);
|
||||
cache_xattr(file, &sx);
|
||||
cache_tmp_xattr(file, &sx);
|
||||
free_xattr(&sx);
|
||||
}
|
||||
#endif
|
||||
set_file_attrs(fbuf, file, NULL, NULL, 0);
|
||||
unmake_file(file);
|
||||
#ifdef SUPPORT_ACLS
|
||||
uncache_tmp_acls();
|
||||
#endif
|
||||
#ifdef SUPPORT_XATTRS
|
||||
uncache_tmp_xattrs();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
*p = '/';
|
||||
@@ -219,14 +225,14 @@ int make_backup(const char *fname, BOOL prefer_rename)
|
||||
#ifdef SUPPORT_ACLS
|
||||
if (preserve_acls && !S_ISLNK(file->mode)) {
|
||||
get_acl(fname, &sx);
|
||||
cache_acl(file, &sx);
|
||||
cache_tmp_acl(file, &sx);
|
||||
free_acl(&sx);
|
||||
}
|
||||
#endif
|
||||
#ifdef SUPPORT_XATTRS
|
||||
if (preserve_xattrs) {
|
||||
get_xattr(fname, &sx);
|
||||
cache_xattr(file, &sx);
|
||||
cache_tmp_xattr(file, &sx);
|
||||
free_xattr(&sx);
|
||||
}
|
||||
#endif
|
||||
@@ -313,6 +319,12 @@ int make_backup(const char *fname, BOOL prefer_rename)
|
||||
rprintf(FINFO, "make_bak: skipping non-regular file %s\n",
|
||||
fname);
|
||||
unmake_file(file);
|
||||
#ifdef SUPPORT_ACLS
|
||||
uncache_tmp_acls();
|
||||
#endif
|
||||
#ifdef SUPPORT_XATTRS
|
||||
uncache_tmp_xattrs();
|
||||
#endif
|
||||
return 2;
|
||||
}
|
||||
|
||||
@@ -322,6 +334,12 @@ int make_backup(const char *fname, BOOL prefer_rename)
|
||||
rsyserr(FERROR, errno, "keep_backup failed: %s -> \"%s\"",
|
||||
full_fname(fname), buf);
|
||||
unmake_file(file);
|
||||
#ifdef SUPPORT_ACLS
|
||||
uncache_tmp_acls();
|
||||
#endif
|
||||
#ifdef SUPPORT_XATTRS
|
||||
uncache_tmp_xattrs();
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
ret = 2;
|
||||
@@ -333,6 +351,12 @@ int make_backup(const char *fname, BOOL prefer_rename)
|
||||
preserve_xattrs = save_preserve_xattrs;
|
||||
|
||||
unmake_file(file);
|
||||
#ifdef SUPPORT_ACLS
|
||||
uncache_tmp_acls();
|
||||
#endif
|
||||
#ifdef SUPPORT_XATTRS
|
||||
uncache_tmp_xattrs();
|
||||
#endif
|
||||
|
||||
success:
|
||||
if (INFO_GTE(BACKUP, 1)) {
|
||||
|
||||
@@ -82,6 +82,8 @@ static char *namebuf = NULL;
|
||||
static item_list empty_xattr = EMPTY_ITEM_LIST;
|
||||
static item_list rsync_xal_l = EMPTY_ITEM_LIST;
|
||||
|
||||
static size_t prior_xattr_count = (size_t)-1;
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
static void rsync_xal_free(item_list *xalp)
|
||||
@@ -725,13 +727,15 @@ void receive_xattr(struct file_struct *file, int f)
|
||||
|
||||
/* Turn the xattr data in stat_x into cached xattr data, setting the index
|
||||
* values in the file struct. */
|
||||
void cache_xattr(struct file_struct *file, stat_x *sxp)
|
||||
void cache_tmp_xattr(struct file_struct *file, stat_x *sxp)
|
||||
{
|
||||
int ndx;
|
||||
|
||||
if (!sxp->xattr)
|
||||
return;
|
||||
|
||||
if (prior_xattr_count == (size_t)-1)
|
||||
prior_xattr_count = rsync_xal_l.count;
|
||||
ndx = find_matching_xattr(sxp->xattr);
|
||||
if (ndx < 0)
|
||||
rsync_xal_store(sxp->xattr); /* adds item to rsync_xal_l */
|
||||
@@ -739,6 +743,21 @@ void cache_xattr(struct file_struct *file, stat_x *sxp)
|
||||
F_XATTR(file) = ndx;
|
||||
}
|
||||
|
||||
void uncache_tmp_xattrs(void)
|
||||
{
|
||||
if (prior_xattr_count != (size_t)-1) {
|
||||
item_list *xattr_item = rsync_xal_l.items;
|
||||
item_list *xattr_start = xattr_item + prior_xattr_count;
|
||||
xattr_item += rsync_xal_l.count;
|
||||
rsync_xal_l.count = prior_xattr_count;
|
||||
while (xattr_item-- > xattr_start) {
|
||||
rsync_xal_free(xattr_item);
|
||||
free(xattr_item);
|
||||
}
|
||||
prior_xattr_count = (size_t)-1;
|
||||
}
|
||||
}
|
||||
|
||||
static int rsync_xal_set(const char *fname, item_list *xalp,
|
||||
const char *fnamecmp, stat_x *sxp)
|
||||
{
|
||||
|
||||
Reference in new issue
Block a user