vfs_nfs4acl_xattr: add XDR backend
authorRalph Boehme <slow@samba.org>
Wed, 18 Oct 2017 18:48:37 +0000 (20:48 +0200)
committerJeremy Allison <jra@samba.org>
Tue, 7 Nov 2017 23:20:08 +0000 (00:20 +0100)
Add a NFS4 ACL backend that stores the ACL blob in an XDR encoded xattr,
by default in "security.nfs4acl_xdr".

This backend is enabled by setting "nfs4acl_xattr:encoding = xdr" in a
share definition.

Signed-off-by: Ralph Boehme <slow@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>
source3/modules/nfs41acl.x [new file with mode: 0644]
source3/modules/nfs4acl_xattr_xdr.c [new file with mode: 0644]
source3/modules/nfs4acl_xattr_xdr.h [new file with mode: 0644]
source3/modules/vfs_nfs4acl_xattr.c
source3/modules/wscript_build
source3/wscript

diff --git a/source3/modules/nfs41acl.x b/source3/modules/nfs41acl.x
new file mode 100644 (file)
index 0000000..9cfbd9f
--- /dev/null
@@ -0,0 +1,94 @@
+typedef opaque utf8string<>;
+typedef utf8string utf8str_mixed;
+
+const ACE4_ACCESS_ALLOWED_ACE_TYPE      = 0x00000000;
+const ACE4_ACCESS_DENIED_ACE_TYPE       = 0x00000001;
+const ACE4_SYSTEM_AUDIT_ACE_TYPE        = 0x00000002;
+const ACE4_SYSTEM_ALARM_ACE_TYPE        = 0x00000003;
+
+typedef u_int acetype4;
+
+const ACE4_FILE_INHERIT_ACE             = 0x00000001;
+const ACE4_DIRECTORY_INHERIT_ACE        = 0x00000002;
+const ACE4_NO_PROPAGATE_INHERIT_ACE     = 0x00000004;
+const ACE4_INHERIT_ONLY_ACE             = 0x00000008;
+const ACE4_SUCCESSFUL_ACCESS_ACE_FLAG   = 0x00000010;
+const ACE4_FAILED_ACCESS_ACE_FLAG       = 0x00000020;
+const ACE4_IDENTIFIER_GROUP             = 0x00000040;
+const ACE4_INHERITED_ACE                = 0x00000080;
+
+typedef u_int aceflag4;
+
+/*
+ * The following aceiflag4 is extensions for RFC 5661 that deals with storing
+ * identifiers as numerical ids instead UTF8 strings in order to avoid wasting
+ * CPU cycles for the costly conversion.
+ *
+ * Placed in a seperate field to avoid ever running into conflicts with newly
+ * defined NFSv4 flags.
+ */
+
+const ACEI4_SPECIAL_WHO                  = 0x00000001;
+
+typedef u_int aceiflag4;
+
+/*
+ * Numerical representation of special identifiers from 6.2.1.5.
+ * ACEI4_SPECIAL_WHO MUST be set in nfsace4.aceiflag4.
+ */
+const ACE4_SPECIAL_OWNER                = 1;
+const ACE4_SPECIAL_GROUP                = 2;
+const ACE4_SPECIAL_EVERYONE             = 3;
+const ACE4_SPECIAL_INTERACTIVE          = 4;
+const ACE4_SPECIAL_NETWORK              = 5;
+const ACE4_SPECIAL_DIALUP               = 6;
+const ACE4_SPECIAL_BATCH                = 7;
+const ACE4_SPECIAL_ANONYMOUS            = 8;
+const ACE4_SPECIAL_AUTHENTICATED        = 9;
+const ACE4_SPECIAL_SERVICE              = 10;
+
+const ACE4_READ_DATA            = 0x00000001;
+const ACE4_LIST_DIRECTORY       = 0x00000001;
+const ACE4_WRITE_DATA           = 0x00000002;
+const ACE4_ADD_FILE             = 0x00000002;
+const ACE4_APPEND_DATA          = 0x00000004;
+const ACE4_ADD_SUBDIRECTORY     = 0x00000004;
+const ACE4_READ_NAMED_ATTRS     = 0x00000008;
+const ACE4_WRITE_NAMED_ATTRS    = 0x00000010;
+const ACE4_EXECUTE              = 0x00000020;
+const ACE4_DELETE_CHILD         = 0x00000040;
+const ACE4_READ_ATTRIBUTES      = 0x00000080;
+const ACE4_WRITE_ATTRIBUTES     = 0x00000100;
+const ACE4_WRITE_RETENTION      = 0x00000200;
+const ACE4_WRITE_RETENTION_HOLD = 0x00000400;
+
+const ACE4_DELETE               = 0x00010000;
+const ACE4_READ_ACL             = 0x00020000;
+const ACE4_WRITE_ACL            = 0x00040000;
+const ACE4_WRITE_OWNER          = 0x00080000;
+const ACE4_SYNCHRONIZE          = 0x00100000;
+
+typedef u_int acemask4;
+
+struct nfsace4 {
+        acetype4        type;
+        aceflag4        flag;
+        aceiflag4       iflag;
+        acemask4        access_mask;
+        u_int           who;
+};
+
+const ACL4_XATTR_VERSION_40      = 0;
+const ACL4_XATTR_VERSION_41      = 1;
+const ACL4_XATTR_VERSION_DEFAULT = ACL4_XATTR_VERSION_40;
+
+const ACL4_AUTO_INHERIT         = 0x00000001;
+const ACL4_PROTECTED            = 0x00000002;
+const ACL4_DEFAULTED            = 0x00000004;
+
+typedef u_int aclflag4;
+
+struct nfsacl41 {
+        aclflag4        na41_flag;
+        nfsace4         na41_aces<>;
+};
diff --git a/source3/modules/nfs4acl_xattr_xdr.c b/source3/modules/nfs4acl_xattr_xdr.c
new file mode 100644 (file)
index 0000000..67684dc
--- /dev/null
@@ -0,0 +1,421 @@
+/*
+ * Copyright (C) Ralph Boehme 2017
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "includes.h"
+#include "smbd/proto.h"
+#include "libcli/security/security_descriptor.h"
+#include "libcli/security/security_token.h"
+#include "nfs4_acls.h"
+#include "nfs4acl_xattr.h"
+
+#undef DBGC_CLASS
+#define DBGC_CLASS DBGC_VFS
+
+#ifdef HAVE_RPC_XDR_H
+#include <rpc/xdr.h>
+#include "nfs41acl.h"
+#include "nfs4acl_xattr_xdr.h"
+
+static unsigned nfs4acl_get_naces(nfsacl41 *nacl)
+{
+       return nacl->na41_aces.na41_aces_len;
+}
+
+static void nfs4acl_set_naces(nfsacl41 *nacl, unsigned naces)
+{
+       nacl->na41_aces.na41_aces_len = naces;
+}
+
+static unsigned nfs4acl_get_flags(nfsacl41 *nacl)
+{
+       return nacl->na41_flag;
+}
+
+static void nfs4acl_set_flags(nfsacl41 *nacl, unsigned flags)
+{
+       nacl->na41_flag = flags;
+}
+
+static size_t nfs4acl_get_xdrblob_size(nfsacl41 *nacl)
+{
+       size_t acl_size;
+       size_t aces_size;
+       unsigned naces = nfs4acl_get_naces(nacl);
+
+       acl_size = sizeof(aclflag4) + sizeof(unsigned);
+
+       if (naces > NFS4ACL_XDR_MAX_ACES) {
+               DBG_ERR("Too many ACEs: %u", naces);
+               return 0;
+       }
+
+       aces_size = naces * sizeof(struct nfsace4);
+       if (acl_size + aces_size < acl_size) {
+               return 0;
+       }
+       acl_size += aces_size;
+
+       return acl_size;
+}
+
+static size_t nfs4acl_get_xdrblob_naces(size_t _blobsize)
+{
+       size_t blobsize = _blobsize;
+
+       blobsize -= sizeof(aclflag4);
+       blobsize -= sizeof(unsigned);
+       if (blobsize > _blobsize) {
+               return 0;
+       }
+       return (blobsize / sizeof(struct nfsace4));
+}
+
+static nfsacl41 *nfs4acl_alloc(TALLOC_CTX *mem_ctx, unsigned naces)
+{
+       size_t acl_size = sizeof(nfsacl41) + (naces * sizeof(struct nfsace4));
+       nfsacl41 *nacl = NULL;
+
+       if (naces > NFS4ACL_XDR_MAX_ACES) {
+               DBG_ERR("Too many ACEs: %d\n", naces);
+               return NULL;
+       }
+
+       nacl = talloc_zero_size(mem_ctx, acl_size);
+       if (nacl == NULL) {
+               DBG_ERR("talloc_zero_size failed\n");
+               return NULL;
+       }
+
+       nfs4acl_set_naces(nacl, naces);
+       nacl->na41_aces.na41_aces_val =
+               (nfsace4 *)((char *)nacl + sizeof(nfsacl41));
+
+       return nacl;
+}
+
+static nfsace4 *nfs4acl_get_ace(nfsacl41 *nacl, size_t n)
+{
+       return &nacl->na41_aces.na41_aces_val[n];
+}
+
+static unsigned smb4acl_to_nfs4acl_flags(uint16_t smb4acl_flags)
+{
+       unsigned nfs4acl_flags = 0;
+
+       if (smb4acl_flags & SEC_DESC_DACL_AUTO_INHERITED) {
+               nfs4acl_flags |= ACL4_AUTO_INHERIT;
+       }
+       if (smb4acl_flags & SEC_DESC_DACL_PROTECTED) {
+               nfs4acl_flags |= ACL4_PROTECTED;
+       }
+       if (smb4acl_flags & SEC_DESC_DACL_DEFAULTED) {
+               nfs4acl_flags |= ACL4_DEFAULTED;
+       }
+
+       return nfs4acl_flags;
+}
+
+static bool smb4acl_to_nfs4acl(vfs_handle_struct *handle,
+                              TALLOC_CTX *mem_ctx,
+                              struct SMB4ACL_T *smb4acl,
+                              nfsacl41 **_nacl)
+{
+       struct nfs4acl_config *config = NULL;
+       struct SMB4ACE_T *smb4ace = NULL;
+       size_t smb4naces = 0;
+       nfsacl41 *nacl = 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);
+       nacl = nfs4acl_alloc(mem_ctx, smb4naces);
+       nfs4acl_set_naces(nacl, 0);
+
+       if (config->nfs_version > ACL4_XATTR_VERSION_40) {
+               smb4acl_flags = smbacl4_get_controlflags(smb4acl);
+               nacl_flags = smb4acl_to_nfs4acl_flags(smb4acl_flags);
+               nfs4acl_set_flags(nacl, nacl_flags);
+       }
+
+       smb4ace = smb_first_ace4(smb4acl);
+       while (smb4ace != NULL) {
+               SMB_ACE4PROP_T *ace4prop = smb_get_ace4(smb4ace);
+               size_t nace_count = nfs4acl_get_naces(nacl);
+               nfsace4 *nace = nfs4acl_get_ace(nacl, nace_count);
+
+               nace->type = ace4prop->aceType;
+               nace->flag = ace4prop->aceFlags;
+               nace->access_mask = ace4prop->aceMask;
+
+               if (ace4prop->flags & SMB_ACE4_ID_SPECIAL) {
+                       nace->iflag |= ACEI4_SPECIAL_WHO;
+
+                       switch (ace4prop->who.special_id) {
+                       case SMB_ACE4_WHO_OWNER:
+                               nace->who = ACE4_SPECIAL_OWNER;
+                               break;
+
+                       case SMB_ACE4_WHO_GROUP:
+                               nace->who = ACE4_SPECIAL_GROUP;
+                               break;
+
+                       case SMB_ACE4_WHO_EVERYONE:
+                               nace->who = ACE4_SPECIAL_EVERYONE;
+                               break;
+
+                       default:
+                               DBG_ERR("Unsupported special id [%d]\n",
+                                       ace4prop->who.special_id);
+                               continue;
+                       }
+               } else {
+                       if (ace4prop->aceFlags & SMB_ACE4_IDENTIFIER_GROUP) {
+                               nace->flag |= ACE4_IDENTIFIER_GROUP;
+                               nace->who = ace4prop->who.gid;
+                       } else {
+                               nace->who = ace4prop->who.uid;
+                       }
+               }
+
+               nace_count++;
+               nfs4acl_set_naces(nacl, nace_count);
+               smb4ace = smb_next_ace4(smb4ace);
+       }
+
+       *_nacl = nacl;
+       return true;
+}
+
+NTSTATUS nfs4acl_smb4acl_to_xdr_blob(vfs_handle_struct *handle,
+                                    TALLOC_CTX *mem_ctx,
+                                    struct SMB4ACL_T *smb4acl,
+                                    DATA_BLOB *_blob)
+{
+       nfsacl41 *nacl = NULL;
+       XDR xdr = {0};
+       size_t aclblobsize;
+       DATA_BLOB blob;
+       bool ok;
+
+       ok = smb4acl_to_nfs4acl(handle, talloc_tos(), smb4acl, &nacl);
+       if (!ok) {
+               DBG_ERR("smb4acl_to_nfs4acl failed\n");
+               return NT_STATUS_INTERNAL_ERROR;
+       }
+
+       aclblobsize = nfs4acl_get_xdrblob_size(nacl);
+       if (aclblobsize == 0) {
+               return NT_STATUS_INTERNAL_ERROR;
+       }
+
+       blob = data_blob_talloc(mem_ctx, NULL, aclblobsize);
+       if (blob.data == NULL) {
+               TALLOC_FREE(nacl);
+               return NT_STATUS_NO_MEMORY;
+       }
+
+       xdrmem_create(&xdr, (char *)blob.data, blob.length, XDR_ENCODE);
+
+       ok = xdr_nfsacl41(&xdr, nacl);
+       TALLOC_FREE(nacl);
+       if (!ok) {
+               DBG_ERR("xdr_nfs4acl41 failed\n");
+               return NT_STATUS_NO_MEMORY;
+       }
+
+       *_blob = blob;
+       return NT_STATUS_OK;
+}
+
+static uint16_t nfs4acl_to_smb4acl_flags(unsigned nfsacl41_flags)
+{
+       uint16_t smb4acl_flags = SEC_DESC_SELF_RELATIVE;
+
+       if (nfsacl41_flags & ACL4_AUTO_INHERIT) {
+               smb4acl_flags |= SEC_DESC_DACL_AUTO_INHERITED;
+       }
+       if (nfsacl41_flags & ACL4_PROTECTED) {
+               smb4acl_flags |= SEC_DESC_DACL_PROTECTED;
+       }
+       if (nfsacl41_flags & ACL4_DEFAULTED) {
+               smb4acl_flags |= SEC_DESC_DACL_DEFAULTED;
+       }
+
+       return smb4acl_flags;
+}
+
+static NTSTATUS nfs4acl_xdr_blob_to_nfs4acl(struct vfs_handle_struct *handle,
+                                           TALLOC_CTX *mem_ctx,
+                                           DATA_BLOB *blob,
+                                           nfsacl41 **_nacl)
+{
+       struct nfs4acl_config *config = NULL;
+       nfsacl41 *nacl = NULL;
+       size_t naces;
+       XDR xdr = {0};
+       bool ok;
+
+       SMB_VFS_HANDLE_GET_DATA(handle, config,
+                               struct nfs4acl_config,
+                               return NT_STATUS_INTERNAL_ERROR);
+
+       naces = nfs4acl_get_xdrblob_naces(blob->length);
+       nacl = nfs4acl_alloc(mem_ctx, naces);
+
+       xdrmem_create(&xdr, (char *)blob->data, blob->length, XDR_DECODE);
+
+       ok = xdr_nfsacl41(&xdr, nacl);
+       if (!ok) {
+               DBG_ERR("xdr_nfs4acl41 failed\n");
+               return NT_STATUS_INTERNAL_ERROR;
+       }
+
+       if (config->nfs_version == ACL4_XATTR_VERSION_40) {
+               nacl->na41_flag = 0;
+       }
+
+       *_nacl = nacl;
+       return NT_STATUS_OK;
+}
+
+static NTSTATUS nfs4acl_to_smb4acl(struct vfs_handle_struct *handle,
+                                  TALLOC_CTX *mem_ctx,
+                                  nfsacl41 *nacl,
+                                  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 = nfs4acl_get_naces(nacl);
+       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;
+       }
+
+       if (config->nfs_version > ACL4_XATTR_VERSION_40) {
+               nfsacl41_flag = nfs4acl_get_flags(nacl);
+               smb4acl_flags = nfs4acl_to_smb4acl_flags(nfsacl41_flag);
+               smbacl4_set_controlflags(smb4acl, smb4acl_flags);
+       }
+
+       DBG_DEBUG("flags [%x] nace [%u]\n", smb4acl_flags, naces);
+
+       for (i = 0; i < naces; i++) {
+               nfsace4 *nace = nfs4acl_get_ace(nacl, i);
+               SMB_ACE4PROP_T smbace = { 0 };
+
+               DBG_DEBUG("type [%d] iflag [%x] flag [%x] mask [%x] who [%d]\n",
+                         nace->type, nace->iflag, nace->flag,
+                         nace->access_mask, nace->who);
+
+               smbace.aceType = nace->type;
+               smbace.aceFlags = nace->flag;
+               smbace.aceMask = nace->access_mask;
+
+               if (nace->iflag & ACEI4_SPECIAL_WHO) {
+                       smbace.flags |= SMB_ACE4_ID_SPECIAL;
+
+                       switch (nace->who) {
+                       case ACE4_SPECIAL_OWNER:
+                               smbace.who.special_id = SMB_ACE4_WHO_OWNER;
+                               break;
+
+                       case ACE4_SPECIAL_GROUP:
+                               smbace.who.special_id = SMB_ACE4_WHO_GROUP;
+                               break;
+
+                       case ACE4_SPECIAL_EVERYONE:
+                               smbace.who.special_id = SMB_ACE4_WHO_EVERYONE;
+                               break;
+
+                       default:
+                               DBG_ERR("Unknown special id [%d]\n", nace->who);
+                               continue;
+                       }
+               } else {
+                       if (nace->flag & ACE4_IDENTIFIER_GROUP) {
+                               smbace.who.gid = nace->who;
+                       } else {
+                               smbace.who.uid = nace->who;
+                       }
+               }
+
+               smb_add_ace4(smb4acl, &smbace);
+       }
+
+       *_smb4acl = smb4acl;
+       return NT_STATUS_OK;
+}
+
+NTSTATUS nfs4acl_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;
+       nfsacl41 *nacl = NULL;
+       struct SMB4ACL_T *smb4acl = NULL;
+       NTSTATUS status;
+
+       SMB_VFS_HANDLE_GET_DATA(handle, config,
+                               struct nfs4acl_config,
+                               return NT_STATUS_INTERNAL_ERROR);
+
+       status = nfs4acl_xdr_blob_to_nfs4acl(handle, talloc_tos(), blob, &nacl);
+       if (!NT_STATUS_IS_OK(status)) {
+               return status;
+       }
+
+       status = nfs4acl_to_smb4acl(handle, mem_ctx, nacl, &smb4acl);
+       TALLOC_FREE(nacl);
+       if (!NT_STATUS_IS_OK(status)) {
+               return status;
+       }
+
+       *_smb4acl = smb4acl;
+       return NT_STATUS_OK;
+}
+
+#else /* !HAVE_RPC_XDR_H */
+NTSTATUS nfs4acl_xdr_blob_to_smb4(struct vfs_handle_struct *handle,
+                                 TALLOC_CTX *mem_ctx,
+                                 DATA_BLOB *blob,
+                                 struct SMB4ACL_T **_smb4acl)
+{
+       return NT_STATUS_NOT_SUPPORTED;
+}
+
+NTSTATUS nfs4acl_smb4acl_to_xdr_blob(vfs_handle_struct *handle,
+                                    TALLOC_CTX *mem_ctx,
+                                    struct SMB4ACL_T *smbacl,
+                                    DATA_BLOB *blob)
+{
+       return NT_STATUS_NOT_SUPPORTED;
+}
+#endif /* HAVE_RPC_XDR_H */
diff --git a/source3/modules/nfs4acl_xattr_xdr.h b/source3/modules/nfs4acl_xattr_xdr.h
new file mode 100644 (file)
index 0000000..8a54434
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) Ralph Boehme 2017
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef __NFS4ACL_XATTR_XDR_H__
+#define __NFS4ACL_XATTR_XDR_H__
+
+#define NFS4ACL_XDR_XATTR_NAME "security.nfs4acl_xdr"
+#define NFS4ACL_XDR_MAX_ACES 8192
+
+NTSTATUS nfs4acl_xdr_blob_to_smb4(struct vfs_handle_struct *handle,
+                                 TALLOC_CTX *mem_ctx,
+                                 DATA_BLOB *blob,
+                                 struct SMB4ACL_T **_smb4acl);
+
+NTSTATUS nfs4acl_smb4acl_to_xdr_blob(vfs_handle_struct *handle,
+                                    TALLOC_CTX *mem_ctx,
+                                    struct SMB4ACL_T *smbacl,
+                                    DATA_BLOB *blob);
+
+#endif /* __NFS4ACL_XATTR_XDR_H__ */
index d4f4d47635ee143779ae04423268676eff6567e6..d301f25ed31dc27d690a9f90d35afb3c972d25e0 100644 (file)
@@ -34,6 +34,7 @@
 #include "librpc/gen_ndr/ndr_nfs4acl.h"
 #include "nfs4acl_xattr.h"
 #include "nfs4acl_xattr_ndr.h"
+#include "nfs4acl_xattr_xdr.h"
 
 #undef DBGC_CLASS
 #define DBGC_CLASS DBGC_VFS
@@ -224,6 +225,9 @@ static NTSTATUS nfs4acl_blob_to_smb4(struct vfs_handle_struct *handle,
        case NFS4ACL_ENCODING_NDR:
                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);
+               break;
        default:
                status = NT_STATUS_INTERNAL_ERROR;
                break;
@@ -320,6 +324,10 @@ static bool nfs4acl_smb4acl_set_fn(vfs_handle_struct *handle,
                status = nfs4acl_smb4acl_to_ndr_blob(handle, talloc_tos(),
                                                     smb4acl, &blob);
                break;
+       case NFS4ACL_ENCODING_XDR:
+               status = nfs4acl_smb4acl_to_xdr_blob(handle, talloc_tos(),
+                                                    smb4acl, &blob);
+               break;
        default:
                status = NT_STATUS_INTERNAL_ERROR;
                break;
@@ -515,6 +523,9 @@ static int nfs4acl_connect(struct vfs_handle_struct *handle,
        config->encoding = (enum nfs4acl_encoding)enumval;
 
        switch (config->encoding) {
+       case NFS4ACL_ENCODING_XDR:
+               default_xattr_name = NFS4ACL_XDR_XATTR_NAME;
+               break;
        case NFS4ACL_ENCODING_NDR:
        default:
                default_xattr_name = NFS4ACL_NDR_XATTR_NAME;
index 6943d474826a662e64f864605f8f07d021ff3633..ab9be384189ad5e50eddd15e144939dfc12a666b 100644 (file)
@@ -217,9 +217,30 @@ bld.SAMBA3_MODULE('vfs_zfsacl',
                  internal_module=bld.SAMBA3_IS_STATIC_MODULE('vfs_zfsacl'),
                  enabled=bld.SAMBA3_IS_ENABLED_MODULE('vfs_zfsacl'))
 
+xdr_buf_hack = 'sed -e "s@^\([ \t]*register int32_t \*buf\);@\\1 = buf;@"'
+
+bld.SAMBA_GENERATOR('nfs41acl-xdr-c',
+                    source='nfs41acl.x',
+                    target='nfs41acl_xdr.c',
+                    rule='rpcgen -c ${SRC} | ' + xdr_buf_hack + ' > ${TGT}')
+
+bld.SAMBA_GENERATOR('nfs41acl-h',
+                    source='nfs41acl.x',
+                    target='nfs41acl.h',
+                    rule='rpcgen -h ${SRC} > ${TGT}')
+
+vfs_nfs4acl_xattr_source = '''
+                           vfs_nfs4acl_xattr.c
+                           nfs4acl_xattr_ndr.c
+                           nfs4acl_xattr_xdr.c
+                           '''
+
+if bld.CONFIG_SET("HAVE_RPC_XDR_H"):
+    vfs_nfs4acl_xattr_source += ' nfs41acl_xdr.c'
+
 bld.SAMBA3_MODULE('vfs_nfs4acl_xattr',
                   subsystem='vfs',
-                  source='vfs_nfs4acl_xattr.c nfs4acl_xattr_ndr.c',
+                  source=vfs_nfs4acl_xattr_source,
                   deps='NFS4_ACLS sunacl NDR_NFS4ACL',
                   init_function='',
                   internal_module=bld.SAMBA3_IS_STATIC_MODULE('vfs_nfs4acl_xattr'),
index 3638abab2026b18a70765cda572058f9dc6c8b5b..814433488e4d553502a1d3b2239394754feae075 100644 (file)
@@ -1664,6 +1664,8 @@ main() {
         Logs.info("building with Spotlight support")
         default_static_modules.extend(TO_LIST('rpc_mdssvc_module'))
 
+    conf.CHECK_HEADERS('rpc/xdr.h')
+
     forced_static_modules.extend(TO_LIST('auth_builtin auth_sam auth_winbind'))
     default_static_modules.extend(TO_LIST('''pdb_smbpasswd pdb_tdbsam
                                       auth_unix