[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