diff --git a/libisofs/aaip_0_2.c b/libisofs/aaip_0_2.c index dcd2aea..f2ad726 100644 --- a/libisofs/aaip_0_2.c +++ b/libisofs/aaip_0_2.c @@ -559,6 +559,8 @@ ex:; "other::" -> S_IRWXO) bit3= update acl_text by *st_mode (same mapping as bit 2 but with reversed transfer direction) + bit4= map "group::" <-> S_IRWXG in any case. + I.e. ignore "mask::". @return <0 failure >=0 tells in its bits which tag types were found. The first three tell which types deviate from the @@ -620,7 +622,7 @@ int aaip_cleanout_st_mode(char *acl_text, mode_t *in_st_mode, int flag) tag_types|= 64 | 128; } } else if(strncmp(rpt, "group:", 6) == 0) { - if(rpt[6] == ':' && npt - rpt == 10 && !has_mask) { + if(rpt[6] == ':' && npt - rpt == 10 && ((flag & 16) || !has_mask)) { /* oddly: mask overrides group in st_mode */ cpt= rpt + 7; m= 0; @@ -672,22 +674,24 @@ others_st_mode:; cpt= rpt + 7; goto others_st_mode; } else if(strncmp(rpt, "mask::", 6) == 0 && npt - rpt == 9) { - /* oddly: mask overrides group in st_mode */ cpt= rpt + 6; mask_st_mode:; - m= 0; - if(cpt[0] == 'r') - m|= S_IRGRP; - if(cpt[1] == 'w') - m|= S_IWGRP; - if(cpt[2] == 'x') - m|= S_IXGRP; - list_mode= (list_mode & ~S_IRWXG) | m; tag_types|= 64 | 512; - if(flag & 8) { - cpt[0]= st_mode & S_IRGRP ? 'r' : '-'; - cpt[1]= st_mode & S_IWGRP ? 'w' : '-'; - cpt[2]= st_mode & S_IXGRP ? 'x' : '-'; + if(!(flag & 16)) { + /* oddly: mask overrides group in st_mode */ + m= 0; + if(cpt[0] == 'r') + m|= S_IRGRP; + if(cpt[1] == 'w') + m|= S_IWGRP; + if(cpt[2] == 'x') + m|= S_IXGRP; + list_mode= (list_mode & ~S_IRWXG) | m; + if(flag & 8) { + cpt[0]= st_mode & S_IRGRP ? 'r' : '-'; + cpt[1]= st_mode & S_IWGRP ? 'w' : '-'; + cpt[2]= st_mode & S_IXGRP ? 'x' : '-'; + } } } else if(strncmp(rpt, "mask:", 5) == 0 && npt - rpt == 8) { cpt= rpt + 5; diff --git a/libisofs/aaip_0_2.h b/libisofs/aaip_0_2.h index 378150b..452ff51 100644 --- a/libisofs/aaip_0_2.h +++ b/libisofs/aaip_0_2.h @@ -89,7 +89,7 @@ int aaip_encode_both_acl(char *a_acl_text, char *d_acl_text, mode_t st_mode, or "other:" from an ACL in long text form if they match the bits in st_mode as described by man 2 stat and man 5 acl. @param acl_text The text to be analyzed and eventually shortened. - @param st_mode The component of struct stat which tells POSIX permission + @param st_mode The component of struct stat which tells permission bits and eventually shall take equivalent bits as read from the ACL. The caller should submit a pointer to the st_mode variable which holds permissions as @@ -102,6 +102,8 @@ int aaip_encode_both_acl(char *a_acl_text, char *d_acl_text, mode_t st_mode, "other::" -> S_IRWXO) bit3= update acl_text by *st_mode (same mapping as bit 2 but with reversed transfer direction) + bit4= map "group::" <-> S_IRWXG in any case. + I.e. ignore "mask::". @return <0 failure >=0 tells in its bits which tag types were found. The first three tell which types deviate from the diff --git a/libisofs/libisofs.h b/libisofs/libisofs.h index 2e46cc1..07b3192 100644 --- a/libisofs/libisofs.h +++ b/libisofs/libisofs.h @@ -4346,6 +4346,22 @@ int iso_node_get_acl_text(IsoNode *node, int iso_node_set_acl_text(IsoNode *node, char *access_text, char *default_text, int flag); +/* ts A90206 */ +/** + * Like iso_node_get_permissions but reflecting ACL entry "group::" in S_IRWXG + * rather than ACL entry "mask::". This is necessary if the permissions of a + * node with ACL shall be restored to a filesystem without restoring the ACL. + * If the node has no ACL then the result is iso_node_get_permissions(node). + * @param node + * The node that is to be inquired. + * @return + * Permission bits as of stat(2) + * + * @since 0.6.14 + */ +mode_t iso_node_get_perms_wo_acl(const IsoNode *node); + + /* ts A90131 */ /** * Get the list of XFS-style Extended Attributes xattr which is associated diff --git a/libisofs/node.c b/libisofs/node.c index 724c5a5..c23c7c8 100644 --- a/libisofs/node.c +++ b/libisofs/node.c @@ -318,6 +318,7 @@ void iso_node_set_permissions(IsoNode *node, mode_t mode) iso_node_set_perms_internal(node, mode, 0); } + /** * Get the permissions for the node */ @@ -1875,13 +1876,26 @@ int iso_node_set_acl_text(IsoNode *node, char *access_text, char *default_text, goto ex; } - /* replace variable value */; - if (values[i] != NULL) - free(values[i]); - if(acl == NULL) { /* delete whole ACL attribute */ - - /* >>> update S_IRWXG by eventual group:: ACL entry */; + if(acl == NULL) { /* Delete whole ACL attribute */ + /* Update S_IRWXG by eventual "group::" ACL entry. + With ACL it reflected the "mask::" entry. + */ + if (a_text != NULL) + free(a_text); + ret = iso_decode_acl(v_data, v_len, &consumed, + &a_text, &a_text_fill, 0); + if (ret == 0) + goto bad_decode; + if (ret < 0) + goto ex; + ret = aaip_cleanout_st_mode(a_text, &st_mode, 4 | 16); + if (ret < 0) + goto ex; + iso_node_set_perms_internal(node, st_mode, 1); + /* Delete the attribute pair */ + if (values[i] != NULL) + free(values[i]); for (j = i + 1; j < num_attrs; j++) { names[j - 1] = names[j]; value_lengths[j - 1] = value_lengths[j]; @@ -1889,6 +1903,9 @@ int iso_node_set_acl_text(IsoNode *node, char *access_text, char *default_text, } num_attrs--; } else { + /* replace variable value */; + if (values[i] != NULL) + free(values[i]); values[i] = (char *) acl; acl = NULL; value_lengths[i] = acl_len; @@ -2071,3 +2088,32 @@ int iso_local_set_attrs(char *disk_path, size_t num_attrs, char **names, } +/* ts A90206 */ +mode_t iso_node_get_perms_wo_acl(const IsoNode *node) +{ + +#ifdef Libisofs_with_aaiP + + mode_t st_mode; + int ret; + char *a_text = NULL, *d_text = NULL; + + st_mode = iso_node_get_permissions(node); + + ret = iso_node_get_acl_text((IsoNode *) node, &a_text, &d_text, 16); + if (ret != 1) + goto ex; + ret = aaip_cleanout_st_mode(a_text, &st_mode, 4 | 16); +ex:; + iso_node_get_acl_text((IsoNode *) node, &a_text, &d_text, 1 << 15); + return st_mode; + +#else /* Libisofs_with_aaiP */ + + return iso_node_get_permissions(node); + +#endif /* ! Libisofs_with_aaiP */ + +} + +