vfs_nfs4acl_xattr: add support for NFS 4.1 ACL flags in the NDR backend
authorRalph Boehme <slow@samba.org>
Thu, 19 Oct 2017 13:40:52 +0000 (15:40 +0200)
committerJeremy Allison <jra@samba.org>
Tue, 7 Nov 2017 23:20:08 +0000 (00:20 +0100)
Signed-off-by: Ralph Boehme <slow@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>
source3/modules/nfs4acl_xattr_ndr.c
source3/modules/vfs_nfs4acl_xattr.c

index af100184c5f26ee53f51344251dfd3c5dc87f2db..ffa3e69cbb50cda6277520a6c890080bc6ce91b2 100644 (file)
@@ -73,6 +73,23 @@ static DATA_BLOB nfs4acl_acl2blob(TALLOC_CTX *mem_ctx, struct nfs4acl *acl)
        return blob;
 }
 
+static uint16_t nfs4acl_to_smb4acl_flags(uint8_t nfs4acl_flags)
+{
+       uint16_t smb4acl_flags = SEC_DESC_SELF_RELATIVE;
+
+       if (nfs4acl_flags & ACL4_AUTO_INHERIT) {
+               smb4acl_flags |= SEC_DESC_DACL_AUTO_INHERITED;
+       }
+       if (nfs4acl_flags & ACL4_PROTECTED) {
+               smb4acl_flags |= SEC_DESC_DACL_PROTECTED;
+       }
+       if (nfs4acl_flags & ACL4_DEFAULTED) {
+               smb4acl_flags |= SEC_DESC_DACL_DEFAULTED;
+       }
+
+       return smb4acl_flags;
+}
+
 NTSTATUS nfs4acl_ndr_blob_to_smb4(struct vfs_handle_struct *handle,
                                  TALLOC_CTX *mem_ctx,
                                  DATA_BLOB *blob,
@@ -100,6 +117,15 @@ NTSTATUS nfs4acl_ndr_blob_to_smb4(struct vfs_handle_struct *handle,
                return NT_STATUS_NO_MEMORY;
        }
 
+       if (config->nfs_version > ACL4_XATTR_VERSION_40 &&
+           nfs4acl->a_version > ACL4_XATTR_VERSION_40)
+       {
+               uint16_t smb4acl_flags;
+
+               smb4acl_flags = nfs4acl_to_smb4acl_flags(nfs4acl->a_flags);
+               smbacl4_set_controlflags(smb4acl, smb4acl_flags);
+       }
+
        for (i = 0; i < nfs4acl->a_count; i++) {
                SMB_ACE4PROP_T aceprop;
 
@@ -135,16 +161,39 @@ NTSTATUS nfs4acl_ndr_blob_to_smb4(struct vfs_handle_struct *handle,
        return NT_STATUS_OK;
 }
 
-static bool nfs4acl_smb4acl2nfs4acl(TALLOC_CTX *mem_ctx,
+static uint8_t smb4acl_to_nfs4acl_flags(uint16_t smb4acl_flags)
+{
+       uint8_t flags = 0;
+
+       if (smb4acl_flags & SEC_DESC_DACL_AUTO_INHERITED) {
+               flags |= ACL4_AUTO_INHERIT;
+       }
+       if (smb4acl_flags & SEC_DESC_DACL_PROTECTED) {
+               flags |= ACL4_PROTECTED;
+       }
+       if (smb4acl_flags & SEC_DESC_DACL_DEFAULTED) {
+               flags |= ACL4_DEFAULTED;
+       }
+
+       return flags;
+}
+
+static bool nfs4acl_smb4acl2nfs4acl(vfs_handle_struct *handle,
+                                   TALLOC_CTX *mem_ctx,
                                    struct SMB4ACL_T *smbacl,
                                    struct nfs4acl **_nfs4acl,
                                    bool denymissingspecial)
 {
+       struct nfs4acl_config *config = NULL;
        struct nfs4acl *nfs4acl = NULL;
        struct SMB4ACE_T *smbace = NULL;
        bool have_special_id = false;
        int i;
 
+       SMB_VFS_HANDLE_GET_DATA(handle, config,
+                               struct nfs4acl_config,
+                               return false);
+
        nfs4acl = talloc_zero(mem_ctx, struct nfs4acl);
        if (nfs4acl == NULL) {
                errno = ENOMEM;
@@ -161,6 +210,16 @@ static bool nfs4acl_smb4acl2nfs4acl(TALLOC_CTX *mem_ctx,
                return false;
        }
 
+       nfs4acl->a_version = config->nfs_version;
+       if (nfs4acl->a_version > ACL4_XATTR_VERSION_40) {
+               uint16_t smb4acl_flags;
+               uint8_t flags;
+
+               smb4acl_flags = smbacl4_get_controlflags(smbacl);
+               flags = smb4acl_to_nfs4acl_flags(smb4acl_flags);
+               nfs4acl->a_flags = flags;
+       }
+
        for (smbace = smb_first_ace4(smbacl), i = 0;
             smbace != NULL;
             smbace = smb_next_ace4(smbace), i++)
@@ -222,7 +281,7 @@ NTSTATUS nfs4acl_smb4acl_to_ndr_blob(vfs_handle_struct *handle,
                                          "nfs4acl_xattr",
                                          "denymissingspecial", false);
 
-       ok = nfs4acl_smb4acl2nfs4acl(talloc_tos(), smb4acl, &nfs4acl,
+       ok = nfs4acl_smb4acl2nfs4acl(handle, talloc_tos(), smb4acl, &nfs4acl,
                                     denymissingspecial);
        if (!ok) {
                DBG_ERR("Failed to convert smb ACL to nfs4 ACL.\n");
index b8ff28b75c04afb3d43fb60eefc4feb7a640fc64..e0266d236572747dc1f4b64fb48a2431f0587b54 100644 (file)
@@ -355,6 +355,9 @@ static int nfs4acl_connect(struct vfs_handle_struct *handle,
        case 40:
                config->nfs_version = ACL4_XATTR_VERSION_40;
                break;
+       case 41:
+               config->nfs_version = ACL4_XATTR_VERSION_41;
+               break;
        default:
                config->nfs_version = ACL4_XATTR_VERSION_DEFAULT;
                break;