mirror of
https://github.com/RsyncProject/rsync.git
synced 2026-05-18 03:45:25 -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:
3
NEWS
3
NEWS
@@ -34,6 +34,9 @@ Changes since 3.0.5:
|
||||
|
||||
- Fixed the dropping of an ACL mask when no named ACL values were present.
|
||||
|
||||
- Fixed an ACL/xattr corruption issue where the --backup option could cause
|
||||
rsync to associate the wrong ACL/xattr information with received files.
|
||||
|
||||
- Fixed the use of --dry-run with --read-batch.
|
||||
|
||||
- Fixed configure's erroneous use of target.
|
||||
|
||||
38
acls.c
38
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)
|
||||
{
|
||||
|
||||
32
backup.c
32
backup.c
@@ -148,19 +148,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 = '/';
|
||||
@@ -223,20 +229,26 @@ static int keep_backup(const char *fname)
|
||||
|
||||
if (!(buf = get_backup_name(fname))) {
|
||||
unmake_file(file);
|
||||
#ifdef SUPPORT_ACLS
|
||||
uncache_tmp_acls();
|
||||
#endif
|
||||
#ifdef SUPPORT_XATTRS
|
||||
uncache_tmp_xattrs();
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
#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
|
||||
@@ -326,6 +338,12 @@ static int keep_backup(const char *fname)
|
||||
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 1;
|
||||
}
|
||||
|
||||
@@ -344,6 +362,12 @@ static int keep_backup(const char *fname)
|
||||
set_file_attrs(buf, file, NULL, fname, 0);
|
||||
preserve_xattrs = save_preserve_xattrs;
|
||||
unmake_file(file);
|
||||
#ifdef SUPPORT_ACLS
|
||||
uncache_tmp_acls();
|
||||
#endif
|
||||
#ifdef SUPPORT_XATTRS
|
||||
uncache_tmp_xattrs();
|
||||
#endif
|
||||
|
||||
if (verbose > 1) {
|
||||
rprintf(FINFO, "backed up %s to %s\n",
|
||||
|
||||
21
xattrs.c
21
xattrs.c
@@ -81,6 +81,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)
|
||||
@@ -724,13 +726,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 */
|
||||
@@ -738,6 +742,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