[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