X-Git-Url: https://mattmccutchen.net/rsync/rsync-patches.git/blobdiff_plain/8a38e00aeb2dc1119a0a236a8c903e942903d08b..c1ff70aa47e11c5b37634479a0facee775a7b6d9:/acls.diff diff --git a/acls.diff b/acls.diff index ca57212..ff1f178 100644 --- a/acls.diff +++ b/acls.diff @@ -9,10 +9,20 @@ To use this patch, run these commands for a successful build: ./configure (optional if already run) make ---- old/acls.c -+++ new/acls.c -@@ -89,6 +89,18 @@ static const char *str_acl_type(SMB_ACL_ - : "unknown SMB_ACL_TYPE_T"; +based-on: a01e3b490eb36ccf9e704840e1b6683dab867550 +diff --git a/acls.c b/acls.c +--- a/acls.c ++++ b/acls.c +@@ -31,6 +31,7 @@ extern int list_only; + extern int orig_umask; + extern int numeric_ids; + extern int inc_recurse; ++extern int protocol_version; + + /* Flags used to indicate what items are being transmitted for an entry. */ + #define XMIT_USER_OBJ (1<<0) +@@ -110,6 +111,18 @@ static const char *str_acl_type(SMB_ACL_TYPE_T type) + return "unknown ACL type!"; } +#define OTHER_TYPE(t) (SMB_ACL_TYPE_ACCESS+SMB_ACL_TYPE_DEFAULT-(t)) @@ -20,7 +30,7 @@ To use this patch, run these commands for a successful build: + +static int old_count_racl_entries(const rsync_acl *racl) +{ -+ return racl->users.count + racl->groups.count ++ return racl->names.count + + (racl->user_obj != NO_ENTRY) + + (racl->group_obj != NO_ENTRY) + + (racl->mask_obj != NO_ENTRY) @@ -30,7 +40,7 @@ To use this patch, run these commands for a successful build: static int calc_sacl_entries(const rsync_acl *racl) { /* A System ACL always gets user/group/other permission entries. */ -@@ -544,6 +556,91 @@ int get_acl(const char *fname, statx *sx +@@ -555,6 +568,96 @@ int get_acl(const char *fname, stat_x *sxp) return 0; } @@ -42,13 +52,18 @@ To use this patch, run these commands for a successful build: + id_access *ida; + size_t count = idal->count; + for (ida = idal->idas; count--; ida++) { ++ if (tag_char == 'U') { ++ if (!(ida->access & NAME_IS_USER)) ++ continue; ++ add_uid(ida->id); ++ } else { ++ if (ida->access & NAME_IS_USER) ++ continue; ++ add_gid(ida->id); ++ } + write_byte(f, tag_char); + write_byte(f, ida->access); + write_int(f, ida->id); -+ if (tag_char == 'U') -+ add_uid(ida->id); -+ else -+ add_gid(ida->id); + } +} + @@ -61,12 +76,12 @@ To use this patch, run these commands for a successful build: + write_byte(f, 'u'); + write_byte(f, racl->user_obj); + } -+ old_send_ida_entries(f, &racl->users, 'U'); ++ old_send_ida_entries(f, &racl->names, 'U'); + if (racl->group_obj != NO_ENTRY) { + write_byte(f, 'g'); + write_byte(f, racl->group_obj); + } -+ old_send_ida_entries(f, &racl->groups, 'G'); ++ old_send_ida_entries(f, &racl->names, 'G'); + if (racl->mask_obj != NO_ENTRY) { + write_byte(f, 'm'); + write_byte(f, racl->mask_obj); @@ -77,9 +92,9 @@ To use this patch, run these commands for a successful build: + } +} + -+/* Send the ACL from the statx structure down the indicated file descriptor. ++/* Send the ACL from the stat_x structure down the indicated file descriptor. + * This also frees the ACL data. */ -+void old_send_acl(statx *sxp, int f) ++void old_send_acl(stat_x *sxp, int f) +{ + SMB_ACL_TYPE_T type; + rsync_acl *racl, *new_racl; @@ -121,10 +136,10 @@ To use this patch, run these commands for a successful build: + /* === Send functions === */ - /* The general strategy with the tag_type <-> character mapping is that -@@ -630,6 +727,11 @@ static void send_rsync_acl(rsync_acl *ra + /* Send the ida list over the file descriptor. */ +@@ -630,6 +733,11 @@ static void send_rsync_acl(int f, rsync_acl *racl, SMB_ACL_TYPE_T type, * This also frees the ACL data. */ - void send_acl(statx *sxp, int f) + void send_acl(int f, stat_x *sxp) { + if (protocol_version < 30) { + old_send_acl(sxp, f); @@ -134,7 +149,7 @@ To use this patch, run these commands for a successful build: if (!sxp->acc_acl) { sxp->acc_acl = create_racl(); rsync_acl_fake_perms(sxp->acc_acl, sxp->st.st_mode); -@@ -647,6 +749,146 @@ void send_acl(statx *sxp, int f) +@@ -647,6 +755,160 @@ void send_acl(int f, stat_x *sxp) } } @@ -143,7 +158,7 @@ To use this patch, run these commands for a successful build: +static void old_recv_rsync_acl(rsync_acl *racl, int f) +{ + static item_list temp_ida_list = EMPTY_ITEM_LIST; -+ SMB_ACL_TAG_T tag_type = 0, prior_list_type = 0; ++ SMB_ACL_TAG_T tag_type = 0; + uchar computed_mask_bits = 0; + id_access *ida; + size_t count; @@ -199,20 +214,34 @@ To use this patch, run these commands for a successful build: + tag); + exit_cleanup(RERR_STREAMIO); + } -+ if (tag_type != prior_list_type) { -+ if (prior_list_type) -+ save_idas(racl, prior_list_type, &temp_ida_list); -+ prior_list_type = tag_type; -+ } + ida = EXPAND_ITEM_LIST(&temp_ida_list, id_access, -10); -+ ida->access = access; ++ ida->access = access | (tag_type == SMB_ACL_USER ? NAME_IS_USER : 0); + ida->id = read_int(f); + computed_mask_bits |= access; + } -+ if (prior_list_type) -+ save_idas(racl, prior_list_type, &temp_ida_list); + -+ if (!racl->users.count && !racl->groups.count) { ++ /* Transfer the count id_access items out of the temp_ida_list ++ * into the names ida_entries list in racl. */ ++ if (temp_ida_list.count) { ++#ifdef SMB_ACL_NEED_SORT ++ if (temp_ida_list.count > 1) { ++ qsort(temp_ida_list.items, temp_ida_list.count, ++ sizeof (id_access), id_access_sorter); ++ } ++#endif ++ if (!(racl->names.idas = new_array(id_access, temp_ida_list.count))) ++ out_of_memory("unpack_smb_acl"); ++ memcpy(racl->names.idas, temp_ida_list.items, ++ temp_ida_list.count * sizeof (id_access)); ++ } else ++ racl->names.idas = NULL; ++ ++ racl->names.count = temp_ida_list.count; ++ ++ /* Truncate the temporary list now that its idas have been saved. */ ++ temp_ida_list.count = 0; ++ ++ if (!racl->names.count) { + /* If we received a superfluous mask, throw it away. */ + if (racl->mask_obj != NO_ENTRY) { + /* Mask off the group perms with it first. */ @@ -220,7 +249,7 @@ To use this patch, run these commands for a successful build: + racl->mask_obj = NO_ENTRY; + } + } else if (racl->mask_obj == NO_ENTRY) /* Must be non-empty with lists. */ -+ racl->mask_obj = computed_mask_bits | (racl->group_obj & 7); ++ racl->mask_obj = (computed_mask_bits | racl->group_obj) & 7; +} + +/* Receive the ACL info the sender has included for this file-list entry. */ @@ -273,32 +302,33 @@ To use this patch, run these commands for a successful build: + if (type == SMB_ACL_TYPE_ACCESS) + F_ACL(file) = ndx; + else -+ F_DEF_ACL(file) = ndx; ++ F_DIR_DEFACL(file) = ndx; + racl_list = &default_acl_list; + } while (BUMP_TYPE(type) && S_ISDIR(file->mode)); +} + /* === Receive functions === */ - static uchar recv_acl_access(uchar *name_follows_val, int f) -@@ -766,6 +1008,11 @@ static int recv_rsync_acl(item_list *rac + static uint32 recv_acl_access(int f, uchar *name_follows_ptr) +@@ -768,6 +1030,11 @@ static int recv_rsync_acl(int f, item_list *racl_list, SMB_ACL_TYPE_T type, mode /* Receive the ACL info the sender has included for this file-list entry. */ - void receive_acl(struct file_struct *file, int f) + void receive_acl(int f, struct file_struct *file) { + if (protocol_version < 30) { + old_recv_acl(file, f); + return; + } + - F_ACL(file) = recv_rsync_acl(&access_acl_list, SMB_ACL_TYPE_ACCESS, f); + F_ACL(file) = recv_rsync_acl(f, &access_acl_list, SMB_ACL_TYPE_ACCESS, file->mode); if (S_ISDIR(file->mode)) ---- old/compat.c -+++ new/compat.c -@@ -115,13 +115,6 @@ void setup_protocol(int f_out,int f_in) - protocol_version); - exit_cleanup(RERR_PROTOCOL); - } +diff --git a/compat.c b/compat.c +--- a/compat.c ++++ b/compat.c +@@ -191,13 +191,6 @@ void setup_protocol(int f_out,int f_in) + if (protocol_version < 30) { + if (append_mode == 1) + append_mode = 2; - if (preserve_acls && !local_server) { - rprintf(FERROR, - "--acls requires protocol 30 or higher" @@ -309,16 +339,3 @@ To use this patch, run these commands for a successful build: if (preserve_xattrs && !local_server) { rprintf(FERROR, "--xattrs requires protocol 30 or higher" ---- old/testsuite/default-acls.test -+++ new/testsuite/default-acls.test -@@ -9,10 +9,6 @@ - - $RSYNC --version | grep ", ACLs" >/dev/null || test_skipped "Rsync is configured without ACL support" - --case "$RSYNC" in --*protocol=29*) test_skipped "ACLs require protocol 30" ;; --esac -- - case "$setfacl_nodef" in - true) test_skipped "I don't know how to use your setfacl command" ;; - *-k*) opts='-dm u::7,g::5,o:5' ;;