[SCM] Samba Shared Repository - branch v3-2-test updated - initial-v3-2-test-1358-gb66ac85

Volker Lendecke vl at samba.org
Tue Jan 15 09:58:09 GMT 2008


The branch, v3-2-test has been updated
       via  b66ac8567c16f2c35fceceba2f858d5503620309 (commit)
       via  2036b4c5ad677b8a477b34b0f076febab0abff5e (commit)
      from  e6bd1395f2c1da7bcf1a31cdb297919ed6a15469 (commit)

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


- Log -----------------------------------------------------------------
commit b66ac8567c16f2c35fceceba2f858d5503620309
Author: Volker Lendecke <vl at samba.org>
Date:   Mon Jan 14 22:38:16 2008 +0100

    Fix some warnings -- Jeremy, please check

commit 2036b4c5ad677b8a477b34b0f076febab0abff5e
Author: Volker Lendecke <vl at sernet.de>
Date:   Mon Oct 22 18:14:57 2007 +0200

    Implement vfs_ea_tdb
    
    This is an option for file systems that do not implement xattrs: in
    lockdir/eas.tdb an array of xatts per inode is stored.
    
    It can not solve the problem that xattrs might reappear if a posix-level
    process deletes a file and happens to re-create it under the same name. On file
    systems with birthtime we might have a chance to detect this, but not with
    standard posix. A future version might put relief on file systems that do have
    xattrs but where these are severely limited in size/speed/whatever: We can put
    a simple marker as a native xattr, but the xattrs proper are stored in the tdb.
    
    Volker

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

Summary of changes:
 source/Makefile.in                   |    7 +-
 source/configure.in                  |    3 +-
 source/librpc/gen_ndr/ndr_xattr.c    |  102 +++++
 source/librpc/gen_ndr/ndr_xattr.h    |   16 +
 source/librpc/gen_ndr/xattr.h        |   18 +
 source/librpc/idl/xattr.idl          |   23 +
 source/modules/vfs_ea_tdb.c          |  736 ++++++++++++++++++++++++++++++++++
 source/script/tests/selftest.sh      |    1 +
 source/script/tests/test_posix_s3.sh |    2 +-
 source/utils/net_ads.c               |   11 +-
 source/utils/net_dns.c               |    3 +-
 11 files changed, 912 insertions(+), 10 deletions(-)
 create mode 100644 source/librpc/gen_ndr/ndr_xattr.c
 create mode 100644 source/librpc/gen_ndr/ndr_xattr.h
 create mode 100644 source/librpc/gen_ndr/xattr.h
 create mode 100644 source/librpc/idl/xattr.idl
 create mode 100644 source/modules/vfs_ea_tdb.c


Changeset truncated at 500 lines:

diff --git a/source/Makefile.in b/source/Makefile.in
index 3918d29..1d48055 100644
--- a/source/Makefile.in
+++ b/source/Makefile.in
@@ -503,6 +503,7 @@ VFS_CAP_OBJ = modules/vfs_cap.o
 VFS_EXPAND_MSDFS_OBJ = modules/vfs_expand_msdfs.o
 VFS_SHADOW_COPY_OBJ = modules/vfs_shadow_copy.o
 VFS_AFSACL_OBJ = modules/vfs_afsacl.o
+VFS_EA_TDB_OBJ = modules/vfs_ea_tdb.o librpc/gen_ndr/ndr_xattr.o
 VFS_POSIXACL_OBJ = modules/vfs_posixacl.o
 VFS_AIXACL_OBJ = modules/vfs_aixacl.o modules/vfs_aixacl_util.o
 VFS_AIXACL2_OBJ = modules/vfs_aixacl2.o modules/vfs_aixacl_util.o modules/nfs4_acls.o
@@ -1060,7 +1061,7 @@ modules: SHOWFLAGS $(MODULES)
 ## Perl IDL Compiler
 IDL_FILES = unixinfo.idl lsa.idl dfs.idl echo.idl winreg.idl initshutdown.idl \
 	srvsvc.idl svcctl.idl eventlog.idl wkssvc.idl netlogon.idl notify.idl \
-	epmapper.idl messaging.idl
+	epmapper.idl messaging.idl xattr.idl
 
 idl:
 	@IDL_FILES="$(IDL_FILES)" CPP="$(CPP)" PERL="$(PERL)" \
@@ -1684,6 +1685,10 @@ bin/afsacl. at SHLIBEXT@: $(BINARY_PREREQS) $(VFS_AFSACL_OBJ)
 	@echo "Building plugin $@"
 	@$(SHLD_MODULE) $(VFS_AFSACL_OBJ)
 
+bin/ea_tdb. at SHLIBEXT@: $(BINARY_PREREQS) $(VFS_EA_TDB_OBJ)
+	@echo "Building plugin $@"
+	@$(SHLD_MODULE) $(VFS_EA_TDB_OBJ)
+
 bin/posixacl. at SHLIBEXT@: $(BINARY_PREREQS) $(VFS_POSIXACL_OBJ)
 	@echo "Building plugin $@"
 	@$(SHLD_MODULE) $(VFS_POSIXACL_OBJ)
diff --git a/source/configure.in b/source/configure.in
index 98f5c45..4ddc644 100644
--- a/source/configure.in
+++ b/source/configure.in
@@ -707,7 +707,7 @@ dnl These have to be built static:
 default_static_modules="pdb_smbpasswd pdb_tdbsam rpc_lsa rpc_samr rpc_winreg rpc_initshutdown rpc_lsa_ds rpc_wkssvc rpc_svcctl2 rpc_ntsvcs rpc_net rpc_netdfs rpc_srvsvc2 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 charset_CP850 charset_CP437 auth_script vfs_readahead vfs_syncops"
+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 charset_CP850 charset_CP437 auth_script vfs_readahead vfs_syncops vfs_ea_tdb"
 
 if test "x$developer" = xyes; then
    default_static_modules="$default_static_modules rpc_rpcecho"
@@ -6489,6 +6489,7 @@ SMB_MODULE(vfs_cap, \$(VFS_CAP_OBJ), "bin/cap.$SHLIBEXT", VFS)
 SMB_MODULE(vfs_expand_msdfs, \$(VFS_EXPAND_MSDFS_OBJ), "bin/expand_msdfs.$SHLIBEXT", VFS)
 SMB_MODULE(vfs_shadow_copy, \$(VFS_SHADOW_COPY_OBJ), "bin/shadow_copy.$SHLIBEXT", VFS)
 SMB_MODULE(vfs_afsacl, \$(VFS_AFSACL_OBJ), "bin/afsacl.$SHLIBEXT", VFS)
+SMB_MODULE(vfs_ea_tdb, \$(VFS_EA_TDB_OBJ), "bin/ea_tdb.$SHLIBEXT", VFS)
 SMB_MODULE(vfs_posixacl, \$(VFS_POSIXACL_OBJ), "bin/posixacl.$SHLIBEXT", VFS)
 SMB_MODULE(vfs_aixacl, \$(VFS_AIXACL_OBJ), "bin/aixacl.$SHLIBEXT", VFS)
 SMB_MODULE(vfs_aixacl2, \$(VFS_AIXACL2_OBJ), "bin/aixacl2.$SHLIBEXT", VFS)
diff --git a/source/librpc/gen_ndr/ndr_xattr.c b/source/librpc/gen_ndr/ndr_xattr.c
new file mode 100644
index 0000000..29a31a1
--- /dev/null
+++ b/source/librpc/gen_ndr/ndr_xattr.c
@@ -0,0 +1,102 @@
+/* parser auto-generated by pidl */
+
+#include "includes.h"
+#include "librpc/gen_ndr/ndr_xattr.h"
+
+_PUBLIC_ enum ndr_err_code ndr_push_tdb_xattr(struct ndr_push *ndr, int ndr_flags, const struct tdb_xattr *r)
+{
+	if (ndr_flags & NDR_SCALARS) {
+		NDR_CHECK(ndr_push_align(ndr, 4));
+		{
+			uint32_t _flags_save_string = ndr->flags;
+			ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_UTF8|LIBNDR_FLAG_STR_NULLTERM);
+			NDR_CHECK(ndr_push_string(ndr, NDR_SCALARS, r->name));
+			ndr->flags = _flags_save_string;
+		}
+		NDR_CHECK(ndr_push_DATA_BLOB(ndr, NDR_SCALARS, r->value));
+	}
+	if (ndr_flags & NDR_BUFFERS) {
+	}
+	return NDR_ERR_SUCCESS;
+}
+
+_PUBLIC_ enum ndr_err_code ndr_pull_tdb_xattr(struct ndr_pull *ndr, int ndr_flags, struct tdb_xattr *r)
+{
+	if (ndr_flags & NDR_SCALARS) {
+		NDR_CHECK(ndr_pull_align(ndr, 4));
+		{
+			uint32_t _flags_save_string = ndr->flags;
+			ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_UTF8|LIBNDR_FLAG_STR_NULLTERM);
+			NDR_CHECK(ndr_pull_string(ndr, NDR_SCALARS, &r->name));
+			ndr->flags = _flags_save_string;
+		}
+		NDR_CHECK(ndr_pull_DATA_BLOB(ndr, NDR_SCALARS, &r->value));
+	}
+	if (ndr_flags & NDR_BUFFERS) {
+	}
+	return NDR_ERR_SUCCESS;
+}
+
+_PUBLIC_ void ndr_print_tdb_xattr(struct ndr_print *ndr, const char *name, const struct tdb_xattr *r)
+{
+	ndr_print_struct(ndr, name, "tdb_xattr");
+	ndr->depth++;
+	ndr_print_string(ndr, "name", r->name);
+	ndr_print_DATA_BLOB(ndr, "value", r->value);
+	ndr->depth--;
+}
+
+_PUBLIC_ enum ndr_err_code ndr_push_tdb_xattrs(struct ndr_push *ndr, int ndr_flags, const struct tdb_xattrs *r)
+{
+	uint32_t cntr_xattrs_0;
+	if (ndr_flags & NDR_SCALARS) {
+		NDR_CHECK(ndr_push_align(ndr, 4));
+		NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->num_xattrs));
+		for (cntr_xattrs_0 = 0; cntr_xattrs_0 < r->num_xattrs; cntr_xattrs_0++) {
+			NDR_CHECK(ndr_push_tdb_xattr(ndr, NDR_SCALARS, &r->xattrs[cntr_xattrs_0]));
+		}
+	}
+	if (ndr_flags & NDR_BUFFERS) {
+	}
+	return NDR_ERR_SUCCESS;
+}
+
+_PUBLIC_ enum ndr_err_code ndr_pull_tdb_xattrs(struct ndr_pull *ndr, int ndr_flags, struct tdb_xattrs *r)
+{
+	uint32_t cntr_xattrs_0;
+	TALLOC_CTX *_mem_save_xattrs_0;
+	if (ndr_flags & NDR_SCALARS) {
+		NDR_CHECK(ndr_pull_align(ndr, 4));
+		NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->num_xattrs));
+		NDR_PULL_ALLOC_N(ndr, r->xattrs, r->num_xattrs);
+		_mem_save_xattrs_0 = NDR_PULL_GET_MEM_CTX(ndr);
+		NDR_PULL_SET_MEM_CTX(ndr, r->xattrs, 0);
+		for (cntr_xattrs_0 = 0; cntr_xattrs_0 < r->num_xattrs; cntr_xattrs_0++) {
+			NDR_CHECK(ndr_pull_tdb_xattr(ndr, NDR_SCALARS, &r->xattrs[cntr_xattrs_0]));
+		}
+		NDR_PULL_SET_MEM_CTX(ndr, _mem_save_xattrs_0, 0);
+	}
+	if (ndr_flags & NDR_BUFFERS) {
+	}
+	return NDR_ERR_SUCCESS;
+}
+
+_PUBLIC_ void ndr_print_tdb_xattrs(struct ndr_print *ndr, const char *name, const struct tdb_xattrs *r)
+{
+	uint32_t cntr_xattrs_0;
+	ndr_print_struct(ndr, name, "tdb_xattrs");
+	ndr->depth++;
+	ndr_print_uint32(ndr, "num_xattrs", r->num_xattrs);
+	ndr->print(ndr, "%s: ARRAY(%d)", "xattrs", r->num_xattrs);
+	ndr->depth++;
+	for (cntr_xattrs_0=0;cntr_xattrs_0<r->num_xattrs;cntr_xattrs_0++) {
+		char *idx_0=NULL;
+		asprintf(&idx_0, "[%d]", cntr_xattrs_0);
+		if (idx_0) {
+			ndr_print_tdb_xattr(ndr, "xattrs", &r->xattrs[cntr_xattrs_0]);
+			free(idx_0);
+		}
+	}
+	ndr->depth--;
+	ndr->depth--;
+}
diff --git a/source/librpc/gen_ndr/ndr_xattr.h b/source/librpc/gen_ndr/ndr_xattr.h
new file mode 100644
index 0000000..a18477f
--- /dev/null
+++ b/source/librpc/gen_ndr/ndr_xattr.h
@@ -0,0 +1,16 @@
+/* header auto-generated by pidl */
+
+#include "librpc/ndr/libndr.h"
+#include "librpc/gen_ndr/xattr.h"
+
+#ifndef _HEADER_NDR_xattr
+#define _HEADER_NDR_xattr
+
+#define NDR_XATTR_CALL_COUNT (0)
+enum ndr_err_code ndr_push_tdb_xattr(struct ndr_push *ndr, int ndr_flags, const struct tdb_xattr *r);
+enum ndr_err_code ndr_pull_tdb_xattr(struct ndr_pull *ndr, int ndr_flags, struct tdb_xattr *r);
+void ndr_print_tdb_xattr(struct ndr_print *ndr, const char *name, const struct tdb_xattr *r);
+enum ndr_err_code ndr_push_tdb_xattrs(struct ndr_push *ndr, int ndr_flags, const struct tdb_xattrs *r);
+enum ndr_err_code ndr_pull_tdb_xattrs(struct ndr_pull *ndr, int ndr_flags, struct tdb_xattrs *r);
+void ndr_print_tdb_xattrs(struct ndr_print *ndr, const char *name, const struct tdb_xattrs *r);
+#endif /* _HEADER_NDR_xattr */
diff --git a/source/librpc/gen_ndr/xattr.h b/source/librpc/gen_ndr/xattr.h
new file mode 100644
index 0000000..ee30376
--- /dev/null
+++ b/source/librpc/gen_ndr/xattr.h
@@ -0,0 +1,18 @@
+/* header auto-generated by pidl */
+
+#include <stdint.h>
+
+#ifndef _HEADER_xattr
+#define _HEADER_xattr
+
+struct tdb_xattr {
+	const char * name;/* [flag(LIBNDR_FLAG_STR_UTF8|LIBNDR_FLAG_STR_NULLTERM)] */
+	DATA_BLOB value;
+}/* [public] */;
+
+struct tdb_xattrs {
+	uint32_t num_xattrs;
+	struct tdb_xattr *xattrs;
+}/* [public] */;
+
+#endif /* _HEADER_xattr */
diff --git a/source/librpc/idl/xattr.idl b/source/librpc/idl/xattr.idl
new file mode 100644
index 0000000..ec230a4
--- /dev/null
+++ b/source/librpc/idl/xattr.idl
@@ -0,0 +1,23 @@
+#include "idl_types.h"
+
+/*
+   IDL structures for xattrs
+*/
+
+[
+  pointer_default(unique)
+]
+interface xattr
+{
+	/* xattrs for file systems that don't have any */
+
+	typedef [public] struct {
+		utf8string name;
+		DATA_BLOB value;
+	} tdb_xattr;
+
+	typedef [public] struct {
+		uint32 num_xattrs;
+		tdb_xattr xattrs[num_xattrs];
+	} tdb_xattrs;
+}
diff --git a/source/modules/vfs_ea_tdb.c b/source/modules/vfs_ea_tdb.c
new file mode 100644
index 0000000..8cf04d7
--- /dev/null
+++ b/source/modules/vfs_ea_tdb.c
@@ -0,0 +1,736 @@
+/*
+ * Store posix-level xattrs in a tdb
+ *
+ * Copyright (C) Volker Lendecke, 2007
+ *
+ * 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 "librpc/gen_ndr/xattr.h"
+#include "librpc/gen_ndr/ndr_xattr.h"
+
+#undef DBGC_CLASS
+#define DBGC_CLASS DBGC_VFS
+
+/*
+ * unmarshall tdb_xattrs
+ */
+
+static NTSTATUS ea_tdb_pull_attrs(TALLOC_CTX *mem_ctx,
+				  const TDB_DATA *data,
+				  struct tdb_xattrs **presult)
+{
+	DATA_BLOB blob;
+	enum ndr_err_code ndr_err;
+	struct tdb_xattrs *result;
+
+	if (!(result = TALLOC_ZERO_P(mem_ctx, struct tdb_xattrs))) {
+		return NT_STATUS_NO_MEMORY;
+	}
+
+	if (data->dsize == 0) {
+		*presult = result;
+		return NT_STATUS_OK;
+	}
+
+	blob = data_blob_const(data->dptr, data->dsize);
+
+	ndr_err = ndr_pull_struct_blob(
+		&blob, result, result,
+		(ndr_pull_flags_fn_t)ndr_pull_tdb_xattrs);
+
+	if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+		DEBUG(0, ("ndr_pull_tdb_xattrs failed: %s\n",
+			  ndr_errstr(ndr_err)));
+		TALLOC_FREE(result);
+		return ndr_map_error2ntstatus(ndr_err);;
+	}
+
+	*presult = result;
+	return NT_STATUS_OK;
+}
+
+/*
+ * marshall tdb_xattrs
+ */
+
+static NTSTATUS ea_tdb_push_attrs(TALLOC_CTX *mem_ctx,
+				  const struct tdb_xattrs *attribs,
+				  TDB_DATA *data)
+{
+	DATA_BLOB blob;
+	enum ndr_err_code ndr_err;
+
+	ndr_err = ndr_push_struct_blob(
+		&blob, mem_ctx, attribs,
+		(ndr_push_flags_fn_t)ndr_push_tdb_xattrs);
+
+	if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+		DEBUG(0, ("ndr_push_tdb_xattrs failed: %s\n",
+			  ndr_errstr(ndr_err)));
+		return ndr_map_error2ntstatus(ndr_err);;
+	}
+
+	*data = make_tdb_data(blob.data, blob.length);
+	return NT_STATUS_OK;
+}
+
+/*
+ * Load tdb_xattrs for a file from the tdb
+ */
+
+static NTSTATUS ea_tdb_load_attrs(TALLOC_CTX *mem_ctx,
+				  struct db_context *db_ctx,
+				  const struct file_id *id,
+				  struct tdb_xattrs **presult)
+{
+	uint8 id_buf[16];
+	NTSTATUS status;
+	TDB_DATA data;
+
+	push_file_id_16((char *)id_buf, id);
+
+	if (db_ctx->fetch(db_ctx, mem_ctx,
+			  make_tdb_data(id_buf, sizeof(id_buf)),
+			  &data) == -1) {
+		return NT_STATUS_INTERNAL_DB_CORRUPTION;
+	}
+
+	status = ea_tdb_pull_attrs(mem_ctx, &data, presult);
+	TALLOC_FREE(data.dptr);
+	return NT_STATUS_OK;
+}
+
+/*
+ * fetch_lock the tdb_ea record for a file
+ */
+
+static struct db_record *ea_tdb_lock_attrs(TALLOC_CTX *mem_ctx,
+					   struct db_context *db_ctx,
+					   const struct file_id *id)
+{
+	uint8 id_buf[16];
+	push_file_id_16((char *)id_buf, id);
+	return db_ctx->fetch_locked(db_ctx, mem_ctx,
+				    make_tdb_data(id_buf, sizeof(id_buf)));
+}
+
+/*
+ * Save tdb_xattrs to a previously fetch_locked record
+ */
+
+static NTSTATUS ea_tdb_save_attrs(struct db_record *rec,
+				  const struct tdb_xattrs *attribs)
+{
+	TDB_DATA data;
+	NTSTATUS status;
+
+	status = ea_tdb_push_attrs(talloc_tos(), attribs, &data);
+
+	if (!NT_STATUS_IS_OK(status)) {
+		DEBUG(0, ("ea_tdb_push_attrs failed: %s\n",
+			  nt_errstr(status)));
+		return status;
+	}
+
+	status = rec->store(rec, data, 0);
+
+	TALLOC_FREE(data.dptr);
+
+	return status;
+}
+
+/*
+ * Worker routine for getxattr and fgetxattr
+ */
+
+static ssize_t ea_tdb_getattr(struct db_context *db_ctx,
+			      const struct file_id *id,
+			      const char *name, void *value, size_t size)
+{
+	struct tdb_xattrs *attribs;
+	uint32_t i;
+	ssize_t result = -1;
+	NTSTATUS status;
+
+	status = ea_tdb_load_attrs(talloc_tos(), db_ctx, id, &attribs);
+
+	if (!NT_STATUS_IS_OK(status)) {
+		DEBUG(10, ("ea_tdb_fetch_attrs failed: %s\n",
+			   nt_errstr(status)));
+		errno = EINVAL;
+		return -1;
+	}
+
+	for (i=0; i<attribs->num_xattrs; i++) {
+		if (strcmp(attribs->xattrs[i].name, name) == 0) {
+			break;
+		}
+	}
+
+	if (i == attribs->num_xattrs) {
+		errno = ENOATTR;
+		goto fail;
+	}
+
+	if (attribs->xattrs[i].value.length > size) {
+		errno = ERANGE;
+		goto fail;
+	}
+
+	memcpy(value, attribs->xattrs[i].value.data,
+	       attribs->xattrs[i].value.length);
+	result = attribs->xattrs[i].value.length;
+
+ fail:
+	TALLOC_FREE(attribs);
+	return result;
+}
+
+static ssize_t ea_tdb_getxattr(struct vfs_handle_struct *handle,
+			       const char *path, const char *name,
+			       void *value, size_t size)
+{
+	SMB_STRUCT_STAT sbuf;
+	struct file_id id;
+	struct db_context *db;
+
+	SMB_VFS_HANDLE_GET_DATA(handle, db, struct db_context, return -1);
+
+	if (SMB_VFS_STAT(handle->conn, path, &sbuf) == -1) {
+		return -1;
+	}
+
+	id = SMB_VFS_FILE_ID_CREATE(handle->conn, sbuf.st_dev, sbuf.st_ino);
+
+	return ea_tdb_getattr(db, &id, name, value, size);
+}
+
+static ssize_t ea_tdb_fgetxattr(struct vfs_handle_struct *handle,
+				struct files_struct *fsp,
+				const char *name, void *value, size_t size)
+{
+	SMB_STRUCT_STAT sbuf;
+	struct file_id id;
+	struct db_context *db;
+
+	SMB_VFS_HANDLE_GET_DATA(handle, db, struct db_context, return -1);
+
+	if (SMB_VFS_FSTAT(fsp, &sbuf) == -1) {
+		return -1;
+	}
+
+	id = SMB_VFS_FILE_ID_CREATE(handle->conn, sbuf.st_dev, sbuf.st_ino);
+
+	return ea_tdb_getattr(db, &id, name, value, size);
+}
+
+/*
+ * Worker routine for setxattr and fsetxattr
+ */
+
+static int ea_tdb_setattr(struct db_context *db_ctx,
+			  const struct file_id *id, const char *name,
+			  const void *value, size_t size, int flags)
+{
+	NTSTATUS status;
+	struct db_record *rec;
+	struct tdb_xattrs *attribs;
+	uint32_t i;
+
+	rec = ea_tdb_lock_attrs(talloc_tos(), db_ctx, id);
+
+	if (rec == NULL) {
+		DEBUG(0, ("ea_tdb_lock_attrs failed\n"));
+		errno = EINVAL;
+		return -1;


-- 
Samba Shared Repository


More information about the samba-cvs mailing list