X-Git-Url: https://mattmccutchen.net/rsync/rsync.git/blobdiff_plain/e5abce8e0dbb8a36b3112e77d508a11fde06f170..f31514adb780899d886df63edd79ac3d48363f2f:/acls.c diff --git a/acls.c b/acls.c index 36d6ba21..6f20cf3a 100644 --- a/acls.c +++ b/acls.c @@ -6,9 +6,8 @@ * Copyright (C) 2006 Wayne Davison * * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -510,7 +509,7 @@ static int get_rsync_acl(const char *fname, rsync_acl *racl, if (!ok) { return -1; } - } else if (errno == ENOTSUP || errno == ENOSYS) { + } else if (no_acl_syscall_error(errno)) { /* ACLs are not supported, so pretend we have a basic ACL. */ if (type == SMB_ACL_TYPE_ACCESS) rsync_acl_fake_perms(racl, mode); @@ -560,11 +559,11 @@ static void send_ida_entries(const ida_entries *idal, int user_names, int f) id_access *ida; size_t count = idal->count; - write_abbrevint(f, idal->count); + write_varint(f, idal->count); for (ida = idal->idas; count--; ida++) { char *name = user_names ? add_uid(ida->id) : add_gid(ida->id); - write_abbrevint(f, ida->id); + write_varint(f, ida->id); if (inc_recurse && name) { int len = strlen(name); write_byte(f, ida->access | (uchar)0x80); @@ -581,7 +580,7 @@ static void send_rsync_acl(rsync_acl *racl, SMB_ACL_TYPE_T type, int ndx = find_matching_rsync_acl(racl, type, racl_list); /* Send 0 (-1 + 1) to indicate that literal ACL data follows. */ - write_abbrevint(f, ndx + 1); + write_varint(f, ndx + 1); if (ndx < 0) { rsync_acl *new_racl = EXPAND_ITEM_LIST(racl_list, rsync_acl, 1000); @@ -673,8 +672,7 @@ static uchar recv_acl_access(uchar *name_follows_val, int f) static uchar recv_ida_entries(ida_entries *ent, int user_names, int f) { uchar computed_mask_bits = 0; - uchar has_name; - int i, count = read_abbrevint(f); + int i, count = read_varint(f); if (count) { if (!(ent->idas = new_array(id_access, ent->count))) @@ -685,7 +683,8 @@ static uchar recv_ida_entries(ida_entries *ent, int user_names, int f) ent->count = count; for (i = 0; i < count; i++) { - id_t id = read_abbrevint(f); + uchar has_name; + id_t id = read_varint(f); int access = recv_acl_access(&has_name, f); if (has_name) { @@ -714,7 +713,7 @@ static int recv_rsync_acl(item_list *racl_list, SMB_ACL_TYPE_T type, int f) uchar computed_mask_bits = 0; acl_duo *duo_item; uchar flags; - int ndx = read_abbrevint(f); + int ndx = read_varint(f); if (ndx < 0 || (size_t)ndx > racl_list->count) { rprintf(FERROR, "recv_acl_index: %s ACL index %d > %d\n", @@ -968,63 +967,30 @@ int set_acl(const char *fname, const struct file_struct *file, statx *sxp) return unchanged; } -/* === Enumeration functions for uid mapping === */ - -/* Context -- one and only one. Should be cycled through once on uid - * mapping and once on gid mapping. */ -static item_list *_enum_racl_lists[] = { - &access_acl_list, &default_acl_list, NULL -}; - -static item_list **enum_racl_list = &_enum_racl_lists[0]; -static int enum_ida_index = 0; -static size_t enum_racl_index = 0; - -/* This returns the next tag_type id from the given ACL for the next entry, - * or it returns 0 if there are no more tag_type ids in the acl. */ -static id_t *next_ace_id(SMB_ACL_TAG_T tag_type, const rsync_acl *racl) -{ - const ida_entries *idal = tag_type == SMB_ACL_USER ? &racl->users : &racl->groups; - if (enum_ida_index < idal->count) { - id_access *ida = &idal->idas[enum_ida_index++]; - return &ida->id; - } - enum_ida_index = 0; - return NULL; -} - -static id_t *next_acl_id(SMB_ACL_TAG_T tag_type, const item_list *racl_list) -{ - for (; enum_racl_index < racl_list->count; enum_racl_index++) { - id_t *id; - acl_duo *duo_item = racl_list->items; - duo_item += enum_racl_index; - if ((id = next_ace_id(tag_type, &duo_item->racl)) != NULL) - return id; - } - enum_racl_index = 0; - return NULL; -} - -static id_t *next_acl_list_id(SMB_ACL_TAG_T tag_type) +/* Non-incremental recursion needs to convert all the received IDs + * in a single pass after the file-list is complete. */ +static void match_racl_ids(const item_list *racl_list) { - for (; *enum_racl_list; enum_racl_list++) { - id_t *id = next_acl_id(tag_type, *enum_racl_list); - if (id) - return id; + int list_cnt, name_cnt; + acl_duo *duo_item = racl_list->items; + for (list_cnt = racl_list->count; list_cnt--; duo_item++) { + ida_entries *idal = &duo_item->racl.users; + for (name_cnt = idal->count; name_cnt--; idal++) { + id_access *ida = idal->idas; + ida->id = match_uid(ida->id); + } + idal = &duo_item->racl.groups; + for (name_cnt = idal->count; name_cnt--; idal++) { + id_access *ida = idal->idas; + ida->id = match_gid(ida->id); + } } - enum_racl_list = &_enum_racl_lists[0]; - return NULL; } -id_t *next_acl_uid() +void match_acl_ids(void) { - return next_acl_list_id(SMB_ACL_USER); -} - -id_t *next_acl_gid() -{ - return next_acl_list_id(SMB_ACL_GROUP); + match_racl_ids(&access_acl_list); + match_racl_ids(&default_acl_list); } /* This is used by dest_mode(). */ @@ -1043,7 +1009,9 @@ int default_perms_for_dir(const char *dir) if (sacl == NULL) { /* Couldn't get an ACL. Darn. */ switch (errno) { +#ifdef ENOTSUP case ENOTSUP: +#endif case ENOSYS: /* No ACLs are available. */ break;