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 <[EMAIL PROTECTED]>
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/[EMAIL PROTECTED]@: $(BINARY_PREREQS) 
$(VFS_ACL_XATTR_OBJ)
        @echo "Building plugin $@"
        @$(SHLD_MODULE) $(VFS_ACL_XATTR_OBJ)
 
+bin/[EMAIL PROTECTED]@: $(BINARY_PREREQS) $(VFS_ACL_TDB_OBJ)
+       @echo "Building plugin $@"
+       @$(SHLD_MODULE) $(VFS_ACL_TDB_OBJ)
+
 bin/[EMAIL PROTECTED]@: $(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

Reply via email to