From 40ff07a5a0ce6c3bdff8a86d4161bfd1ca25f651 Mon Sep 17 00:00:00 2001 From: Eli Zaretskii Date: Sun, 23 Dec 2012 19:16:33 +0200 Subject: [PATCH] Don't fail in acl_set_file on MS-Windows if the operation is a no-op. src/w32.c (acl_set_file): If setting the file security descriptor fails, and the new DACL is identical to the existing one, silently return success. This fixes problems for users backing up their own files without having the necessary privileges for setting security descriptors. --- src/ChangeLog | 6 ++++++ src/w32.c | 27 +++++++++++++++++++++++++-- 2 files changed, 31 insertions(+), 2 deletions(-) diff --git a/src/ChangeLog b/src/ChangeLog index c7502104ddf..648f14a61e4 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,5 +1,11 @@ 2012-12-23 Eli Zaretskii + * w32.c (acl_set_file): If setting the file security descriptor + fails, and the new DACL is identical to the existing one, silently + return success. This fixes problems for users backing up their + own files without having the necessary privileges for setting + security descriptors. + * w32proc.c (reader_thread): Do not index fd_info[] with negative values. (reader_thread): Exit when cp->status becomes STATUS_READ_ERROR diff --git a/src/w32.c b/src/w32.c index 47b950668b0..9ebc97088d0 100644 --- a/src/w32.c +++ b/src/w32.c @@ -4876,8 +4876,31 @@ acl_set_file (const char *fname, acl_type_t type, acl_t acl) retval = 0; errno = e; } - else if (err == ERROR_INVALID_OWNER) - errno = EPERM; + else if (err == ERROR_INVALID_OWNER || err == ERROR_NOT_ALL_ASSIGNED) + { + /* Maybe the requested ACL and the one the file already has are + identical, in which case we can silently ignore the + failure. (And no, Windows doesn't.) */ + acl_t current_acl = acl_get_file (fname, ACL_TYPE_ACCESS); + + errno = EPERM; + if (current_acl) + { + char *acl_from = acl_to_text (current_acl, NULL); + char *acl_to = acl_to_text (acl, NULL); + + if (acl_from && acl_to && xstrcasecmp (acl_from, acl_to) == 0) + { + retval = 0; + errno = e; + } + if (acl_from) + acl_free (acl_from); + if (acl_to) + acl_free (acl_to); + acl_free (current_acl); + } + } else if (err == ERROR_FILE_NOT_FOUND || err == ERROR_PATH_NOT_FOUND) errno = ENOENT; -- 2.39.2