vfs_nfs4acl_xattr: move the meat of the implementation to a seperate file
authorRalph Boehme <slow@samba.org>
Tue, 17 Oct 2017 10:02:53 +0000 (12:02 +0200)
committerJeremy Allison <jra@samba.org>
Tue, 7 Nov 2017 23:20:08 +0000 (00:20 +0100)
This is in preperation of modularizing the storage backend. Currently we
store the NFS4 ACL as an IDL/NDR encoded blob in a xattr.

Later commits will add a different backend storing the NFS4 ACL as an
XDR encoded blob in a xattr.

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

diff --git a/source3/modules/nfs4acl_xattr_ndr.c b/source3/modules/nfs4acl_xattr_ndr.c
new file mode 100644 (file)
index 0000000..af10018
--- /dev/null
@@ -0,0 +1,241 @@
+/*
+ * Convert NFSv4 acls stored per http://www.suse.de/~agruen/nfs4acl/ to NT acls and vice versa.
+ *
+ * Copyright (C) Jiri Sasek, 2007
+ * based on the foobar.c module which is copyrighted by Volker Lendecke
+ * based on pvfs_acl_nfs4.c  Copyright (C) Andrew Tridgell 2006
+ *
+ * based on vfs_fake_acls:
+ * Copyright (C) Tim Potter, 1999-2000
+ * Copyright (C) Alexander Bokovoy, 2002
+ * Copyright (C) Andrew Bartlett, 2002,2012
+ * 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 "system/filesys.h"
+#include "smbd/smbd.h"
+#include "nfs4_acls.h"
+#include "librpc/gen_ndr/ndr_nfs4acl.h"
+#include "nfs4acl_xattr.h"
+#include "nfs4acl_xattr_ndr.h"
+
+#undef DBGC_CLASS
+#define DBGC_CLASS DBGC_VFS
+
+static struct nfs4acl *nfs4acl_blob2acl(DATA_BLOB *blob, TALLOC_CTX *mem_ctx)
+{
+       enum ndr_err_code ndr_err;
+       struct nfs4acl *acl = talloc_zero(mem_ctx, struct nfs4acl);
+
+       if (acl == NULL) {
+               errno = ENOMEM;
+               return NULL;
+       }
+
+       ndr_err = ndr_pull_struct_blob(blob, acl, acl,
+               (ndr_pull_flags_fn_t)ndr_pull_nfs4acl);
+
+       if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+               DBG_ERR("ndr_pull_acl_t failed: %s\n", ndr_errstr(ndr_err));
+               TALLOC_FREE(acl);
+               return NULL;
+       }
+       return acl;
+}
+
+static DATA_BLOB nfs4acl_acl2blob(TALLOC_CTX *mem_ctx, struct nfs4acl *acl)
+{
+       enum ndr_err_code ndr_err;
+       DATA_BLOB blob;
+
+       ndr_err = ndr_push_struct_blob(&blob, mem_ctx, acl,
+               (ndr_push_flags_fn_t)ndr_push_nfs4acl);
+
+       if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+               DBG_ERR("ndr_push_acl_t failed: %s\n", ndr_errstr(ndr_err));
+               return data_blob_null;
+       }
+       return blob;
+}
+
+NTSTATUS nfs4acl_ndr_blob_to_smb4(struct vfs_handle_struct *handle,
+                                 TALLOC_CTX *mem_ctx,
+                                 DATA_BLOB *blob,
+                                 struct SMB4ACL_T **_smb4acl)
+{
+       struct nfs4acl *nfs4acl = NULL;
+       struct SMB4ACL_T *smb4acl = NULL;
+       TALLOC_CTX *frame = talloc_stackframe();
+       struct nfs4acl_config *config = NULL;
+       int i;
+
+       SMB_VFS_HANDLE_GET_DATA(handle, config,
+                               struct nfs4acl_config,
+                               return NT_STATUS_INTERNAL_ERROR);
+
+       nfs4acl = nfs4acl_blob2acl(blob, frame);
+       if (nfs4acl == NULL) {
+               TALLOC_FREE(frame);
+               return NT_STATUS_INTERNAL_ERROR;
+       }
+
+       smb4acl = smb_create_smb4acl(mem_ctx);
+       if (smb4acl == NULL) {
+               TALLOC_FREE(frame);
+               return NT_STATUS_NO_MEMORY;
+       }
+
+       for (i = 0; i < nfs4acl->a_count; i++) {
+               SMB_ACE4PROP_T aceprop;
+
+               aceprop.aceType  = (uint32_t) nfs4acl->ace[i].e_type;
+               aceprop.aceFlags = (uint32_t) nfs4acl->ace[i].e_flags;
+               aceprop.aceMask  = (uint32_t) nfs4acl->ace[i].e_mask;
+               aceprop.who.id   = (uint32_t) nfs4acl->ace[i].e_id;
+
+               if (!strcmp(nfs4acl->ace[i].e_who,
+                           NFS4ACL_XATTR_OWNER_WHO)) {
+                       aceprop.flags = SMB_ACE4_ID_SPECIAL;
+                       aceprop.who.special_id = SMB_ACE4_WHO_OWNER;
+               } else if (!strcmp(nfs4acl->ace[i].e_who,
+                                  NFS4ACL_XATTR_GROUP_WHO)) {
+                       aceprop.flags = SMB_ACE4_ID_SPECIAL;
+                       aceprop.who.special_id = SMB_ACE4_WHO_GROUP;
+               } else if (!strcmp(nfs4acl->ace[i].e_who,
+                                  NFS4ACL_XATTR_EVERYONE_WHO)) {
+                       aceprop.flags = SMB_ACE4_ID_SPECIAL;
+                       aceprop.who.special_id = SMB_ACE4_WHO_EVERYONE;
+               } else {
+                       aceprop.flags = 0;
+               }
+
+               if (smb_add_ace4(smb4acl, &aceprop) == NULL) {
+                       TALLOC_FREE(frame);
+                       return NT_STATUS_NO_MEMORY;
+               }
+       }
+
+       *_smb4acl = smb4acl;
+       TALLOC_FREE(frame);
+       return NT_STATUS_OK;
+}
+
+static bool nfs4acl_smb4acl2nfs4acl(TALLOC_CTX *mem_ctx,
+                                   struct SMB4ACL_T *smbacl,
+                                   struct nfs4acl **_nfs4acl,
+                                   bool denymissingspecial)
+{
+       struct nfs4acl *nfs4acl = NULL;
+       struct SMB4ACE_T *smbace = NULL;
+       bool have_special_id = false;
+       int i;
+
+       nfs4acl = talloc_zero(mem_ctx, struct nfs4acl);
+       if (nfs4acl == NULL) {
+               errno = ENOMEM;
+               return false;
+       }
+
+       nfs4acl->a_count = smb_get_naces(smbacl);
+
+       nfs4acl->ace = talloc_zero_array(nfs4acl, struct nfs4ace,
+                                        nfs4acl->a_count);
+       if (nfs4acl->ace == NULL) {
+               TALLOC_FREE(nfs4acl);
+               errno = ENOMEM;
+               return false;
+       }
+
+       for (smbace = smb_first_ace4(smbacl), i = 0;
+            smbace != NULL;
+            smbace = smb_next_ace4(smbace), i++)
+       {
+               SMB_ACE4PROP_T *aceprop = smb_get_ace4(smbace);
+
+               nfs4acl->ace[i].e_type        = aceprop->aceType;
+               nfs4acl->ace[i].e_flags       = aceprop->aceFlags;
+               nfs4acl->ace[i].e_mask        = aceprop->aceMask;
+               nfs4acl->ace[i].e_id          = aceprop->who.id;
+               if(aceprop->flags & SMB_ACE4_ID_SPECIAL) {
+                       switch(aceprop->who.special_id) {
+                       case SMB_ACE4_WHO_EVERYONE:
+                               nfs4acl->ace[i].e_who =
+                                       NFS4ACL_XATTR_EVERYONE_WHO;
+                               break;
+                       case SMB_ACE4_WHO_OWNER:
+                               nfs4acl->ace[i].e_who =
+                                       NFS4ACL_XATTR_OWNER_WHO;
+                               break;
+                       case SMB_ACE4_WHO_GROUP:
+                               nfs4acl->ace[i].e_who =
+                                       NFS4ACL_XATTR_GROUP_WHO;
+                               break;
+                       default:
+                               DBG_DEBUG("unsupported special_id %d\n",
+                                         aceprop->who.special_id);
+                               continue; /* don't add it !!! */
+                       }
+                       have_special_id = true;
+               } else {
+                       nfs4acl->ace[i].e_who = "";
+               }
+       }
+
+       if (!have_special_id && denymissingspecial) {
+               TALLOC_FREE(nfs4acl);
+               errno = EACCES;
+               return false;
+       }
+
+       SMB_ASSERT(i == nfs4acl->a_count);
+
+       *_nfs4acl = nfs4acl;
+       return true;
+}
+
+NTSTATUS nfs4acl_smb4acl_to_ndr_blob(vfs_handle_struct *handle,
+                                    TALLOC_CTX *mem_ctx,
+                                    struct SMB4ACL_T *smb4acl,
+                                    DATA_BLOB *_blob)
+{
+       struct nfs4acl *nfs4acl = NULL;
+       DATA_BLOB blob;
+       bool denymissingspecial;
+       bool ok;
+
+       denymissingspecial = lp_parm_bool(SNUM(handle->conn),
+                                         "nfs4acl_xattr",
+                                         "denymissingspecial", false);
+
+       ok = nfs4acl_smb4acl2nfs4acl(talloc_tos(), smb4acl, &nfs4acl,
+                                    denymissingspecial);
+       if (!ok) {
+               DBG_ERR("Failed to convert smb ACL to nfs4 ACL.\n");
+               return NT_STATUS_INTERNAL_ERROR;
+       }
+
+       blob = nfs4acl_acl2blob(mem_ctx, nfs4acl);
+       TALLOC_FREE(nfs4acl);
+       if (blob.data == NULL) {
+               DBG_ERR("Failed to convert ACL to linear blob for xattr\n");
+               return NT_STATUS_INTERNAL_ERROR;
+       }
+
+       *_blob = blob;
+       return NT_STATUS_OK;
+}
diff --git a/source3/modules/nfs4acl_xattr_ndr.h b/source3/modules/nfs4acl_xattr_ndr.h
new file mode 100644 (file)
index 0000000..7db4ce7
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ * Convert NFSv4 acls stored per http://www.suse.de/~agruen/nfs4acl/ to NT acls and vice versa.
+ *
+ * Copyright (C) Jiri Sasek, 2007
+ * based on the foobar.c module which is copyrighted by Volker Lendecke
+ * based on pvfs_acl_nfs4.c  Copyright (C) Andrew Tridgell 2006
+ *
+ * based on vfs_fake_acls:
+ * Copyright (C) Tim Potter, 1999-2000
+ * Copyright (C) Alexander Bokovoy, 2002
+ * Copyright (C) Andrew Bartlett, 2002,2012
+ * 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_NDR_H__
+#define __NFS4ACL_XATTR_NDR_H__
+
+NTSTATUS nfs4acl_ndr_blob_to_smb4(struct vfs_handle_struct *handle,
+                                 TALLOC_CTX *mem_ctx,
+                                 DATA_BLOB *blob,
+                                 struct SMB4ACL_T **_smb4acl);
+
+NTSTATUS nfs4acl_smb4acl_to_ndr_blob(vfs_handle_struct *handle,
+                                    TALLOC_CTX *mem_ctx,
+                                    struct SMB4ACL_T *smbacl,
+                                    DATA_BLOB *blob);
+
+#endif /* _VFS_NFS4ACL_XATTR_NDR_H */
index b3b5e497061c08936ab58b9574eacb630e664490..b8ff28b75c04afb3d43fb60eefc4feb7a640fc64 100644 (file)
@@ -32,6 +32,7 @@
 #include "nfs4_acls.h"
 #include "librpc/gen_ndr/ndr_nfs4acl.h"
 #include "nfs4acl_xattr.h"
+#include "nfs4acl_xattr_ndr.h"
 
 #undef DBGC_CLASS
 #define DBGC_CLASS DBGC_VFS
@@ -99,208 +100,6 @@ static NTSTATUS nfs4acl_get_blob(struct vfs_handle_struct *handle,
        return NT_STATUS_OK;
 }
 
-static struct nfs4acl *nfs4acl_blob2acl(DATA_BLOB *blob, TALLOC_CTX *mem_ctx)
-{
-       enum ndr_err_code ndr_err;
-       struct nfs4acl *acl = talloc_zero(mem_ctx, struct nfs4acl);
-
-       if (acl == NULL) {
-               errno = ENOMEM;
-               return NULL;
-       }
-
-       ndr_err = ndr_pull_struct_blob(blob, acl, acl,
-               (ndr_pull_flags_fn_t)ndr_pull_nfs4acl);
-
-       if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
-               DBG_ERR("ndr_pull_acl_t failed: %s\n", ndr_errstr(ndr_err));
-               TALLOC_FREE(acl);
-               return NULL;
-       }
-       return acl;
-}
-
-static DATA_BLOB nfs4acl_acl2blob(TALLOC_CTX *mem_ctx, struct nfs4acl *acl)
-{
-       enum ndr_err_code ndr_err;
-       DATA_BLOB blob;
-
-       ndr_err = ndr_push_struct_blob(&blob, mem_ctx, acl,
-               (ndr_push_flags_fn_t)ndr_push_nfs4acl);
-
-       if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
-               DBG_ERR("ndr_push_acl_t failed: %s\n", ndr_errstr(ndr_err));
-               return data_blob_null;
-       }
-       return blob;
-}
-
-static NTSTATUS nfs4acl_ndr_blob_to_smb4(struct vfs_handle_struct *handle,
-                                 TALLOC_CTX *mem_ctx,
-                                 DATA_BLOB *blob,
-                                 struct SMB4ACL_T **_smb4acl)
-{
-       struct nfs4acl *nfs4acl = NULL;
-       struct SMB4ACL_T *smb4acl = NULL;
-       TALLOC_CTX *frame = talloc_stackframe();
-       struct nfs4acl_config *config = NULL;
-       int i;
-
-       SMB_VFS_HANDLE_GET_DATA(handle, config,
-                               struct nfs4acl_config,
-                               return NT_STATUS_INTERNAL_ERROR);
-
-       nfs4acl = nfs4acl_blob2acl(blob, frame);
-       if (nfs4acl == NULL) {
-               TALLOC_FREE(frame);
-               return NT_STATUS_INTERNAL_ERROR;
-       }
-
-       smb4acl = smb_create_smb4acl(mem_ctx);
-       if (smb4acl == NULL) {
-               TALLOC_FREE(frame);
-               return NT_STATUS_NO_MEMORY;
-       }
-
-       for (i = 0; i < nfs4acl->a_count; i++) {
-               SMB_ACE4PROP_T aceprop;
-
-               aceprop.aceType  = (uint32_t) nfs4acl->ace[i].e_type;
-               aceprop.aceFlags = (uint32_t) nfs4acl->ace[i].e_flags;
-               aceprop.aceMask  = (uint32_t) nfs4acl->ace[i].e_mask;
-               aceprop.who.id   = (uint32_t) nfs4acl->ace[i].e_id;
-
-               if (!strcmp(nfs4acl->ace[i].e_who,
-                           NFS4ACL_XATTR_OWNER_WHO)) {
-                       aceprop.flags = SMB_ACE4_ID_SPECIAL;
-                       aceprop.who.special_id = SMB_ACE4_WHO_OWNER;
-               } else if (!strcmp(nfs4acl->ace[i].e_who,
-                                  NFS4ACL_XATTR_GROUP_WHO)) {
-                       aceprop.flags = SMB_ACE4_ID_SPECIAL;
-                       aceprop.who.special_id = SMB_ACE4_WHO_GROUP;
-               } else if (!strcmp(nfs4acl->ace[i].e_who,
-                                  NFS4ACL_XATTR_EVERYONE_WHO)) {
-                       aceprop.flags = SMB_ACE4_ID_SPECIAL;
-                       aceprop.who.special_id = SMB_ACE4_WHO_EVERYONE;
-               } else {
-                       aceprop.flags = 0;
-               }
-               if (smb_add_ace4(smb4acl, &aceprop) == NULL) {
-                       TALLOC_FREE(frame);
-                       return NT_STATUS_NO_MEMORY;
-               }
-       }
-
-       *_smb4acl = smb4acl;
-       TALLOC_FREE(frame);
-       return NT_STATUS_OK;
-}
-
-static bool nfs4acl_smb4acl2nfs4acl(TALLOC_CTX *mem_ctx,
-                                   struct SMB4ACL_T *smbacl,
-                                   struct nfs4acl **_nfs4acl,
-                                   bool denymissingspecial)
-{
-       struct nfs4acl *nfs4acl = NULL;
-       struct SMB4ACE_T *smbace = NULL;
-       bool have_special_id = false;
-       int i;
-
-       nfs4acl = talloc_zero(mem_ctx, struct nfs4acl);
-       if (nfs4acl == NULL) {
-               errno = ENOMEM;
-               return false;
-       }
-
-       nfs4acl->a_count = smb_get_naces(smbacl);
-
-       nfs4acl->ace = talloc_zero_array(nfs4acl, struct nfs4ace,
-                                        nfs4acl->a_count);
-       if (nfs4acl->ace == NULL) {
-               TALLOC_FREE(nfs4acl);
-               errno = ENOMEM;
-               return false;
-       }
-
-       for (smbace = smb_first_ace4(smbacl), i = 0;
-            smbace != NULL;
-            smbace = smb_next_ace4(smbace), i++)
-       {
-               SMB_ACE4PROP_T *aceprop = smb_get_ace4(smbace);
-
-               nfs4acl->ace[i].e_type        = aceprop->aceType;
-               nfs4acl->ace[i].e_flags       = aceprop->aceFlags;
-               nfs4acl->ace[i].e_mask        = aceprop->aceMask;
-               nfs4acl->ace[i].e_id          = aceprop->who.id;
-               if(aceprop->flags & SMB_ACE4_ID_SPECIAL) {
-                       switch(aceprop->who.special_id) {
-                       case SMB_ACE4_WHO_EVERYONE:
-                               nfs4acl->ace[i].e_who =
-                                       NFS4ACL_XATTR_EVERYONE_WHO;
-                               break;
-                       case SMB_ACE4_WHO_OWNER:
-                               nfs4acl->ace[i].e_who =
-                                       NFS4ACL_XATTR_OWNER_WHO;
-                               break;
-                       case SMB_ACE4_WHO_GROUP:
-                               nfs4acl->ace[i].e_who =
-                                       NFS4ACL_XATTR_GROUP_WHO;
-                               break;
-                       default:
-                               DBG_DEBUG("unsupported special_id %d\n",
-                                         aceprop->who.special_id);
-                               continue; /* don't add it !!! */
-                       }
-                       have_special_id = true;
-               } else {
-                       nfs4acl->ace[i].e_who = "";
-               }
-       }
-
-       if (!have_special_id && denymissingspecial) {
-               TALLOC_FREE(nfs4acl);
-               errno = EACCES;
-               return false;
-       }
-
-       SMB_ASSERT(i == nfs4acl->a_count);
-
-       *_nfs4acl = nfs4acl;
-       return true;
-}
-
-static NTSTATUS nfs4acl_smb4acl_to_ndr_blob(vfs_handle_struct *handle,
-                                           TALLOC_CTX *mem_ctx,
-                                           struct SMB4ACL_T *smb4acl,
-                                           DATA_BLOB *_blob)
-{
-       struct nfs4acl *nfs4acl = NULL;
-       DATA_BLOB blob;
-       bool denymissingspecial;
-       bool ok;
-
-       denymissingspecial = lp_parm_bool(SNUM(handle->conn),
-                                         "nfs4acl_xattr",
-                                         "denymissingspecial", false);
-
-       ok = nfs4acl_smb4acl2nfs4acl(talloc_tos(), smb4acl, &nfs4acl,
-                                    denymissingspecial);
-       if (!ok) {
-               DBG_ERR("Failed to convert smb ACL to nfs4 ACL.\n");
-               return NT_STATUS_INTERNAL_ERROR;
-       }
-
-       blob = nfs4acl_acl2blob(mem_ctx, nfs4acl);
-       TALLOC_FREE(nfs4acl);
-       if (blob.data == NULL) {
-               DBG_ERR("Failed to convert ACL to linear blob for xattr\n");
-               return NT_STATUS_INTERNAL_ERROR;
-       }
-
-       *_blob = blob;
-       return NT_STATUS_OK;
-}
-
 static NTSTATUS nfs4acl_xattr_default_sd(
        struct vfs_handle_struct *handle,
        const struct smb_filename *smb_fname,
index b9f2b9da25ccd94105e68c04487d9f9f59596538..6943d474826a662e64f864605f8f07d021ff3633 100644 (file)
@@ -219,7 +219,7 @@ bld.SAMBA3_MODULE('vfs_zfsacl',
 
 bld.SAMBA3_MODULE('vfs_nfs4acl_xattr',
                   subsystem='vfs',
-                  source='vfs_nfs4acl_xattr.c',
+                  source='vfs_nfs4acl_xattr.c nfs4acl_xattr_ndr.c',
                   deps='NFS4_ACLS sunacl NDR_NFS4ACL',
                   init_function='',
                   internal_module=bld.SAMBA3_IS_STATIC_MODULE('vfs_nfs4acl_xattr'),