[PATCH] Fix for XDR Backend of NFS4ACL_XATTR module to get it working with NFS4.0 ACL Spec

Jeremy Allison jra at samba.org
Fri Jul 20 21:02:11 UTC 2018


On Fri, Jul 20, 2018 at 12:47:16PM +0000, Sandeep Nashikkar via samba-technical wrote:
> Hi All
> 
> While experimenting with NFS4ACL_XATTR VFS module I came across failures on windows clients in its current implementation.
> I was testing native NFS 4.0 Server export mounted locally and shared through Samba 4.8.0 server with nfs4acl_xattr module.
> Looking at XDR backend code and wireshark traces, I could see that current code is not compatible with NFS4 ACL format in RFC 7530.
> I have fixed the module with following:
> 
> *         Implemented another set of XDR structure and APIs (with nfs40acl prefix) which should work with NFS 4.0 ACL format and convert XDR blob to/from SMB ACL. Enabled by default for now.
> 
> *         Did not change any of the existing XDR Backend APIs (with nfs4acl prefix) which probably intend to support both NFS 4.0 and NFS 4.1 ACL format in future using nfs_version config option. Current APIs use iflag in the nfsace4 structure which I did not find even in NFS v4.1 Spec RFC 5661. And that was causing issues in encoding/decoding XDR blobs. So the existing code is broken for my tests and needed lot of fixes if it has to support both specs.
> 
> *         Changed XDR attribute name to "system.nfs4_acl" which works with native NFSv4 and nfs-ganesha.

Hmmm. I'm going to have to think about this some more
- this changes the read/write possibilities for the
attibute to root-only. Is this correct ?

> 
> *         All owners with Special IDs along with OWNER@, GROUP@, EVERYONE@ are encoded/decoded now.
> 
> Please find below the patch for fixing above issues.
> Kindly review the patch and please let me know if there are any suggestions/corrections.
> I am not used to submit patches to open source, so let me know if there are any lapses and I would be ready to fix it.

Thanks for this Sandeep !

Comments inline below:

> -------------- next part --------------
> From 556f44ca183d12a8a5a4211213362247361edff3 Mon Sep 17 00:00:00 2001
> From: Sandeep Nashikkar <snashikkar at commvault.com>
> Date: Fri, 20 Jul 2018 17:22:43 +0530
> Subject: [PATCH] Fix for XDR Backend of NFS4ACL_XATTR module to get it working
> with NFS4.0 ACL Spec
> 
> Signed-off-by: Sandeep Nashikkar <snashikkar at commvault.com>
> ---
> source3/modules/nfs41acl.x          |  12 +
> source3/modules/nfs4acl_xattr_xdr.c | 473 ++++++++++++++++++++++++++++
> source3/modules/nfs4acl_xattr_xdr.h |  12 +-
> source3/modules/vfs_nfs4acl_xattr.c |   6 +-
> 4 files changed, 499 insertions(+), 4 deletions(-)
> 
> diff --git a/source3/modules/nfs41acl.x b/source3/modules/nfs41acl.x
> index 9cfbd9f3074..beea0071fef 100644
> --- a/source3/modules/nfs41acl.x
> +++ b/source3/modules/nfs41acl.x
> @@ -92,3 +92,15 @@ struct nfsacl41 {
>          aclflag4        na41_flag;
>          nfsace4         na41_aces<>;
> };
> +
> +/* ACL structure definition as per RFC 7530 Section-6.2.1 */
> +struct nfsace40 {
> +        acetype4        type;
> +        aceflag4        flag;
> +        acemask4        access_mask;
> +        utf8str_mixed   who;
> +};
> +
> +struct nfsacl40 {
> +        nfsace40         na40_aces<>;
> +};
> diff --git a/source3/modules/nfs4acl_xattr_xdr.c b/source3/modules/nfs4acl_xattr_xdr.c
> index 399c104faa4..70e562f36cb 100644
> --- a/source3/modules/nfs4acl_xattr_xdr.c
> +++ b/source3/modules/nfs4acl_xattr_xdr.c
> @@ -40,6 +40,21 @@
> #include "nfs41acl.h"
> #include "nfs4acl_xattr_xdr.h"
> +static unsigned nfs40acl_get_naces(nfsacl40 *nacl40)
> +{
> +             return nacl40->na40_aces.na40_aces_len;
> +}
> +
> +static void nfs40acl_set_naces(nfsacl40 *nacl40, unsigned naces)
> +{
> +             nacl40->na40_aces.na40_aces_len = naces;
> +}
> +
> +static nfsace40 *nfs40acl_get_ace(nfsacl40 *nacl40, size_t n)
> +{
> +             return &nacl40->na40_aces.na40_aces_val[n];
> +}
> +
> static unsigned nfs4acl_get_naces(nfsacl41 *nacl)
> {
>                return nacl->na41_aces.na41_aces_len;
> @@ -60,6 +75,61 @@ static void nfs4acl_set_flags(nfsacl41 *nacl, unsigned flags)
>                nacl->na41_flag = flags;
> }
> +static size_t nfs40acl_get_xdrblob_size(nfsacl40 *nacl40)
> +{
> +             size_t acl_size;
> +             size_t aces_size;
> +             size_t identifiers_size;
> +             int i;

i should be unsigned, can never be negative.

> +
> +             unsigned naces = nfs40acl_get_naces(nacl40);
> +
> +             /* ACE Structure minus actual identifier strings */
> +             struct nfsace40_size {
> +                             acetype4 type;
> +                             aceflag4 flag;
> +                             acemask4 access_mask;
> +                             u_int who_length;
> +             };
> +
> +             /* ACL Size: Size of (ACE Count) +
> +              * ACE Count * (Size of nfsace40_size) +
> +              * Cumulative Length of Identifiers strings
> +              */
> +             acl_size = sizeof(u_int);
> +
> +             if (naces > NFS4ACL_XDR_MAX_ACES) {
> +                             DBG_ERR("Too many ACEs: %u", naces);
> +                             return 0;
> +             }
> +
> +             aces_size = naces * sizeof(struct nfsace40_size);
> +             acl_size += aces_size;
> +             DBG_DEBUG("aces_size: %ld\n", aces_size);
> +
> +             identifiers_size = 0;
> +             for (i = 0;  i < naces; i++) {
> +                             nfsace40 *nace40 = nfs40acl_get_ace(nacl40, i);
> +                             /* UTf-8 identifier strings are aligned */
> +                             if (nace40->who.utf8string_len % 4) {
> +                                             size_t id_size = nace40->who.utf8string_len;
> +                                             id_size += (4 - (nace40->who.utf8string_len % 4));
> +                                             identifiers_size += id_size;
> +                                             DBG_DEBUG("identifier[%d] size: %ld\n", i, id_size);
> +                             } else {
> +                                             identifiers_size += (nace40->who.utf8string_len);
> +                             }
> +             }

In the above, does utf8string_len come from the client ?
If so we need overflow checks on the additions of utf8string_len
to prevent security problems.

As a rule, doing overflow checks on any additions from marshalling/unmarshalling
code is a good idea anyway.

> +
> +             DBG_DEBUG("total identifiers_size: %ld\n", identifiers_size);
> +             acl_size += identifiers_size;
> +
> +             DBG_DEBUG("acl_size: %ld\n", acl_size);
> +             return acl_size;
> +}
> +
> +
> +
> static size_t nfs4acl_get_xdrblob_size(nfsacl41 *nacl)
> {
>                size_t acl_size;
> @@ -82,6 +152,12 @@ static size_t nfs4acl_get_xdrblob_size(nfsacl41 *nacl)
>                return acl_size;
> }
> +static size_t nfs40acl_get_xdrblob_naces(size_t _blobsize)
> +{
> +             /* Not required */
> +             return -1;
> +}
> +
> static size_t nfs4acl_get_xdrblob_naces(size_t _blobsize)
> {
>                size_t blobsize = _blobsize;
> @@ -94,6 +170,31 @@ static size_t nfs4acl_get_xdrblob_naces(size_t _blobsize)
>                return (blobsize / sizeof(struct nfsace4));
> }
> +static nfsacl40 *nfs40acl_alloc(TALLOC_CTX *mem_ctx, unsigned naces)
> +{
> +
> +             size_t acl_size = sizeof(nfsacl40) + (naces * sizeof(struct nfsace40));
> +             nfsacl40 *nacl40 = NULL;
> +
> +             if (naces > NFS4ACL_XDR_MAX_ACES) {
> +                             DBG_ERR("Too many ACEs: %d\n", naces);
> +                             return NULL;
> +             }
> +
> +             nacl40 = talloc_zero_size(mem_ctx, acl_size);
> +             if (nacl40 == NULL) {
> +                             DBG_ERR("talloc_zero_size failed\n");
> +                             return NULL;
> +             }
> +
> +             nfs40acl_set_naces(nacl40, naces);
> +             nacl40->na40_aces.na40_aces_val =
> +                             (nfsace40 *)((char *)nacl40 + sizeof(nfsacl40));
> +
> +             return nacl40;
> +}
> +
> +
> static nfsacl41 *nfs4acl_alloc(TALLOC_CTX *mem_ctx, unsigned naces)
> {
>                size_t acl_size = sizeof(nfsacl41) + (naces * sizeof(struct nfsace4));
> @@ -139,6 +240,151 @@ static unsigned smb4acl_to_nfs4acl_flags(uint16_t smb4acl_flags)
>                return nfs4acl_flags;
> }
> +static bool create_special_id(TALLOC_CTX *mem_ctx, nfsace40 *nace40, char *id)
> +{
> +             int len = strlen(id);
> +             nace40->who.utf8string_val = talloc_memdup(mem_ctx, id, len);
> +             nace40->who.utf8string_len = len;
> +             if (nace40->who.utf8string_val == NULL) {
> +                             DBG_ERR("Error talloc_memdup for %d bytes\n", len);
> +                             return false;
> +             }
> +             return true;
> +}
> +static bool create_numeric_id(TALLOC_CTX *mem_ctx, nfsace40 *nace40, uid_t id)
> +{
> +             int id_len = snprintf( NULL, 0, "%ld", id);
> +             char* strid = malloc(id_len + 1);

Use talloc, not malloc here.

> +             if (!strid) {
> +                             DBG_ERR("Error allocating %d bytes\n", id_len + 1);
> +                             return false;
> +             }
> +             snprintf(strid, id_len + 1, "%ld", id);
> +             nace40->who.utf8string_val = talloc_memdup (mem_ctx, strid, id_len);
> +             nace40->who.utf8string_len = id_len;
> +             free(strid);

Use talloc, not malloc here.

> +             if (nace40->who.utf8string_val == NULL) {
> +                             DBG_ERR("Error talloc_memdup for %d bytes\n", id_len);
> +                             return false;
> +             }
> +             return true;
> +}
> +
> +static bool smb4acl_to_nfs40acl(vfs_handle_struct *handle,
> +                                                    TALLOC_CTX *mem_ctx,
> +                                                    struct SMB4ACL_T *smb4acl,
> +                                                    nfsacl40 **_nacl40)
> +{
> +             struct nfs4acl_config *config = NULL;
> +             struct SMB4ACE_T *smb4ace = NULL;
> +             size_t smb4naces = 0;
> +             nfsacl40 *nacl40 = NULL;
> +             uint16_t smb4acl_flags = 0;
> +             unsigned nacl_flags = 0;
> +
> +             SMB_VFS_HANDLE_GET_DATA(handle, config,
> +                                                             struct nfs4acl_config,
> +                                                             return false);
> +
> +             smb4naces = smb_get_naces(smb4acl);
> +             nacl40 = nfs40acl_alloc(mem_ctx, smb4naces);
> +             nfs40acl_set_naces(nacl40, 0);
> +
> +             smb4ace = smb_first_ace4(smb4acl);
> +             while (smb4ace != NULL) {
> +                             SMB_ACE4PROP_T *ace4prop = smb_get_ace4(smb4ace);
> +                             size_t nace_count = nfs40acl_get_naces(nacl40);
> +                             nfsace40 *nace40 = nfs40acl_get_ace(nacl40, nace_count);
> +
> +                             nace40->type = ace4prop->aceType;
> +                             nace40->flag = ace4prop->aceFlags;
> +                             nace40->access_mask = ace4prop->aceMask;
> +
> +                             if (ace4prop->flags & SMB_ACE4_ID_SPECIAL) {
> +                                             switch (ace4prop->who.special_id) {
> +                                             case SMB_ACE4_WHO_OWNER:
> +                                                             if (!create_special_id(mem_ctx, nace40, "OWNER@")) {
> +                                                                             return false;
> +                                                             }
> +                                                             break;
> +                                             case SMB_ACE4_WHO_GROUP:
> +                                                             if (!create_special_id(mem_ctx, nace40, "GROUP@")) {
> +                                                                             return false;
> +                                                             }
> +                                                             break;
> +
> +                                             case SMB_ACE4_WHO_EVERYONE:
> +                                                             if (!create_special_id(mem_ctx, nace40, "EVERYONE@")) {
> +                                                                             return false;
> +                                                             }
> +                                                             break;
> +                                             case SMB_ACE4_WHO_INTERACTIVE:
> +                                                             if (!create_special_id(mem_ctx, nace40, "INTERACTIVE@")) {
> +                                                                             return false;
> +                                                             }
> +                                                             break;
> +                                             case SMB_ACE4_WHO_NETWORK:
> +                                                             if (!create_special_id(mem_ctx, nace40, "NETWORK@")) {
> +                                                                             return false;
> +                                                             }
> +                                                             break;
> +                                             case SMB_ACE4_WHO_DIALUP:
> +                                                             if (!create_special_id(mem_ctx, nace40, "DIALUP@")) {
> +                                                                             return false;
> +                                                             }
> +                                                             break;
> +                                             case SMB_ACE4_WHO_BATCH:
> +                                                             if (!create_special_id(mem_ctx, nace40, "BATCH@")) {
> +                                                                             return false;
> +                                                             }
> +                                                             break;
> +                                             case SMB_ACE4_WHO_ANONYMOUS:
> +                                                             if (!create_special_id(mem_ctx, nace40, "ANONYMOUS@")) {
> +                                                                             return false;
> +                                                             }
> +                                                             break;
> +                                             case SMB_ACE4_WHO_AUTHENTICATED:
> +                                                             if (!create_special_id(mem_ctx, nace40, "AUTHENTICATED@")) {
> +                                                                             return false;
> +                                                             }
> +                                                             break;
> +                                             case SMB_ACE4_WHO_SERVICE:
> +                                                             if (!create_special_id(mem_ctx, nace40, "SERVICE@")) {
> +                                                                             return false;
> +                                                             }
> +                                                             break;
> +
> +                                             default:
> +                                                             DBG_ERR("Unsupported special id [%d]\n",
> +                                                                             ace4prop->who.special_id);
> +                                                             continue;
> +                                             }
> +                                             DBG_DEBUG("nace40->who special [%s]\n", nace40->who.utf8string_val);
> +                             } else {
> +                                             if (ace4prop->aceFlags & SMB_ACE4_IDENTIFIER_GROUP) {
> +                                                             nace40->flag |= ACE4_IDENTIFIER_GROUP;
> +                                                             if (!create_numeric_id(mem_ctx, nace40, ace4prop->who.gid)) {
> +                                                                             return false;
> +                                                             }
> +                                                             DBG_DEBUG("nace40->who gid [%s]\n", nace40->who.utf8string_val);
> +                                             } else {
> +                                                             if (!create_numeric_id(mem_ctx, nace40, ace4prop->who.uid)) {
> +                                                                             return false;
> +                                                             }
> +                                                             DBG_DEBUG("nace40->who uid [%s]\n", nace40->who.utf8string_val);
> +                                             }
> +                             }
> +
> +                             nace_count++;
> +                             nfs40acl_set_naces(nacl40, nace_count);
> +                             smb4ace = smb_next_ace4(smb4ace);
> +             }
> +
> +             *_nacl40 = nacl40;
> +             return true;
> +}
> +
> +
> static bool smb4acl_to_nfs4acl(vfs_handle_struct *handle,
>                                                       TALLOC_CTX *mem_ctx,
>                                                       struct SMB4ACL_T *smb4acl,
> @@ -214,6 +460,49 @@ static bool smb4acl_to_nfs4acl(vfs_handle_struct *handle,
>                return true;
> }
> +NTSTATUS nfs40acl_smb4acl_to_xdr_blob(vfs_handle_struct *handle,
> +                                                                  TALLOC_CTX *mem_ctx,
> +                                                                  struct SMB4ACL_T *smb4acl,
> +                                                                  DATA_BLOB *_blob)
> +{
> +             nfsacl40 *nacl40 = NULL;
> +             XDR xdr = {0};
> +             size_t aclblobsize;
> +             DATA_BLOB blob;
> +             bool ok;
> +
> +             ok = smb4acl_to_nfs40acl(handle, talloc_tos(), smb4acl, &nacl40);
> +             if (!ok) {
> +                             DBG_ERR("smb4acl_to_nfs4acl failed\n");
> +                             return NT_STATUS_INTERNAL_ERROR;
> +             }
> +
> +             aclblobsize = nfs40acl_get_xdrblob_size(nacl40);
> +             if (aclblobsize == 0) {
> +                             return NT_STATUS_INTERNAL_ERROR;
> +             }
> +
> +             blob = data_blob_talloc(mem_ctx, NULL, aclblobsize);
> +             if (blob.data == NULL) {
> +                             TALLOC_FREE(nacl40);
> +                             return NT_STATUS_NO_MEMORY;
> +             }
> +             DBG_DEBUG("blob 0x%x size %ld\n", blob.data, blob.length);
> +
> +             xdrmem_create(&xdr, (char *)blob.data, blob.length, XDR_ENCODE);
> +
> +             ok = xdr_nfsacl40(&xdr, nacl40);
> +             TALLOC_FREE(nacl40);
> +             if (!ok) {
> +                             DBG_ERR("xdr_nfs4acl40 failed\n");
> +                             return NT_STATUS_NO_MEMORY;
> +             }
> +
> +             *_blob = blob;
> +             return NT_STATUS_OK;
> +}
> +
> +
> NTSTATUS nfs4acl_smb4acl_to_xdr_blob(vfs_handle_struct *handle,
>                                                                     TALLOC_CTX *mem_ctx,
>                                                                     struct SMB4ACL_T *smb4acl,
> @@ -272,6 +561,44 @@ static uint16_t nfs4acl_to_smb4acl_flags(unsigned nfsacl41_flags)
>                return smb4acl_flags;
> }
> +static NTSTATUS nfs40acl_xdr_blob_to_nfs40acl(struct vfs_handle_struct *handle,
> +                                                                                 TALLOC_CTX *mem_ctx,
> +                                                                                 DATA_BLOB *blob,
> +                                                                                 nfsacl40 **_nacl40)
> +{
> +             struct nfs4acl_config *config = NULL;
> +             nfsacl40* nacl40;
> +             size_t naces;
> +             XDR xdr = {0};
> +             bool ok;
> +
> +             SMB_VFS_HANDLE_GET_DATA(handle, config,
> +                                                             struct nfs4acl_config,
> +                                                             return NT_STATUS_INTERNAL_ERROR);
> +
> +             nacl40 = talloc_zero_size(mem_ctx, sizeof(nfsacl40));
> +             if (nacl40 == NULL) {
> +                             DBG_ERR("talloc_zero_size failed\n");
> +                             return NT_STATUS_NO_MEMORY;
> +             }
> +
> +             xdrmem_create(&xdr, (char *)blob->data, blob->length, XDR_DECODE);
> +
> +             /* XDR allocates the required memory */
> +             ok = xdr_nfsacl40(&xdr, nacl40);
> +             if (!ok) {
> +                             DBG_ERR("xdr_nfsacl40 failed\n");
> +                             return NT_STATUS_INTERNAL_ERROR;
> +             }
> +
> +             /* naces is obtained by XDR decode */
> +             naces = nacl40->na40_aces.na40_aces_len;
> +             DBG_DEBUG("naces = %d \n", naces);
> +
> +             *_nacl40 = nacl40;
> +             return NT_STATUS_OK;
> +}
> +
> static NTSTATUS nfs4acl_xdr_blob_to_nfs4acl(struct vfs_handle_struct *handle,
>                                                                                    TALLOC_CTX *mem_ctx,
>                                                                                    DATA_BLOB *blob,
> @@ -306,6 +633,121 @@ static NTSTATUS nfs4acl_xdr_blob_to_nfs4acl(struct vfs_handle_struct *handle,
>                return NT_STATUS_OK;
> }
> +static NTSTATUS nfs40acl_to_smb4acl(struct vfs_handle_struct *handle,
> +                                                                TALLOC_CTX *mem_ctx,
> +                                                                nfsacl40 *nacl40,
> +                                                                struct SMB4ACL_T **_smb4acl)
> +{
> +             struct nfs4acl_config *config = NULL;
> +             struct SMB4ACL_T *smb4acl = NULL;
> +             unsigned nfsacl41_flag = 0;
> +             uint16_t smb4acl_flags = 0;
> +             unsigned naces = nfs40acl_get_naces(nacl40);
> +             int i;
> +
> +             SMB_VFS_HANDLE_GET_DATA(handle, config,
> +                                                             struct nfs4acl_config,
> +                                                             return NT_STATUS_INTERNAL_ERROR);
> +
> +             smb4acl = smb_create_smb4acl(mem_ctx);
> +             if (smb4acl == NULL) {
> +                             return NT_STATUS_INTERNAL_ERROR;
> +             }
> +
> +             DBG_DEBUG("flags [%x] nace [%u]\n", smb4acl_flags, naces);
> +
> +             for (i = 0; i < naces; i++) {
> +                             nfsace40 *nace40 = nfs40acl_get_ace(nacl40, i);
> +                             SMB_ACE4PROP_T smbace = { 0 };
> +
> +                             DBG_DEBUG("type [%d] flag [%x] mask [%x] who [%s]\n",
> +                                               nace40->type, nace40->flag,
> +                                               nace40->access_mask, nace40->who.utf8string_val);
> +
> +                             smbace.aceType = nace40->type;
> +                             smbace.aceFlags = nace40->flag;
> +                             smbace.aceMask = nace40->access_mask;
> +
> +                             if (0 == strncmp(nace40->who.utf8string_val, "OWNER@", nace40->who.utf8string_len)) {
> +                                             DBG_DEBUG("OWNER@\n");
> +                                             smbace.flags |= SMB_ACE4_ID_SPECIAL;
> +                                             smbace.who.special_id = SMB_ACE4_WHO_OWNER;
> +                             } else if (0 == strncmp(nace40->who.utf8string_val, "GROUP@", nace40->who.utf8string_len)) {
> +                                             DBG_DEBUG("GROUP@\n");
> +                                             smbace.flags |= SMB_ACE4_ID_SPECIAL;
> +                                             smbace.who.special_id = SMB_ACE4_WHO_GROUP;
> +                             } else if (0 == strncmp(nace40->who.utf8string_val, "EVERYONE@", nace40->who.utf8string_len)) {
> +                                             DBG_DEBUG("EVERYONE@\n");
> +                                             smbace.flags |= SMB_ACE4_ID_SPECIAL;
> +                                             smbace.who.special_id = SMB_ACE4_WHO_EVERYONE;
> +                             } else if (0 == strncmp(nace40->who.utf8string_val, "INTERACTIVE@", nace40->who.utf8string_len)) {
> +                                             DBG_DEBUG("INTERACTIVE@\n");
> +                                             smbace.flags |= SMB_ACE4_ID_SPECIAL;
> +                                             smbace.who.special_id = SMB_ACE4_WHO_INTERACTIVE;
> +                             } else if (0 == strncmp(nace40->who.utf8string_val, "NETWORK@", nace40->who.utf8string_len)) {
> +                                             DBG_DEBUG("NETWORK@\n");
> +                                             smbace.flags |= SMB_ACE4_ID_SPECIAL;
> +                                             smbace.who.special_id = SMB_ACE4_WHO_NETWORK;
> +                             } else if (0 == strncmp(nace40->who.utf8string_val, "DIALUP@", nace40->who.utf8string_len)) {
> +                                             DBG_DEBUG("DIALUP@\n");
> +                                             smbace.flags |= SMB_ACE4_ID_SPECIAL;
> +                                             smbace.who.special_id = SMB_ACE4_WHO_DIALUP;
> +                             } else if (0 == strncmp(nace40->who.utf8string_val, "BATCH@", nace40->who.utf8string_len)) {
> +                                             DBG_DEBUG("BATCH@\n");
> +                                             smbace.flags |= SMB_ACE4_ID_SPECIAL;
> +                                             smbace.who.special_id = SMB_ACE4_WHO_BATCH;
> +                             } else if (0 == strncmp(nace40->who.utf8string_val, "ANONYMOUS@", nace40->who.utf8string_len)) {
> +                                             DBG_DEBUG("ANONYMOUS@\n");
> +                                             smbace.flags |= SMB_ACE4_ID_SPECIAL;
> +                                             smbace.who.special_id = SMB_ACE4_WHO_ANONYMOUS;
> +                             } else if (0 == strncmp(nace40->who.utf8string_val, "AUTHENTICATED@", nace40->who.utf8string_len)) {
> +                                             DBG_DEBUG("AUTHENTICATED@\n");
> +                                             smbace.flags |= SMB_ACE4_ID_SPECIAL;
> +                                             smbace.who.special_id = SMB_ACE4_WHO_AUTHENTICATED;
> +                             } else if (0 == strncmp(nace40->who.utf8string_val, "SERVICE@", nace40->who.utf8string_len)) {
> +                                             DBG_DEBUG("SERVICE@\n");
> +                                             smbace.flags |= SMB_ACE4_ID_SPECIAL;
> +                                             smbace.who.special_id = SMB_ACE4_WHO_SERVICE;
> +
> +                             } else {
> +
> +                                             if (nace40->flag & ACE4_IDENTIFIER_GROUP) {
> +                                                             char *id = calloc(1, nace40->who.utf8string_len + 1);

Use talloc here, not malloc.

> +                                                             memcpy(id, nace40->who.utf8string_val, nace40->who.utf8string_len);
> +                                                             char *endptr = NULL;
> +                                                             smbace.who.gid = strtoul(id, &endptr, 10);
> +                                                             if (endptr >= nace40->who.utf8string_val && endptr < nace40->who.utf8string_val + nace40->who.utf8string_len) {
> +                                                                             DBG_ERR("Error converting gid [%s] to numeric gid, utf8string [%p] endptr: [%p] skipping %d %d\n",
> +                                                                                             id, nace40->who.utf8string_val, endptr, endptr - nace40->who.utf8string_val, nace40->who.utf8string_len);
> +                                                                             free(id);
> +                                                                             continue;
> +                                                             } else {
> +                                                                             DBG_DEBUG("gid %ld\n", smbace.who.gid);
> +                                                                             free(id);
> +                                                             }
> +                                             } else {
> +                                                             char *id = calloc(1, nace40->who.utf8string_len + 1);

Use talloc here, not malloc.

> +                                                             memcpy(id, nace40->who.utf8string_val, nace40->who.utf8string_len);
> +                                                             char *endptr = NULL;
> +                                                             smbace.who.uid = strtoul(id, &endptr, 10);
> +                                                             if (endptr >= nace40->who.utf8string_val && endptr < nace40->who.utf8string_val + nace40->who.utf8string_len) {
> +                                                                             DBG_ERR("Error converting uid [%s] to numeric uid, utf8string [%p] endptr: [%p] skipping\n",
> +                                                                                             id, nace40->who.utf8string_val, endptr);
> +                                                                             free(id);
> +                                                                             continue;
> +                                                             } else {
> +                                                                             DBG_DEBUG("uid %ld\n", smbace.who.uid);
> +                                                                             free(id);
> +                                                             }
> +                                             }
> +                             }
> +                             smb_add_ace4(smb4acl, &smbace);
> +             }
> +
> +             *_smb4acl = smb4acl;
> +             return NT_STATUS_OK;
> +}
> +
> static NTSTATUS nfs4acl_to_smb4acl(struct vfs_handle_struct *handle,
>                                                                   TALLOC_CTX *mem_ctx,
>                                                                   nfsacl41 *nacl,
> @@ -382,6 +824,37 @@ static NTSTATUS nfs4acl_to_smb4acl(struct vfs_handle_struct *handle,
>                return NT_STATUS_OK;
> }
> +NTSTATUS nfs40acl_xdr_blob_to_smb4(struct vfs_handle_struct *handle,
> +                                                               TALLOC_CTX *mem_ctx,
> +                                                               DATA_BLOB *blob,
> +                                                               struct SMB4ACL_T **_smb4acl)
> +{
> +             struct nfs4acl_config *config = NULL;
> +             nfsacl40 *nacl40 = NULL;
> +             struct SMB4ACL_T *smb4acl = NULL;
> +             NTSTATUS status;
> +
> +             DBG_DEBUG("entered\n");
> +
> +             SMB_VFS_HANDLE_GET_DATA(handle, config,
> +                                                             struct nfs4acl_config,
> +                                                             return NT_STATUS_INTERNAL_ERROR);
> +
> +             status = nfs40acl_xdr_blob_to_nfs40acl(handle, talloc_tos(), blob, &nacl40);
> +             if (!NT_STATUS_IS_OK(status)) {
> +                             return status;
> +             }
> +
> +             status = nfs40acl_to_smb4acl(handle, mem_ctx, nacl40, &smb4acl);
> +             TALLOC_FREE(nacl40);
> +             if (!NT_STATUS_IS_OK(status)) {
> +                             return status;
> +             }
> +
> +             *_smb4acl = smb4acl;
> +             return NT_STATUS_OK;
> +}
> +
> NTSTATUS nfs4acl_xdr_blob_to_smb4(struct vfs_handle_struct *handle,
>                                                                  TALLOC_CTX *mem_ctx,
>                                                                  DATA_BLOB *blob,
> diff --git a/source3/modules/nfs4acl_xattr_xdr.h b/source3/modules/nfs4acl_xattr_xdr.h
> index 8a544349cc8..67d60706335 100644
> --- a/source3/modules/nfs4acl_xattr_xdr.h
> +++ b/source3/modules/nfs4acl_xattr_xdr.h
> @@ -19,7 +19,7 @@
> #ifndef __NFS4ACL_XATTR_XDR_H__
> #define __NFS4ACL_XATTR_XDR_H__
> -#define NFS4ACL_XDR_XATTR_NAME "security.nfs4acl_xdr"
> +#define NFS4ACL_XDR_XATTR_NAME "system.nfs4_acl"
> #define NFS4ACL_XDR_MAX_ACES 8192
>  NTSTATUS nfs4acl_xdr_blob_to_smb4(struct vfs_handle_struct *handle,
> @@ -32,4 +32,14 @@ NTSTATUS nfs4acl_smb4acl_to_xdr_blob(vfs_handle_struct *handle,
>                                                                     struct SMB4ACL_T *smbacl,
>                                                                     DATA_BLOB *blob);
> +NTSTATUS nfs40acl_xdr_blob_to_smb4(struct vfs_handle_struct *handle,
> +                                                               TALLOC_CTX *mem_ctx,
> +                                                               DATA_BLOB *blob,
> +                                                               struct SMB4ACL_T **_smb4acl);
> +
> +NTSTATUS nfs40acl_smb4acl_to_xdr_blob(vfs_handle_struct *handle,
> +                                                                  TALLOC_CTX *mem_ctx,
> +                                                                  struct SMB4ACL_T *smbacl,
> +                                                                  DATA_BLOB *blob);
> +
> #endif /* __NFS4ACL_XATTR_XDR_H__ */
> diff --git a/source3/modules/vfs_nfs4acl_xattr.c b/source3/modules/vfs_nfs4acl_xattr.c
> index 0e52782075b..1b0e9cfe327 100644
> --- a/source3/modules/vfs_nfs4acl_xattr.c
> +++ b/source3/modules/vfs_nfs4acl_xattr.c
> @@ -226,7 +226,7 @@ static NTSTATUS nfs4acl_blob_to_smb4(struct vfs_handle_struct *handle,
>                                status = nfs4acl_ndr_blob_to_smb4(handle, mem_ctx, blob, smb4acl);
>                                break;
>                case NFS4ACL_ENCODING_XDR:
> -                              status = nfs4acl_xdr_blob_to_smb4(handle, mem_ctx, blob, smb4acl);
> +                             status = nfs40acl_xdr_blob_to_smb4(handle, mem_ctx, blob, smb4acl);
>                                break;
>                default:
>                                status = NT_STATUS_INTERNAL_ERROR;
> @@ -325,7 +325,7 @@ static bool nfs4acl_smb4acl_set_fn(vfs_handle_struct *handle,
>                                                                                                     smb4acl, &blob);
>                                break;
>                case NFS4ACL_ENCODING_XDR:
> -                              status = nfs4acl_smb4acl_to_xdr_blob(handle, talloc_tos(),
> +                             status = nfs40acl_smb4acl_to_xdr_blob(handle, talloc_tos(),
>                                                                                                     smb4acl, &blob);
>                                break;
>                default:
> @@ -535,7 +535,7 @@ static int nfs4acl_connect(struct vfs_handle_struct *handle,
>                nfs_version = (unsigned)lp_parm_int(SNUM(handle->conn),
>                                                                                    "nfs4acl_xattr",
>                                                                                    "version",
> -                                                                                  41);
> +                                                                                 40);
>                switch (nfs_version) {
>                case 40:
>                                config->nfs_version = ACL4_XATTR_VERSION_40;
> --
> 2.18.0.windows.1
> 
> ***************************Legal Disclaimer***************************
> "This communication may contain confidential and privileged material for the
> sole use of the intended recipient. Any unauthorized review, use or distribution
> by others is strictly prohibited. If you have received the message by mistake,
> please advise the sender by reply email and delete the message. Thank you."
> **********************************************************************



More information about the samba-technical mailing list