svn commit: samba r19199 - in branches/SAMBA_4_0/source/ntvfs/posix: .

tridge at samba.org tridge at samba.org
Mon Oct 9 11:13:50 GMT 2006


Author: tridge
Date: 2006-10-09 11:13:49 +0000 (Mon, 09 Oct 2006)
New Revision: 19199

WebSVN: http://websvn.samba.org/cgi-bin/viewcvs.cgi?view=rev&root=samba&rev=19199

Log:

split out the xattr NTACL code into a separate part of the posix
backend, allowing other ACL backends to be added. The xattr backend is
still the default backend

Added:
   branches/SAMBA_4_0/source/ntvfs/posix/pvfs_acl_xattr.c
Modified:
   branches/SAMBA_4_0/source/ntvfs/posix/config.mk
   branches/SAMBA_4_0/source/ntvfs/posix/pvfs_acl.c
   branches/SAMBA_4_0/source/ntvfs/posix/pvfs_xattr.c
   branches/SAMBA_4_0/source/ntvfs/posix/vfs_posix.c
   branches/SAMBA_4_0/source/ntvfs/posix/vfs_posix.h


Changeset:
Modified: branches/SAMBA_4_0/source/ntvfs/posix/config.mk
===================================================================
--- branches/SAMBA_4_0/source/ntvfs/posix/config.mk	2006-10-09 10:44:14 UTC (rev 19198)
+++ branches/SAMBA_4_0/source/ntvfs/posix/config.mk	2006-10-09 11:13:49 UTC (rev 19199)
@@ -1,4 +1,14 @@
 ################################################
+# Start MODULE pvfs_acl_xattr
+[MODULE::pvfs_acl_xattr]
+INIT_FUNCTION = pvfs_acl_xattr_init 
+SUBSYSTEM = ntvfs
+OBJ_FILES = \
+		pvfs_acl_xattr.o
+# End MODULE pvfs_acl_xattr
+################################################
+
+################################################
 # Start MODULE ntvfs_posix
 [MODULE::ntvfs_posix]
 SUBSYSTEM = ntvfs
@@ -32,6 +42,7 @@
 		pvfs_notify.o \
 		xattr_system.o \
 		xattr_tdb.o
+PRIVATE_DEPENDENCIES = pvfs_acl_xattr
 PUBLIC_DEPENDENCIES = NDR_XATTR WRAP_XATTR BLKID ntvfs_common MESSAGING
 # End MODULE ntvfs_posix
 ################################################

Modified: branches/SAMBA_4_0/source/ntvfs/posix/pvfs_acl.c
===================================================================
--- branches/SAMBA_4_0/source/ntvfs/posix/pvfs_acl.c	2006-10-09 10:44:14 UTC (rev 19198)
+++ branches/SAMBA_4_0/source/ntvfs/posix/pvfs_acl.c	2006-10-09 11:13:49 UTC (rev 19199)
@@ -27,7 +27,61 @@
 #include "libcli/security/security.h"
 
 
+/* the list of currently registered ACL backends */
+static struct pvfs_acl_backend {
+	const struct pvfs_acl_ops *ops;
+} *backends = NULL;
+static int num_backends;
+
 /*
+  register a pvfs acl backend. 
+
+  The 'name' can be later used by other backends to find the operations
+  structure for this backend.  
+*/
+_PUBLIC_ NTSTATUS pvfs_acl_register(const struct pvfs_acl_ops *ops)
+{
+	struct pvfs_acl_ops *new_ops;
+
+	if (pvfs_acl_backend_byname(ops->name) != NULL) {
+		DEBUG(0,("pvfs acl backend '%s' already registered\n", ops->name));
+		return NT_STATUS_OBJECT_NAME_COLLISION;
+	}
+
+	backends = talloc_realloc(talloc_autofree_context(), backends, struct pvfs_acl_backend, num_backends+1);
+	NT_STATUS_HAVE_NO_MEMORY(backends);
+
+	new_ops = talloc_memdup(backends, ops, sizeof(*ops));
+	new_ops->name = talloc_strdup(new_ops, ops->name);
+
+	backends[num_backends].ops = new_ops;
+
+	num_backends++;
+
+	DEBUG(3,("NTVFS backend '%s' registered\n", ops->name));
+
+	return NT_STATUS_OK;
+}
+
+
+/*
+  return the operations structure for a named backend
+*/
+_PUBLIC_ const struct pvfs_acl_ops *pvfs_acl_backend_byname(const char *name)
+{
+	int i;
+
+	for (i=0;i<num_backends;i++) {
+		if (strcmp(backends[i].ops->name, name) == 0) {
+			return backends[i].ops;
+		}
+	}
+
+	return NULL;
+}
+
+
+/*
   map a single access_mask from generic to specific bits for files/dirs
 */
 static uint32_t pvfs_translate_mask(uint32_t access_mask)
@@ -67,17 +121,18 @@
 static NTSTATUS pvfs_default_acl(struct pvfs_state *pvfs,
 				 struct ntvfs_request *req,
 				 struct pvfs_filename *name, int fd, 
-				 struct xattr_NTACL *acl)
+				 struct security_descriptor **psd)
 {
 	struct security_descriptor *sd;
 	NTSTATUS status;
 	struct security_ace ace;
 	mode_t mode;
 
-	sd = security_descriptor_initialise(req);
-	if (sd == NULL) {
+	*psd = security_descriptor_initialise(req);
+	if (*psd == NULL) {
 		return NT_STATUS_NO_MEMORY;
 	}
+	sd = *psd;
 
 	status = sidmap_uid_to_sid(pvfs->sidmap, sd, name->st.st_uid, &sd->owner_sid);
 	if (!NT_STATUS_IS_OK(status)) {
@@ -154,9 +209,6 @@
 	ace.access_mask = SEC_RIGHTS_FILE_ALL;
 	security_descriptor_dacl_add(sd, &ace);
 	
-	acl->version = 1;
-	acl->info.sd = sd;
-
 	return NT_STATUS_OK;
 }
 				 
@@ -190,36 +242,24 @@
 		      uint32_t access_mask,
 		      union smb_setfileinfo *info)
 {
-	struct xattr_NTACL *acl;
 	uint32_t secinfo_flags = info->set_secdesc.in.secinfo_flags;
 	struct security_descriptor *new_sd, *sd, orig_sd;
-	NTSTATUS status;
+	NTSTATUS status = NT_STATUS_NOT_FOUND;
 	uid_t old_uid = -1;
 	gid_t old_gid = -1;
 	uid_t new_uid = -1;
 	gid_t new_gid = -1;
 
-	acl = talloc(req, struct xattr_NTACL);
-	if (acl == NULL) {
-		return NT_STATUS_NO_MEMORY;
+	if (pvfs->acl_ops != NULL) {
+		status = pvfs->acl_ops->acl_load(pvfs, name, fd, req, &sd);
 	}
-
-	status = pvfs_acl_load(pvfs, name, fd, acl);
 	if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) {
-		status = pvfs_default_acl(pvfs, req, name, fd, acl);
+		status = pvfs_default_acl(pvfs, req, name, fd, &sd);
 	}
 	if (!NT_STATUS_IS_OK(status)) {
 		return status;
 	}
 
-	switch (acl->version) {
-	case 1:
-		sd = acl->info.sd;
-		break;
-	default:
-		return NT_STATUS_INVALID_ACL;
-	}
-
 	new_sd = info->set_secdesc.in.sd;
 	orig_sd = *sd;
 
@@ -286,8 +326,8 @@
 	/* we avoid saving if the sd is the same. This means when clients
 	   copy files and end up copying the default sd that we don't
 	   needlessly use xattrs */
-	if (!security_descriptor_equal(sd, &orig_sd)) {
-		status = pvfs_acl_save(pvfs, name, fd, acl);
+	if (!security_descriptor_equal(sd, &orig_sd) && pvfs->acl_ops) {
+		status = pvfs->acl_ops->acl_save(pvfs, name, fd, sd);
 	}
 
 	return status;
@@ -302,31 +342,19 @@
 			struct pvfs_filename *name, int fd, 
 			union smb_fileinfo *info)
 {
-	struct xattr_NTACL *acl;
-	NTSTATUS status;
+	NTSTATUS status = NT_STATUS_NOT_FOUND;
 	struct security_descriptor *sd;
 
-	acl = talloc(req, struct xattr_NTACL);
-	if (acl == NULL) {
-		return NT_STATUS_NO_MEMORY;
+	if (pvfs->acl_ops) {
+		status = pvfs->acl_ops->acl_load(pvfs, name, fd, req, &sd);
 	}
-
-	status = pvfs_acl_load(pvfs, name, fd, acl);
 	if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) {
-		status = pvfs_default_acl(pvfs, req, name, fd, acl);
+		status = pvfs_default_acl(pvfs, req, name, fd, &sd);
 	}
 	if (!NT_STATUS_IS_OK(status)) {
 		return status;
 	}
 
-	switch (acl->version) {
-	case 1:
-		sd = acl->info.sd;
-		break;
-	default:
-		return NT_STATUS_INVALID_ACL;
-	}
-
 	normalise_sd_flags(sd, info->query_secdesc.in.secinfo_flags);
 
 	info->query_secdesc.out.sd = sd;

Added: branches/SAMBA_4_0/source/ntvfs/posix/pvfs_acl_xattr.c
===================================================================
--- branches/SAMBA_4_0/source/ntvfs/posix/pvfs_acl_xattr.c	2006-10-09 10:44:14 UTC (rev 19198)
+++ branches/SAMBA_4_0/source/ntvfs/posix/pvfs_acl_xattr.c	2006-10-09 11:13:49 UTC (rev 19199)
@@ -0,0 +1,105 @@
+/* 
+   Unix SMB/CIFS implementation.
+
+   POSIX NTVFS backend - NT ACLs in xattrs
+
+   Copyright (C) Andrew Tridgell 2006
+
+   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 2 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, write to the Free Software
+   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "includes.h"
+#include "vfs_posix.h"
+#include "lib/util/unix_privs.h"
+#include "librpc/gen_ndr/ndr_xattr.h"
+
+/*
+  load the current ACL from extended attributes
+*/
+static NTSTATUS pvfs_acl_load_xattr(struct pvfs_state *pvfs, struct pvfs_filename *name, int fd,
+				    TALLOC_CTX *mem_ctx,
+				    struct security_descriptor **sd)
+{
+	NTSTATUS status;
+	struct xattr_NTACL *acl;
+
+	if (!(pvfs->flags & PVFS_FLAG_XATTR_ENABLE)) {
+		return NT_STATUS_NOT_FOUND;
+	}
+
+	acl = talloc_zero(mem_ctx, struct xattr_NTACL);
+	NT_STATUS_HAVE_NO_MEMORY(acl);
+
+	status = pvfs_xattr_ndr_load(pvfs, mem_ctx, name->full_name, fd, 
+				     XATTR_NTACL_NAME,
+				     acl, 
+				     (ndr_pull_flags_fn_t)ndr_pull_xattr_NTACL);
+
+	if (!NT_STATUS_IS_OK(status)) {
+		talloc_free(acl);
+		return status;
+	}
+
+	if (acl->version != 1) {
+		talloc_free(acl);
+		return NT_STATUS_INVALID_ACL;
+	}
+	
+	*sd = talloc_steal(mem_ctx, acl->info.sd);
+
+	return NT_STATUS_OK;
+}
+
+/*
+  save the acl for a file into filesystem xattr
+*/
+static NTSTATUS pvfs_acl_save_xattr(struct pvfs_state *pvfs, struct pvfs_filename *name, int fd,
+				    struct security_descriptor *sd)
+{
+	NTSTATUS status;
+	void *privs;
+	struct xattr_NTACL acl;
+
+	if (!(pvfs->flags & PVFS_FLAG_XATTR_ENABLE)) {
+		return NT_STATUS_OK;
+	}
+
+	acl.version = 1;
+	acl.info.sd = sd;
+
+	/* this xattr is in the "system" namespace, so we need
+	   admin privileges to set it */
+	privs = root_privileges();
+	status = pvfs_xattr_ndr_save(pvfs, name->full_name, fd, 
+				     XATTR_NTACL_NAME, 
+				     &acl, 
+				     (ndr_push_flags_fn_t)ndr_push_xattr_NTACL);
+	talloc_free(privs);
+	return status;
+}
+
+
+/*
+  initialise pvfs acl xattr backend
+*/
+NTSTATUS pvfs_acl_xattr_init(void)
+{
+	struct pvfs_acl_ops ops = {
+		.name = "xattr",
+		.acl_load = pvfs_acl_load_xattr,
+		.acl_save = pvfs_acl_save_xattr
+	};
+	return pvfs_acl_register(&ops);
+}

Modified: branches/SAMBA_4_0/source/ntvfs/posix/pvfs_xattr.c
===================================================================
--- branches/SAMBA_4_0/source/ntvfs/posix/pvfs_xattr.c	2006-10-09 10:44:14 UTC (rev 19198)
+++ branches/SAMBA_4_0/source/ntvfs/posix/pvfs_xattr.c	2006-10-09 11:13:49 UTC (rev 19199)
@@ -101,10 +101,10 @@
 /*
   load a NDR structure from a xattr
 */
-static NTSTATUS pvfs_xattr_ndr_load(struct pvfs_state *pvfs,
-				    TALLOC_CTX *mem_ctx,
-				    const char *fname, int fd, const char *attr_name,
-				    void *p, ndr_pull_flags_fn_t pull_fn)
+NTSTATUS pvfs_xattr_ndr_load(struct pvfs_state *pvfs,
+			     TALLOC_CTX *mem_ctx,
+			     const char *fname, int fd, const char *attr_name,
+			     void *p, void *pull_fn)
 {
 	NTSTATUS status;
 	DATA_BLOB blob;
@@ -116,7 +116,7 @@
 	}
 
 	/* pull the blob */
-	status = ndr_pull_struct_blob(&blob, mem_ctx, p, pull_fn);
+	status = ndr_pull_struct_blob(&blob, mem_ctx, p, (ndr_pull_flags_fn_t)pull_fn);
 
 	data_blob_free(&blob);
 
@@ -126,15 +126,15 @@
 /*
   save a NDR structure into a xattr
 */
-static NTSTATUS pvfs_xattr_ndr_save(struct pvfs_state *pvfs,
-				    const char *fname, int fd, const char *attr_name, 
-				    void *p, ndr_push_flags_fn_t push_fn)
+NTSTATUS pvfs_xattr_ndr_save(struct pvfs_state *pvfs,
+			     const char *fname, int fd, const char *attr_name, 
+			     void *p, void *push_fn)
 {
 	TALLOC_CTX *mem_ctx = talloc_new(NULL);
 	DATA_BLOB blob;
 	NTSTATUS status;
 
-	status = ndr_push_struct_blob(&blob, mem_ctx, p, push_fn);
+	status = ndr_push_struct_blob(&blob, mem_ctx, p, (ndr_push_flags_fn_t)push_fn);
 	if (!NT_STATUS_IS_OK(status)) {
 		talloc_free(mem_ctx);
 		return status;

Modified: branches/SAMBA_4_0/source/ntvfs/posix/vfs_posix.c
===================================================================
--- branches/SAMBA_4_0/source/ntvfs/posix/vfs_posix.c	2006-10-09 10:44:14 UTC (rev 19198)
+++ branches/SAMBA_4_0/source/ntvfs/posix/vfs_posix.c	2006-10-09 11:13:49 UTC (rev 19199)
@@ -113,6 +113,9 @@
 	if (pvfs->flags & PVFS_FLAG_XATTR_ENABLE) {
 		pvfs_xattr_probe(pvfs);
 	}
+
+	/* enable an ACL backend */
+	pvfs->acl_ops = pvfs_acl_backend_byname(share_string_option(scfg, PVFS_ACL, "xattr"));
 }
 
 static int pvfs_state_destructor(struct pvfs_state *pvfs)

Modified: branches/SAMBA_4_0/source/ntvfs/posix/vfs_posix.h
===================================================================
--- branches/SAMBA_4_0/source/ntvfs/posix/vfs_posix.h	2006-10-09 10:44:14 UTC (rev 19198)
+++ branches/SAMBA_4_0/source/ntvfs/posix/vfs_posix.h	2006-10-09 11:13:49 UTC (rev 19199)
@@ -83,6 +83,9 @@
 		const struct dom_sid *creator_owner;
 		const struct dom_sid *creator_group;		
 	} sid_cache;
+
+	/* the acl backend */
+	const struct pvfs_acl_ops *acl_ops;
 };
 
 /* this is the basic information needed about a file from the filesystem */
@@ -220,6 +223,7 @@
 #define PVFS_SHARE_DELAY		"posix:sharedelay"
 #define PVFS_ALLOCATION_ROUNDING	"posix:allocationrounding"
 #define PVFS_SEARCH_INACTIVITY		"posix:searchinactivity"
+#define PVFS_ACL			"posix:acl"
 
 #define PVFS_XATTR_DEFAULT			True
 #define PVFS_FAKE_OPLOCKS_DEFAULT		False
@@ -227,6 +231,13 @@
 #define PVFS_ALLOCATION_ROUNDING_DEFAULT	512
 #define PVFS_SEARCH_INACTIVITY_DEFAULT		300
 
+struct pvfs_acl_ops {
+	const char *name;
+	NTSTATUS (*acl_load)(struct pvfs_state *, struct pvfs_filename *, int , TALLOC_CTX *, 
+			     struct security_descriptor **);
+	NTSTATUS (*acl_save)(struct pvfs_state *, struct pvfs_filename *, int , struct security_descriptor *);
+};
+
 #include "ntvfs/posix/vfs_posix_proto.h"
 
 #endif /* _VFS_POSIX_H_ */



More information about the samba-cvs mailing list