[SCM] Samba Shared Repository - branch v3-3-test updated - release-3-2-0pre2-4354-g10d07c7

Jeremy Allison jra at samba.org
Tue Nov 11 01:59:12 GMT 2008


The branch, v3-3-test has been updated
       via  10d07c79dea075e62f4e9fdec3abd63996fec08c (commit)
      from  6e8daac76fd3df05f9ab81ced95748b46ea01a62 (commit)

http://gitweb.samba.org/?p=samba.git;a=shortlog;h=v3-3-test


- Log -----------------------------------------------------------------
commit 10d07c79dea075e62f4e9fdec3abd63996fec08c
Author: Jeremy Allison <jra at samba.org>
Date:   Mon Nov 10 17:58:09 2008 -0800

    Added vfs_acl_tdb.c module to do ACLs completely in userspace. Passes all of RAW-ACLS except for the last test which uses a non-POSIX chown. More testing/documentation to follow.
    Jeremy.

-----------------------------------------------------------------------

Summary of changes:
 source/Makefile.in                                |    5 +
 source/configure.in                               |    3 +-
 source/modules/{vfs_acl_xattr.c => vfs_acl_tdb.c} |  452 +++++++++++++++------
 source/modules/vfs_acl_xattr.c                    |   98 +++--
 4 files changed, 394 insertions(+), 164 deletions(-)
 copy source/modules/{vfs_acl_xattr.c => vfs_acl_tdb.c} (60%)


Changeset truncated at 500 lines:

diff --git a/source/Makefile.in b/source/Makefile.in
index a203e6a..ac03204 100644
--- a/source/Makefile.in
+++ b/source/Makefile.in
@@ -626,6 +626,7 @@ VFS_FILEID_OBJ = modules/vfs_fileid.o
 VFS_AIO_FORK_OBJ = modules/vfs_aio_fork.o
 VFS_SYNCOPS_OBJ = modules/vfs_syncops.o
 VFS_ACL_XATTR_OBJ = modules/vfs_acl_xattr.o
+VFS_ACL_TDB_OBJ = modules/vfs_acl_tdb.o
 VFS_SMB_TRAFFIC_ANALYZER_OBJ = modules/vfs_smb_traffic_analyzer.o
 
 PLAINTEXT_AUTH_OBJ = auth/pampass.o auth/pass_check.o
@@ -2413,6 +2414,10 @@ bin/acl_xattr. at SHLIBEXT@: $(BINARY_PREREQS) $(VFS_ACL_XATTR_OBJ)
 	@echo "Building plugin $@"
 	@$(SHLD_MODULE) $(VFS_ACL_XATTR_OBJ)
 
+bin/acl_tdb. at SHLIBEXT@: $(BINARY_PREREQS) $(VFS_ACL_TDB_OBJ)
+	@echo "Building plugin $@"
+	@$(SHLD_MODULE) $(VFS_ACL_TDB_OBJ)
+
 bin/registry. at SHLIBEXT@: $(BINARY_PREREQS) libgpo/gpext/registry.o
 	@echo "Building plugin $@"
 	@$(SHLD_MODULE) libgpo/gpext/registry.o
diff --git a/source/configure.in b/source/configure.in
index 40e6fb3..95ddb67 100644
--- a/source/configure.in
+++ b/source/configure.in
@@ -409,7 +409,7 @@ dnl These have to be built static:
 default_static_modules="pdb_smbpasswd pdb_tdbsam rpc_lsarpc rpc_samr rpc_winreg rpc_initshutdown rpc_dssetup rpc_wkssvc rpc_svcctl2 rpc_ntsvcs2 rpc_netlogon rpc_netdfs rpc_srvsvc rpc_spoolss rpc_eventlog2 auth_sam auth_unix auth_winbind auth_server auth_domain auth_builtin vfs_default nss_info_template"
 
 dnl These are preferably build shared, and static if dlopen() is not available
-default_shared_modules="vfs_recycle vfs_audit vfs_extd_audit vfs_full_audit vfs_netatalk vfs_fake_perms vfs_default_quota vfs_readonly vfs_cap vfs_expand_msdfs vfs_shadow_copy vfs_shadow_copy2 charset_CP850 charset_CP437 auth_script vfs_readahead vfs_xattr_tdb vfs_streams_xattr vfs_acl_xattr vfs_smb_traffic_analyzer"
+default_shared_modules="vfs_recycle vfs_audit vfs_extd_audit vfs_full_audit vfs_netatalk vfs_fake_perms vfs_default_quota vfs_readonly vfs_cap vfs_expand_msdfs vfs_shadow_copy vfs_shadow_copy2 charset_CP850 charset_CP437 auth_script vfs_readahead vfs_xattr_tdb vfs_streams_xattr vfs_acl_xattr vfs_acl_tdb vfs_smb_traffic_analyzer"
 
 if test "x$developer" = xyes; then
    default_static_modules="$default_static_modules rpc_rpcecho"
@@ -6118,6 +6118,7 @@ SMB_MODULE(vfs_syncops, \$(VFS_SYNCOPS_OBJ), "bin/syncops.$SHLIBEXT", VFS)
 SMB_MODULE(vfs_zfsacl, \$(VFS_ZFSACL_OBJ), "bin/zfsacl.$SHLIBEXT", VFS)
 SMB_MODULE(vfs_notify_fam, \$(VFS_NOTIFY_FAM_OBJ), "bin/notify_fam.$SHLIBEXT", VFS)
 SMB_MODULE(vfs_acl_xattr, \$(VFS_ACL_XATTR_OBJ), "bin/acl_xattr.$SHLIBEXT", VFS)
+SMB_MODULE(vfs_acl_tdb, \$(VFS_ACL_TDB_OBJ), "bin/acl_tdb.$SHLIBEXT", VFS)
 SMB_MODULE(vfs_smb_traffic_analyzer, \$(VFS_SMB_TRAFFIC_ANALYZER_OBJ), "bin/smb_traffic_analyzer.$SHLIBEXT", VFS)
 
 
diff --git a/source/modules/vfs_acl_xattr.c b/source/modules/vfs_acl_tdb.c
similarity index 60%
copy from source/modules/vfs_acl_xattr.c
copy to source/modules/vfs_acl_tdb.c
index 6f1c1a3..be49bb7 100644
--- a/source/modules/vfs_acl_xattr.c
+++ b/source/modules/vfs_acl_tdb.c
@@ -1,5 +1,5 @@
 /*
- * Store Windows ACLs in xattrs.
+ * Store Windows ACLs in xattrs, or a tdb if configured that way.
  *
  * Copyright (C) Volker Lendecke, 2008
  * Copyright (C) Jeremy Allison, 2008
@@ -27,8 +27,83 @@
 #undef DBGC_CLASS
 #define DBGC_CLASS DBGC_VFS
 
+static unsigned int ref_count;
+static struct db_context *acl_db;
+
+/*******************************************************************
+ Open acl_db if not already open, increment ref count.
+*******************************************************************/
+
+static bool acl_tdb_init(struct db_context **pp_db)
+{
+	const char *dbname;
+
+	if (acl_db) {
+		*pp_db = acl_db;
+		ref_count++;
+		return true;
+	}
+
+	dbname = lock_path("file_ntacls.tdb");
+
+	if (dbname == NULL) {
+		errno = ENOSYS;
+		return false;
+	}
+
+	become_root();
+	*pp_db = db_open(NULL, dbname, 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600);
+	unbecome_root();
+
+	if (*pp_db == NULL) {
+#if defined(ENOTSUP)
+		errno = ENOTSUP;
+#else
+		errno = ENOSYS;
+#endif
+		return false;
+	}
+
+	ref_count++;
+	return true;
+}
+
+/*******************************************************************
+ Lower ref count and close acl_db if zero.
+*******************************************************************/
+
+static void free_acl_xattr_data(void **pptr)
+{
+	struct db_context **pp_db = (struct db_context **)pptr;
+
+	ref_count--;
+	if (ref_count == 0) {
+		TALLOC_FREE(*pp_db);
+		acl_db = NULL;
+	}
+}
+
+/*******************************************************************
+ Fetch_lock the tdb acl record for a file
+*******************************************************************/
+
+static struct db_record *acl_xattr_tdb_lock(TALLOC_CTX *mem_ctx,
+					struct db_context *db,
+					const struct file_id *id)
+{
+	uint8 id_buf[16];
+	push_file_id_16((char *)id_buf, id);
+	return db->fetch_locked(db,
+				mem_ctx,
+				make_tdb_data(id_buf,
+					sizeof(id_buf)));
+}
+
+/*******************************************************************
+ Parse out a struct security_descriptor from a DATA_BLOB.
+*******************************************************************/
+
 static NTSTATUS parse_acl_blob(const DATA_BLOB *pblob,
-				const struct timespec cts,
 				uint32 security_info,
 				struct security_descriptor **ppdesc)
 {
@@ -50,30 +125,6 @@ static NTSTATUS parse_acl_blob(const DATA_BLOB *pblob,
 		return NT_STATUS_REVISION_MISMATCH;
 	}
 
-#if 0
-	{
-		struct timespec ts;
-		/* Arg. This doesn't work. Too many activities
-		 * change the ctime. May have to roll back to
-		 * version 1.
-		 */
-		/*
-		 * Check that the ctime timestamp is ealier
-		 * than the stored timestamp.
-		 */
-
-		ts = nt_time_to_unix_timespec(&xacl.info.sd_ts->last_changed);
-
-		if (timespec_compare(&cts, &ts) > 0) {
-			DEBUG(5, ("parse_acl_blob: stored ACL out of date "
-				"(%s > %s.\n",
-				timestring(ctx, cts.tv_sec),
-				timestring(ctx, ts.tv_sec)));
-			return NT_STATUS_EA_CORRUPT_ERROR;
-		}
-	}
-#endif
-
 	*ppdesc = make_sec_desc(ctx, SEC_DESC_REVISION, xacl.info.sd_ts->sd->type | SEC_DESC_SELF_RELATIVE,
 			(security_info & OWNER_SECURITY_INFORMATION)
 			? xacl.info.sd_ts->sd->owner_sid : NULL,
@@ -90,60 +141,61 @@ static NTSTATUS parse_acl_blob(const DATA_BLOB *pblob,
 	return (*ppdesc != NULL) ? NT_STATUS_OK : NT_STATUS_NO_MEMORY;
 }
 
+/*******************************************************************
+ Pull a security descriptor into a DATA_BLOB from a tdb store.
+*******************************************************************/
+
 static NTSTATUS get_acl_blob(TALLOC_CTX *ctx,
 			vfs_handle_struct *handle,
 			files_struct *fsp,
 			const char *name,
 			DATA_BLOB *pblob)
 {
-	size_t size = 1024;
-	uint8_t *val = NULL;
-	uint8_t *tmp;
-	ssize_t sizeret;
-	int saved_errno = 0;
-
-	ZERO_STRUCTP(pblob);
-
-  again:
+	uint8 id_buf[16];
+	TDB_DATA data;
+	struct file_id id;
+	struct db_context *db;
+	SMB_STRUCT_STAT sbuf;
 
-	tmp = TALLOC_REALLOC_ARRAY(ctx, val, uint8_t, size);
-	if (tmp == NULL) {
-		TALLOC_FREE(val);
-		return NT_STATUS_NO_MEMORY;
-	}
-	val = tmp;
+	SMB_VFS_HANDLE_GET_DATA(handle, db, struct db_context,
+		return NT_STATUS_INTERNAL_DB_CORRUPTION);
 
-	become_root();
 	if (fsp && fsp->fh->fd != -1) {
-		sizeret = SMB_VFS_FGETXATTR(fsp, XATTR_NTACL_NAME, val, size);
+		if (SMB_VFS_FSTAT(fsp, &sbuf) == -1) {
+			return map_nt_error_from_unix(errno);
+		}
 	} else {
-		sizeret = SMB_VFS_GETXATTR(handle->conn, name,
-					XATTR_NTACL_NAME, val, size);
-	}
-	if (sizeret == -1) {
-		saved_errno = errno;
+		if (SMB_VFS_STAT(handle->conn, name, &sbuf) == -1) {
+			return map_nt_error_from_unix(errno);
+		}
 	}
-	unbecome_root();
+	id = vfs_file_id_from_sbuf(handle->conn, &sbuf);
 
-	/* Max ACL size is 65536 bytes. */
-	if (sizeret == -1) {
-		errno = saved_errno;
-		if ((errno == ERANGE) && (size != 65536)) {
-			/* Too small, try again. */
-			size = 65536;
-			goto again;
-		}
+	push_file_id_16((char *)id_buf, &id);
 
-		/* Real error - exit here. */
-		TALLOC_FREE(val);
-		return map_nt_error_from_unix(errno);
+	if (db->fetch(db,
+			ctx,
+			make_tdb_data(id_buf, sizeof(id_buf)),
+			&data) == -1) {
+		return NT_STATUS_INTERNAL_DB_CORRUPTION;
 	}
 
-	pblob->data = val;
-	pblob->length = sizeret;
+	pblob->data = data.dptr;
+	pblob->length = data.dsize;
+
+	DEBUG(10,("get_acl_blob: returned %u bytes from file %s\n",
+		(unsigned int)data.dsize, name ));
+
+	if (pblob->length == 0 || pblob->data == NULL) {
+		return NT_STATUS_OBJECT_NAME_NOT_FOUND;
+	}
 	return NT_STATUS_OK;
 }
 
+/*******************************************************************
+ Create a DATA_BLOB from a security descriptor.
+*******************************************************************/
+
 static NTSTATUS create_acl_blob(const struct security_descriptor *psd, DATA_BLOB *pblob)
 {
 	struct xattr_NTACL xacl;
@@ -182,69 +234,95 @@ static NTSTATUS create_acl_blob(const struct security_descriptor *psd, DATA_BLOB
 	return NT_STATUS_OK;
 }
 
-static NTSTATUS store_acl_blob_fsp(files_struct *fsp,
+/*******************************************************************
+ Store a DATA_BLOB into a tdb record given an fsp pointer.
+*******************************************************************/
+
+static NTSTATUS store_acl_blob_fsp(vfs_handle_struct *handle,
+				files_struct *fsp,
 				DATA_BLOB *pblob)
 {
-	int ret;
-	int saved_errno = 0;
+	uint8 id_buf[16];
+	struct file_id id;
+	SMB_STRUCT_STAT sbuf;
+	TDB_DATA data;
+	struct db_context *db;
+	struct db_record *rec;
 
 	DEBUG(10,("store_acl_blob_fsp: storing blob length %u on file %s\n",
 			(unsigned int)pblob->length, fsp->fsp_name));
 
-	become_root();
+	SMB_VFS_HANDLE_GET_DATA(handle, db, struct db_context,
+		return NT_STATUS_INTERNAL_DB_CORRUPTION);
+
 	if (fsp->fh->fd != -1) {
-		ret = SMB_VFS_FSETXATTR(fsp, XATTR_NTACL_NAME,
-			pblob->data, pblob->length, 0);
+		if (SMB_VFS_FSTAT(fsp, &sbuf) == -1) {
+			return map_nt_error_from_unix(errno);
+		}
 	} else {
-		ret = SMB_VFS_SETXATTR(fsp->conn, fsp->fsp_name,
-				XATTR_NTACL_NAME,
-				pblob->data, pblob->length, 0);
-	}
-	if (ret) {
-		saved_errno = errno;
+		if (SMB_VFS_STAT(handle->conn, fsp->fsp_name, &sbuf) == -1) {
+			return map_nt_error_from_unix(errno);
+		}
 	}
-	unbecome_root();
-	if (ret) {
-		errno = saved_errno;
-		DEBUG(5, ("store_acl_blob_fsp: setting attr failed for file %s"
-			"with error %s\n",
-			fsp->fsp_name,
-			strerror(errno) ));
-		return map_nt_error_from_unix(errno);
+	id = vfs_file_id_from_sbuf(handle->conn, &sbuf);
+
+	push_file_id_16((char *)id_buf, &id);
+	rec = db->fetch_locked(db, talloc_tos(),
+				make_tdb_data(id_buf,
+					sizeof(id_buf)));
+	if (rec == NULL) {
+		DEBUG(0, ("store_acl_blob_fsp_tdb: fetch_lock failed\n"));
+		return NT_STATUS_INTERNAL_DB_CORRUPTION;
 	}
-	return NT_STATUS_OK;
+	data.dptr = pblob->data;
+	data.dsize = pblob->length;
+	return rec->store(rec, data, 0);
 }
 
-static NTSTATUS store_acl_blob_pathname(connection_struct *conn,
+/*******************************************************************
+ Store a DATA_BLOB into a tdb record given a pathname.
+*******************************************************************/
+
+static NTSTATUS store_acl_blob_pathname(vfs_handle_struct *handle,
 					const char *fname,
 					DATA_BLOB *pblob)
 {
-	int ret;
-	int saved_errno = 0;
+	uint8 id_buf[16];
+	struct file_id id;
+	TDB_DATA data;
+	SMB_STRUCT_STAT sbuf;
+	struct db_context *db;
+	struct db_record *rec;
 
 	DEBUG(10,("store_acl_blob_pathname: storing blob "
 			"length %u on file %s\n",
 			(unsigned int)pblob->length, fname));
 
-	become_root();
-	ret = SMB_VFS_SETXATTR(conn, fname,
-				XATTR_NTACL_NAME,
-				pblob->data, pblob->length, 0);
-	if (ret) {
-		saved_errno = errno;
-	}
-	unbecome_root();
-	if (ret) {
-		errno = saved_errno;
-		DEBUG(5, ("store_acl_blob_pathname: setting attr failed "
-			"for file %s with error %s\n",
-			fname,
-			strerror(errno) ));
+	SMB_VFS_HANDLE_GET_DATA(handle, db, struct db_context,
+		return NT_STATUS_INTERNAL_DB_CORRUPTION);
+
+	if (SMB_VFS_STAT(handle->conn, fname, &sbuf) == -1) {
 		return map_nt_error_from_unix(errno);
 	}
-	return NT_STATUS_OK;
+
+	id = vfs_file_id_from_sbuf(handle->conn, &sbuf);
+	push_file_id_16((char *)id_buf, &id);
+
+	rec = db->fetch_locked(db, talloc_tos(),
+				make_tdb_data(id_buf,
+					sizeof(id_buf)));
+	if (rec == NULL) {
+		DEBUG(0, ("store_acl_blob_pathname_tdb: fetch_lock failed\n"));
+		return NT_STATUS_INTERNAL_DB_CORRUPTION;
+	}
+	data.dptr = pblob->data;
+	data.dsize = pblob->length;
+	return rec->store(rec, data, 0);
 }
 
+/*******************************************************************
+ Store a DATA_BLOB into an xattr given a pathname.
+*******************************************************************/
 
 static NTSTATUS get_nt_acl_xattr_internal(vfs_handle_struct *handle,
 					files_struct *fsp,
@@ -254,7 +332,6 @@ static NTSTATUS get_nt_acl_xattr_internal(vfs_handle_struct *handle,
 {
 	TALLOC_CTX *ctx = talloc_tos();
 	DATA_BLOB blob;
-	SMB_STRUCT_STAT sbuf;
 	NTSTATUS status;
 
 	if (fsp && name == NULL) {
@@ -269,18 +346,7 @@ static NTSTATUS get_nt_acl_xattr_internal(vfs_handle_struct *handle,
 		return status;
 	}
 
-	if (fsp && fsp->fh->fd != -1) {
-		if (SMB_VFS_FSTAT(fsp, &sbuf) == -1) {
-			return map_nt_error_from_unix(errno);
-		}
-	} else {
-		if (SMB_VFS_STAT(handle->conn, name, &sbuf) == -1) {
-			return map_nt_error_from_unix(errno);
-		}
-	}
-
-	status = parse_acl_blob(&blob, get_ctimespec(&sbuf),
-			security_info, ppdesc);
+	status = parse_acl_blob(&blob, security_info, ppdesc);
 	if (!NT_STATUS_IS_OK(status)) {
 		DEBUG(10, ("parse_acl_blob returned %s\n",
 				nt_errstr(status)));
@@ -427,9 +493,9 @@ static NTSTATUS inherit_new_acl(vfs_handle_struct *handle,
 		return status;
 	}
 	if (fsp) {
-		return store_acl_blob_fsp(fsp, &blob);
+		return store_acl_blob_fsp(handle, fsp, &blob);
 	} else {
-		return store_acl_blob_pathname(handle->conn, fname, &blob);
+		return store_acl_blob_pathname(handle, fname, &blob);
 	}
 }
 
@@ -487,6 +553,55 @@ static int open_acl_xattr(vfs_handle_struct *handle,
 	return fsp->fh->fd;
 }
 
+/*********************************************************************
+ On unlink we need to delete the tdb record (if using tdb).
+*********************************************************************/
+
+static int unlink_acl_xattr(vfs_handle_struct *handle, const char *path)
+{
+	SMB_STRUCT_STAT sbuf;
+	struct file_id id;
+	struct db_context *db;
+	struct db_record *rec;
+	int ret;
+
+	SMB_VFS_HANDLE_GET_DATA(handle, db, struct db_context, return -1);
+
+	if (SMB_VFS_STAT(handle->conn, path, &sbuf) == -1) {
+		return -1;
+	}
+
+	ret = SMB_VFS_NEXT_UNLINK(handle, path);
+
+	if (ret == -1) {
+		return -1;
+	}
+
+	id = vfs_file_id_from_sbuf(handle->conn, &sbuf);
+
+	rec = acl_xattr_tdb_lock(talloc_tos(), db, &id);
+
+	/*
+	 * If rec == NULL there's not much we can do about it
+	 */
+
+	if (rec == NULL) {
+		DEBUG(10,("unlink_acl_xattr: path %s rec == NULL\n",
+			path ));
+		TALLOC_FREE(rec);
+		return 0;
+	}
+
+	rec->delete_rec(rec);
+	TALLOC_FREE(rec);
+
+	return 0;
+}
+
+/*********************************************************************
+ Store an inherited SD on mkdir.
+*********************************************************************/
+


-- 
Samba Shared Repository


More information about the samba-cvs mailing list