summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRalph Boehme <slow@samba.org>2017-10-17 12:02:53 +0200
committerJeremy Allison <jra@samba.org>2017-11-08 00:20:08 +0100
commitf5b2c66e44e9178ceef36630c9daabbc68ad4a57 (patch)
tree80279e05a612c799d7b8212c0e7e160f2ed6ef7e
parentd4d7e38bf6fcde3ef1fde6c5f83c4f5e983818e1 (diff)
downloadsamba-f5b2c66e44e9178ceef36630c9daabbc68ad4a57.tar.gz
vfs_nfs4acl_xattr: move the meat of the implementation to a seperate file
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>
-rw-r--r--source3/modules/nfs4acl_xattr_ndr.c241
-rw-r--r--source3/modules/nfs4acl_xattr_ndr.h42
-rw-r--r--source3/modules/vfs_nfs4acl_xattr.c203
-rw-r--r--source3/modules/wscript_build2
4 files changed, 285 insertions, 203 deletions
diff --git a/source3/modules/nfs4acl_xattr_ndr.c b/source3/modules/nfs4acl_xattr_ndr.c
new file mode 100644
index 00000000000..af100184c5f
--- /dev/null
+++ b/source3/modules/nfs4acl_xattr_ndr.c
@@ -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
index 00000000000..7db4ce734f5
--- /dev/null
+++ b/source3/modules/nfs4acl_xattr_ndr.h
@@ -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 */
diff --git a/source3/modules/vfs_nfs4acl_xattr.c b/source3/modules/vfs_nfs4acl_xattr.c
index b3b5e497061..b8ff28b75c0 100644
--- a/source3/modules/vfs_nfs4acl_xattr.c
+++ b/source3/modules/vfs_nfs4acl_xattr.c
@@ -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,
diff --git a/source3/modules/wscript_build b/source3/modules/wscript_build
index b9f2b9da25c..6943d474826 100644
--- a/source3/modules/wscript_build
+++ b/source3/modules/wscript_build
@@ -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'),