From 6ba324e1b7bf3726e5aa4688fb216b6f4367c26d Mon Sep 17 00:00:00 2001 From: Marco van Wieringen Date: Mon, 9 Jan 2012 14:35:17 +0100 Subject: [PATCH] Fix bug #1815 Only acl pointer can be NULL in call to aclx_get with GET_ACLINFO_ONLY set not the mode pointer. Implemented alternative version of nfsv4 acl is trivial function borrowed from gnulib. For restores we check the destination filesystem if it supports the type of acl being restored against the list of available acl types returned by aclx_gettypes. --- bacula/src/filed/acl.c | 87 ++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 84 insertions(+), 3 deletions(-) diff --git a/bacula/src/filed/acl.c b/bacula/src/filed/acl.c index cf0f442ceb..64bd5a498b 100644 --- a/bacula/src/filed/acl.c +++ b/bacula/src/filed/acl.c @@ -152,7 +152,31 @@ static bool acl_is_trivial(struct acl *acl) static bool acl_nfs4_is_trivial(nfs4_acl_int_t *acl) { +#if 0 return (acl->aclEntryN > 0 ? false : true); +#else + int i; + int count = acl->aclEntryN; + nfs4_ace_int_t *ace; + + for (i = 0; i < count; i++) { + ace = &acl->aclEntry[i]; + if (!((ace->flags & ACE4_ID_SPECIAL) != 0 && + (ace->aceWho.special_whoid == ACE4_WHO_OWNER || + ace->aceWho.special_whoid == ACE4_WHO_GROUP || + ace->aceWho.special_whoid == ACE4_WHO_EVERYONE) && + ace->aceType == ACE4_ACCESS_ALLOWED_ACE_TYPE && + ace->aceFlags == 0 && + (ace->aceMask & ~(ACE4_READ_DATA | + ACE4_LIST_DIRECTORY | + ACE4_WRITE_DATA | + ACE4_ADD_FILE | + ACE4_EXECUTE)) == 0)) { + return false; + } + } + return true; +#endif } /* @@ -179,12 +203,23 @@ static bacl_exit_code aix_build_acl_streams(JCR *jcr, FF_PKT *ff_pkt) /* * First see how big the buffers should be. */ + memset(&type, 0, sizeof(acl_type_t)); type.u64 = ACL_ANY; - if (aclx_get(jcr->last_fname, GET_ACLINFO_ONLY, &type, NULL, &aclsize, NULL) < 0) { + if (aclx_get(jcr->last_fname, GET_ACLINFO_ONLY, &type, NULL, &aclsize, &mode) < 0) { switch (errno) { case ENOENT: retval = bacl_exit_ok; goto bail_out; + case ENOSYS: + /* + * If the filesystem reports it doesn't support ACLs we clear the + * BACL_FLAG_SAVE_NATIVE flag so we skip ACL saves on all other files + * on the same filesystem. The BACL_FLAG_SAVE_NATIVE flag gets set again + * when we change from one filesystem to an other. + */ + jcr->acl_data->flags &= ~BACL_FLAG_SAVE_NATIVE; + retval = bacl_exit_ok; + goto bail_out; default: Mmsg2(jcr->errmsg, _("aclx_get error on file \"%s\": ERR=%s\n"), @@ -291,6 +326,32 @@ bail_out: return retval; } +/* + * See if a specific type of ACLs are supported on the filesystem + * the file is located on. + */ +static inline bool aix_query_acl_support(JCR *jcr, + uint64_t aclType, + acl_type_t *pacl_type_info) +{ + unsigned int i; + acl_types_list_t acl_type_list; + size_t acl_type_list_len = sizeof(acl_types_list_t); + + memset(&acl_type_list, 0, sizeof(acl_type_list)); + if (aclx_gettypes(jcr->last_fname, &acl_type_list, &acl_type_list_len)) { + return false; + } + + for (i = 0; i < acl_type_list.num_entries; i++) { + if (acl_type_list.entries[i].u64 == aclType) { + memcpy(pacl_type_info, acl_type_list.entries + i, sizeof(acl_type_t)); + return true; + } + } + return false; +} + static bacl_exit_code aix_parse_acl_streams(JCR *jcr, int stream, char *content, @@ -315,10 +376,20 @@ static bacl_exit_code aix_parse_acl_streams(JCR *jcr, retval = bacl_exit_ok; goto bail_out; case STREAM_ACL_AIX_AIXC: - type.u64 = ACL_AIXC; + if (!aix_query_acl_support(jcr, ACL_AIXC, &type)) { + Mmsg1(jcr->errmsg, + _("Trying to restore POSIX acl on file \"%s\" on filesystem without AIXC acl support\n"), + jcr->last_fname); + goto bail_out; + } break; case STREAM_ACL_AIX_NFS4: - type.u64 = ACL_NFS4; + if (!aix_query_acl_support(jcr, ACL_NFS4, &type)) { + Mmsg1(jcr->errmsg, + _("Trying to restore NFSv4 acl on file \"%s\" on filesystem without NFS4 acl support\n"), + jcr->last_fname); + goto bail_out; + } break; default: goto bail_out; @@ -381,6 +452,16 @@ static bacl_exit_code aix_parse_acl_streams(JCR *jcr, case ENOENT: retval = bacl_exit_ok; goto bail_out; + case ENOSYS: + /* + * If the filesystem reports it doesn't support ACLs we clear the + * BACL_FLAG_RESTORE_NATIVE flag so we skip ACL restores on all other files + * on the same filesystem. The BACL_FLAG_RESTORE_NATIVE flag gets set again + * when we change from one filesystem to an other. + */ + jcr->acl_data->flags &= ~BACL_FLAG_RESTORE_NATIVE; + retval = bacl_exit_ok; + goto bail_out; default: Mmsg2(jcr->errmsg, _("aclx_put error on file \"%s\": ERR=%s\n"), -- 2.39.5