--- embedaddon/rsync/acls.c 2016/11/01 09:54:32 1.1.1.3 +++ embedaddon/rsync/acls.c 2021/03/17 00:32:36 1.1.1.4 @@ -3,7 +3,7 @@ * * Copyright (C) 1996 Andrew Tridgell * Copyright (C) 1996 Paul Mackerras - * Copyright (C) 2006-2015 Wayne Davison + * Copyright (C) 2006-2020 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 @@ -48,7 +48,7 @@ extern int preserve_specials; /* When we send the access bits over the wire, we shift them 2 bits to the * left and use the lower 2 bits as flags (relevant only to a name entry). * This makes the protocol more efficient than sending a value that would - * be likely to have its hightest bits set. */ + * be likely to have its highest bits set. */ #define XFLAG_NAME_FOLLOWS 0x0001u #define XFLAG_NAME_IS_USER 0x0002u @@ -78,35 +78,20 @@ typedef struct rsync_acl { uchar other_obj; } rsync_acl; -typedef struct nfs4_acl { - char *nfs4_acl_text; - ssize_t nfs4_acl_len; -} nfs4_acl; - typedef struct { rsync_acl racl; SMB_ACL_T sacl; } acl_duo; -typedef struct { - nfs4_acl nacl; - SMB_ACL_T sacl; -} nfs4_duo; - static const rsync_acl empty_rsync_acl = { {NULL, 0}, NO_ENTRY, NO_ENTRY, NO_ENTRY, NO_ENTRY }; -static const nfs4_acl empty_nfs4_acl = { - NULL, -1 -}; static item_list access_acl_list = EMPTY_ITEM_LIST; static item_list default_acl_list = EMPTY_ITEM_LIST; -static item_list nfs4_acl_list = EMPTY_ITEM_LIST; static size_t prior_access_count = (size_t)-1; static size_t prior_default_count = (size_t)-1; -static size_t prior_nfs4_count = (size_t)-1; /* === Calculations on ACL types === */ @@ -183,24 +168,11 @@ static rsync_acl *create_racl(void) { rsync_acl *racl = new(rsync_acl); - if (!racl) - out_of_memory("create_racl"); *racl = empty_rsync_acl; return racl; } -static nfs4_acl *create_nfs4_acl(void) -{ - nfs4_acl *nacl = new(nfs4_acl); - - if (!nacl) - out_of_memory("create_nfs4_acl"); - *nacl = empty_nfs4_acl; - - return nacl; -} - static BOOL ida_entries_equal(const ida_entries *ial1, const ida_entries *ial2) { id_access *ida1, *ida2; @@ -225,11 +197,6 @@ static BOOL rsync_acl_equal(const rsync_acl *racl1, co && ida_entries_equal(&racl1->names, &racl2->names); } -static BOOL nfs4_acl_equal(const nfs4_acl *nacl1, const nfs4_acl *nacl2) -{ - return (strcmp(nacl1->nfs4_acl_text, nacl2->nfs4_acl_text) == 0); -} - /* Are the extended (non-permission-bit) entries equal? If so, the rest of * the ACL will be handled by the normal mode-preservation code. This is * only meaningful for access ACLs! Note: the 1st arg is a fully-populated @@ -263,13 +230,6 @@ static void rsync_acl_free(rsync_acl *racl) *racl = empty_rsync_acl; } -static void nfs4_acl_free(nfs4_acl *nacl) -{ - if (nacl->nfs4_acl_text) - free(nacl->nfs4_acl_text); - *nacl = empty_nfs4_acl; -} - void free_acl(stat_x *sxp) { if (sxp->acc_acl) { @@ -282,11 +242,6 @@ void free_acl(stat_x *sxp) free(sxp->def_acl); sxp->def_acl = NULL; } - if (sxp->nfs4_acl) { - nfs4_acl_free(sxp->nfs4_acl); - free(sxp->nfs4_acl); - sxp->nfs4_acl = NULL; - } } #ifdef SMB_ACL_NEED_SORT @@ -375,14 +330,11 @@ static BOOL unpack_smb_acl(SMB_ACL_T sacl, rsync_acl * 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); + 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)); + racl->names.idas = new_array(id_access, temp_ida_list.count); + memcpy(racl->names.idas, temp_ida_list.items, temp_ida_list.count * sizeof (id_access)); } else racl->names.idas = NULL; @@ -517,26 +469,6 @@ static int find_matching_rsync_acl(const rsync_acl *ra return *match; } -static int find_matching_nfs4_acl(const nfs4_acl *nacl, const item_list *nfs4_acl_list) -{ - static int nfs4_match = -1; - int *match = &nfs4_match; - size_t count = nfs4_acl_list->count; - - if (*match == -1) - *match = nfs4_acl_list->count - 1; - while (count--) { - nfs4_acl *base = nfs4_acl_list->items; - if (nfs4_acl_equal(base + *match, nacl)) - return *match; - if (!(*match)--) - *match = nfs4_acl_list->count - 1; - } - - *match = -1; - return *match; -} - static int get_rsync_acl(const char *fname, rsync_acl *racl, SMB_ACL_TYPE_T type, mode_t mode) { @@ -570,9 +502,7 @@ static int get_rsync_acl(const char *fname, rsync_acl if (cnt) { char *bp = buf + 4*4; - id_access *ida; - if (!(ida = racl->names.idas = new_array(id_access, cnt))) - out_of_memory("get_rsync_acl"); + id_access *ida = racl->names.idas = new_array(id_access, cnt); racl->names.count = cnt; for ( ; cnt--; ida++, bp += 4+4) { ida->id = IVAL(bp, 0); @@ -607,21 +537,6 @@ static int get_rsync_acl(const char *fname, rsync_acl /* Return the Access Control List for the given filename. */ int get_acl(const char *fname, stat_x *sxp) { - if (sys_acl_get_brand_file(fname, &sxp->brand) < 0) - return -1; - - if (sxp->brand == SMB_ACL_BRAND_NFS4) { - SMB_ACL_T sacl; - if ((sacl = sys_acl_get_file(fname, SMB_ACL_TYPE_NFS4)) == NULL) - return -1; - - sxp->nfs4_acl = create_nfs4_acl(); - sxp->nfs4_acl->nfs4_acl_text = acl_to_text(sacl, &sxp->nfs4_acl->nfs4_acl_len); - - sys_acl_free_acl(sacl); - return 0; - } - sxp->acc_acl = create_racl(); if (S_ISREG(sxp->st.st_mode) || S_ISDIR(sxp->st.st_mode)) { @@ -730,25 +645,6 @@ static void send_rsync_acl(int f, rsync_acl *racl, SMB } } -static void send_nfs4_acl(int f, nfs4_acl *nacl, item_list *nfs4_list) -{ - int ndx = find_matching_nfs4_acl(nacl, nfs4_list); - - /* Send 0 (-1 + 1) to indicate that literal ACL data follows. */ - write_varint(f, ndx + 1); - - if (ndx < 0) { - nfs4_acl *new_nacl = EXPAND_ITEM_LIST(&nfs4_acl_list, nfs4_acl, 1000); - - write_varint(f, nacl->nfs4_acl_len); - write_buf(f, nacl->nfs4_acl_text, nacl->nfs4_acl_len); - - *new_nacl = *nacl; - *nacl = empty_nfs4_acl; - } -} - - /* Send the ACL from the stat_x structure down the indicated file descriptor. * This also frees the ACL data. */ void send_acl(int f, stat_x *sxp) @@ -760,14 +656,12 @@ void send_acl(int f, stat_x *sxp) /* Avoid sending values that can be inferred from other data. */ rsync_acl_strip_perms(sxp); - write_varint(f, SMB_ACL_TYPE_ACCESS); send_rsync_acl(f, sxp->acc_acl, SMB_ACL_TYPE_ACCESS, &access_acl_list); if (S_ISDIR(sxp->st.st_mode)) { if (!sxp->def_acl) sxp->def_acl = create_racl(); - write_varint(f, SMB_ACL_TYPE_DEFAULT); send_rsync_acl(f, sxp->def_acl, SMB_ACL_TYPE_DEFAULT, &default_acl_list); } } @@ -804,12 +698,7 @@ static uchar recv_ida_entries(int f, ida_entries *ent) uchar computed_mask_bits = 0; int i, count = read_varint(f); - if (count) { - if (!(ent->idas = new_array(id_access, count))) - out_of_memory("recv_ida_entries"); - } else - ent->idas = NULL; - + ent->idas = count ? new_array(id_access, count) : NULL; ent->count = count; for (i = 0; i < count; i++) { @@ -917,48 +806,19 @@ static int cache_rsync_acl(rsync_acl *racl, SMB_ACL_TY return ndx; } -static int cache_nfs4_acl(nfs4_acl *nacl, item_list *nfs4_list) -{ - int ndx; - - if (!nacl) - ndx = -1; - else if ((ndx = find_matching_nfs4_acl(nacl, nfs4_list)) == -1) { - nfs4_duo *new_duo; - ndx = nfs4_list->count; - new_duo = EXPAND_ITEM_LIST(nfs4_list, nfs4_duo, 1000); - new_duo->nacl = *nacl; - new_duo->sacl = NULL; - *nacl = empty_nfs4_acl; - } - - return ndx; -} - - /* Turn the ACL data in stat_x into cached ACL data, setting the index * values in the file struct. */ void cache_tmp_acl(struct file_struct *file, stat_x *sxp) { - if (sxp->brand == SMB_ACL_BRAND_NFS4) { - if (prior_nfs4_count == (size_t)-1) - prior_nfs4_count = nfs4_acl_list.count; - - F_ACL(file) = cache_nfs4_acl(sxp->nfs4_acl, &nfs4_acl_list); - return; - } - 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); + 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); + F_DIR_DEFACL(file) = cache_rsync_acl(sxp->def_acl, SMB_ACL_TYPE_DEFAULT, &default_acl_list); } } @@ -977,21 +837,6 @@ static void uncache_duo_acls(item_list *duo_list, size } } -static void uncache_nfs4_acls(item_list *nfs4_list, size_t start) -{ - nfs4_duo *nfs4_item = nfs4_list->items; - nfs4_duo *nfs4_start = nfs4_item + start; - - nfs4_item += nfs4_list->count; - nfs4_list->count = start; - - while (nfs4_item-- > nfs4_start) { - nfs4_acl_free(&nfs4_item->nacl); - if (nfs4_item->sacl) - sys_acl_free_acl(nfs4_item->sacl); - } -} - void uncache_tmp_acls(void) { if (prior_access_count != (size_t)-1) { @@ -1003,10 +848,6 @@ void uncache_tmp_acls(void) uncache_duo_acls(&default_acl_list, prior_default_count); prior_default_count = (size_t)-1; } - if (prior_nfs4_count != (size_t)-1) { - uncache_nfs4_acls(&nfs4_acl_list, prior_nfs4_count); - prior_nfs4_count = (size_t)-1; - } } #ifndef HAVE_OSX_ACLS @@ -1141,8 +982,7 @@ static int set_rsync_acl(const char *fname, acl_duo *d mode = 0; /* eliminate compiler warning */ #else if (type == SMB_ACL_TYPE_ACCESS) { - cur_mode = change_sacl_perms(duo_item->sacl, &duo_item->racl, - cur_mode, mode); + cur_mode = change_sacl_perms(duo_item->sacl, &duo_item->racl, cur_mode, mode); if (cur_mode == (mode_t)-1) return 0; } @@ -1159,7 +999,6 @@ static int set_rsync_acl(const char *fname, acl_duo *d return 0; } - /* Given a fname, this sets extended access ACL entries, the default ACL (for a * dir), and the regular mode bits on the file. Call this with fname set to * NULL to just check if the ACL is different. @@ -1179,32 +1018,6 @@ int set_acl(const char *fname, const struct file_struc return -1; } - if (sxp->brand == SMB_ACL_BRAND_NFS4) { - ndx = F_ACL(file); - if (ndx >= 0 && (size_t)ndx < nfs4_acl_list.count) { - nfs4_duo *duo_item = nfs4_acl_list.items; - duo_item += ndx; - changed = 1; - - if (!duo_item->sacl) { - duo_item->sacl = acl_from_text(duo_item->nacl.nfs4_acl_text); - if (!duo_item->sacl) - return -1; - } - - if (!dry_run && fname) { - if (sys_acl_set_file(fname, SMB_ACL_TYPE_NFS4, duo_item->sacl) < 0) { - rsyserr(FERROR_XFER, errno, "set_acl: sys_acl_set_file(%s, %s)", - fname, str_acl_type(SMB_ACL_TYPE_NFS4)); - return -1; - } - - return changed; - } - } - } - - ndx = F_ACL(file); if (ndx >= 0 && (size_t)ndx < access_acl_list.count) { acl_duo *duo_item = access_acl_list.items; @@ -1289,14 +1102,12 @@ int default_perms_for_dir(const char *dir) case ENOSYS: /* No ACLs are available. */ break; - case ENOENT: - if (dry_run) { + default: + if (dry_run && errno == ENOENT) { /* We're doing a dry run, so the containing directory * wasn't actually created. Don't worry about it. */ break; } - /* Otherwise fall through. */ - default: rprintf(FWARNING, "default_perms_for_dir: sys_acl_get_file(%s, %s): %s, falling back on umask\n", dir, str_acl_type(SMB_ACL_TYPE_DEFAULT), strerror(errno));