summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source3/lib/xattr_tdb.c12
-rw-r--r--source3/lib/xattr_tdb.h3
-rw-r--r--source3/modules/vfs_xattr_tdb.c43
3 files changed, 47 insertions, 11 deletions
diff --git a/source3/lib/xattr_tdb.c b/source3/lib/xattr_tdb.c
index 21223f04b8..6f33163ed6 100644
--- a/source3/lib/xattr_tdb.c
+++ b/source3/lib/xattr_tdb.c
@@ -169,8 +169,9 @@ static NTSTATUS xattr_tdb_save_attrs(struct db_record *rec,
*/
ssize_t xattr_tdb_getattr(struct db_context *db_ctx,
+ TALLOC_CTX *mem_ctx,
const struct file_id *id,
- const char *name, void *value, size_t size)
+ const char *name, DATA_BLOB *blob)
{
struct tdb_xattrs *attribs;
uint32_t i;
@@ -200,13 +201,8 @@ ssize_t xattr_tdb_getattr(struct db_context *db_ctx,
goto fail;
}
- if (attribs->eas[i].value.length > size) {
- errno = ERANGE;
- goto fail;
- }
-
- memcpy(value, attribs->eas[i].value.data,
- attribs->eas[i].value.length);
+ *blob = attribs->eas[i].value;
+ talloc_steal(mem_ctx, blob->data);
result = attribs->eas[i].value.length;
fail:
diff --git a/source3/lib/xattr_tdb.h b/source3/lib/xattr_tdb.h
index 0a54833f51..03bc43a38c 100644
--- a/source3/lib/xattr_tdb.h
+++ b/source3/lib/xattr_tdb.h
@@ -26,8 +26,9 @@
/* The following definitions come from lib/util/xattr_tdb.c */
ssize_t xattr_tdb_getattr(struct db_context *db_ctx,
+ TALLOC_CTX *mem_ctx,
const struct file_id *id,
- const char *name, void *value, size_t size);
+ const char *name, DATA_BLOB *blob);
int xattr_tdb_setattr(struct db_context *db_ctx,
const struct file_id *id, const char *name,
const void *value, size_t size, int flags);
diff --git a/source3/modules/vfs_xattr_tdb.c b/source3/modules/vfs_xattr_tdb.c
index f5e5440e16..5c105b5194 100644
--- a/source3/modules/vfs_xattr_tdb.c
+++ b/source3/modules/vfs_xattr_tdb.c
@@ -34,16 +34,35 @@ static ssize_t xattr_tdb_getxattr(struct vfs_handle_struct *handle,
SMB_STRUCT_STAT sbuf;
struct file_id id;
struct db_context *db;
+ ssize_t xattr_size;
+ DATA_BLOB blob;
+ TALLOC_CTX *frame = talloc_stackframe();
+ if (!frame) {
+ errno = ENOMEM;
+ return -1;
+ }
SMB_VFS_HANDLE_GET_DATA(handle, db, struct db_context, return -1);
if (vfs_stat_smb_fname(handle->conn, path, &sbuf) == -1) {
+ TALLOC_FREE(frame);
return -1;
}
id = SMB_VFS_FILE_ID_CREATE(handle->conn, &sbuf);
- return xattr_tdb_getattr(db, &id, name, value, size);
+ xattr_size = xattr_tdb_getattr(db, frame, &id, name, &blob);
+ if (xattr_size < 0) {
+ TALLOC_FREE(frame);
+ return -1;
+ }
+ if (blob.length > size) {
+ TALLOC_FREE(frame);
+ errno = ERANGE;
+ return -1;
+ }
+ memcpy(value, blob.data, size);
+ return xattr_size;
}
static ssize_t xattr_tdb_fgetxattr(struct vfs_handle_struct *handle,
@@ -53,16 +72,36 @@ static ssize_t xattr_tdb_fgetxattr(struct vfs_handle_struct *handle,
SMB_STRUCT_STAT sbuf;
struct file_id id;
struct db_context *db;
+ ssize_t xattr_size;
+ DATA_BLOB blob;
+ TALLOC_CTX *frame = talloc_stackframe();
+ if (!frame) {
+ errno = ENOMEM;
+ return -1;
+ }
SMB_VFS_HANDLE_GET_DATA(handle, db, struct db_context, return -1);
if (SMB_VFS_FSTAT(fsp, &sbuf) == -1) {
+ TALLOC_FREE(frame);
return -1;
}
id = SMB_VFS_FILE_ID_CREATE(handle->conn, &sbuf);
- return xattr_tdb_getattr(db, &id, name, value, size);
+ xattr_size = xattr_tdb_getattr(db, frame, &id, name, &blob);
+ if (xattr_size < 0) {
+ TALLOC_FREE(frame);
+ return -1;
+ }
+ if (blob.length > size) {
+ TALLOC_FREE(frame);
+ errno = ERANGE;
+ return -1;
+ }
+ memcpy(value, blob.data, size);
+ TALLOC_FREE(frame);
+ return xattr_size;
}
static int xattr_tdb_setxattr(struct vfs_handle_struct *handle,