summaryrefslogtreecommitdiff
path: root/net/samba411/files/patch-source3_modules_vfs__streams__xattr.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/samba411/files/patch-source3_modules_vfs__streams__xattr.c')
-rw-r--r--net/samba411/files/patch-source3_modules_vfs__streams__xattr.c526
1 files changed, 0 insertions, 526 deletions
diff --git a/net/samba411/files/patch-source3_modules_vfs__streams__xattr.c b/net/samba411/files/patch-source3_modules_vfs__streams__xattr.c
deleted file mode 100644
index 59d79d9f76cd..000000000000
--- a/net/samba411/files/patch-source3_modules_vfs__streams__xattr.c
+++ /dev/null
@@ -1,526 +0,0 @@
---- source3/modules/vfs_streams_xattr.c.orig 2019-01-15 10:07:00 UTC
-+++ source3/modules/vfs_streams_xattr.c
-@@ -1,10 +1,10 @@
- /*
- * Store streams in xattrs
- *
-- * Copyright (C) Volker Lendecke, 2008
-+ * Copyright (C) Volker Lendecke, 2008
-+ * Copyright (C) Timur I. Bakeyev, 2017
- *
- * Partly based on James Peach's Darwin module, which is
-- *
- * Copyright (C) James Peach 2006-2007
- *
- * This program is free software; you can redistribute it and/or modify
-@@ -79,25 +79,79 @@ static SMB_INO_T stream_inode(const SMB_
- }
-
- static ssize_t get_xattr_size(connection_struct *conn,
-- const struct smb_filename *smb_fname,
-- const char *xattr_name)
-+ const struct smb_filename *smb_fname,
-+ const char *xattr_name)
- {
-- NTSTATUS status;
-- struct ea_struct ea;
- ssize_t result;
-
-- status = get_ea_value(talloc_tos(), conn, NULL, smb_fname,
-- xattr_name, &ea);
-+ result = SMB_VFS_GETXATTR(conn, smb_fname, xattr_name, NULL, 0);
-+ // ? -1
-+ return result;
-+}
-
-- if (!NT_STATUS_IS_OK(status)) {
-- return -1;
-+static NTSTATUS get_xattr_value(TALLOC_CTX *mem_ctx,
-+ connection_struct *conn,
-+ const struct smb_filename *smb_fname,
-+ const char *ea_name,
-+ struct ea_struct *pea)
-+{
-+ ssize_t attr_size;
-+
-+ attr_size = get_xattr_size(conn, smb_fname, ea_name);
-+
-+ if (attr_size == -1) {
-+ return map_nt_error_from_unix(errno);
- }
-
-- result = ea.value.length-1;
-- TALLOC_FREE(ea.value.data);
-- return result;
-+ pea->value = data_blob_talloc(mem_ctx, NULL, attr_size);
-+ /* We may have xattr of a 0 size */
-+ if(pea->value.data == NULL && attr_size) {
-+ DEBUG(5,
-+ ("get_xattr_value: for EA '%s' failed to allocate %lu bytes\n",
-+ ea_name, (unsigned long)attr_size)
-+ );
-+ return NT_STATUS_NO_MEMORY;
-+ }
-+
-+ attr_size = SMB_VFS_GETXATTR(conn, smb_fname, ea_name, pea->value.data, pea->value.length);
-+
-+ if (attr_size == -1) {
-+ return map_nt_error_from_unix(errno);
-+ }
-+
-+ if(pea->value.length != attr_size) {
-+ DEBUG(5,
-+ ("get_xattr_value: for EA '%s' requested %lu, read %lu bytes\n",
-+ ea_name, (unsigned long)pea->value.length, (unsigned long)attr_size)
-+ );
-+ return NT_STATUS_UNSUCCESSFUL;
-+ }
-+
-+ DEBUG(10,("get_xattr_value: EA '%s' is of length %lu\n", ea_name, (unsigned long)attr_size));
-+ /*
-+ * This can dump huge amount of data multiple times. For example
-+ * for 1Mb ADS and chunk size 64Kb the same 1Mb dump will be
-+ * logged 16 times!
-+ */
-+ dump_data(50, (uint8_t *)pea->value.data, pea->value.length);
-+
-+ pea->flags = 0;
-+ // ? user.
-+ if (strnequal(ea_name, "user.", 5)) {
-+ pea->name = talloc_strdup(mem_ctx, &ea_name[5]);
-+ } else {
-+ pea->name = talloc_strdup(mem_ctx, ea_name);
-+ }
-+
-+ if (pea->name == NULL) {
-+ data_blob_free(&pea->value);
-+ return NT_STATUS_NO_MEMORY;
-+ }
-+
-+ return NT_STATUS_OK;
- }
-
-+
- /**
- * Given a stream name, populate xattr_name with the xattr name to use for
- * accessing the stream.
-@@ -114,6 +168,7 @@ static NTSTATUS streams_xattr_get_name(v
- SMB_VFS_HANDLE_GET_DATA(handle, config, struct streams_xattr_config,
- return NT_STATUS_UNSUCCESSFUL);
-
-+ // stream_name is passed as ':stream', so skip leading ':'
- sname = talloc_strdup(ctx, stream_name + 1);
- if (sname == NULL) {
- return NT_STATUS_NO_MEMORY;
-@@ -125,7 +180,7 @@ static NTSTATUS streams_xattr_get_name(v
- * characters from their on-the-wire Unicode Private Range
- * encoding to their native ASCII representation.
- *
-- * As as result the name of xattrs storing the streams (via
-+ * As a result the name of xattrs storing the streams (via
- * vfs_streams_xattr) may contain a colon, so we have to use
- * strrchr_m() instead of strchr_m() for matching the stream
- * type suffix.
-@@ -157,7 +212,7 @@ static NTSTATUS streams_xattr_get_name(v
- return NT_STATUS_NO_MEMORY;
- }
-
-- DEBUG(10, ("xattr_name: %s, stream_name: %s\n", *xattr_name,
-+ DEBUG(10, ("xattr_name: '%s', stream_name: '%s'\n", *xattr_name,
- stream_name));
-
- talloc_free(sname);
-@@ -270,8 +325,8 @@ static int streams_xattr_fstat(vfs_handl
- return -1;
- }
-
-- sbuf->st_ex_size = get_xattr_size(handle->conn,
-- smb_fname_base, io->xattr_name);
-+ sbuf->st_ex_size = get_xattr_size(handle->conn, smb_fname_base,
-+ io->xattr_name);
- if (sbuf->st_ex_size == -1) {
- TALLOC_FREE(smb_fname_base);
- SET_STAT_INVALID(*sbuf);
-@@ -446,10 +501,10 @@ static int streams_xattr_open(vfs_handle
- goto fail;
- }
-
-- status = get_ea_value(talloc_tos(), handle->conn, NULL,
-- smb_fname, xattr_name, &ea);
-+ status = get_xattr_value(talloc_tos(), handle->conn,
-+ smb_fname, xattr_name, &ea);
-
-- DEBUG(10, ("get_ea_value returned %s\n", nt_errstr(status)));
-+ DEBUG(10, ("get_xattr_value returned %s\n", nt_errstr(status)));
-
- if (!NT_STATUS_IS_OK(status)) {
- if (!NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) {
-@@ -480,19 +535,13 @@ static int streams_xattr_open(vfs_handle
- /*
- * The attribute does not exist or needs to be truncated
- */
--
-- /*
-- * Darn, xattrs need at least 1 byte
-- */
-- char null = '\0';
--
- DEBUG(10, ("creating or truncating attribute %s on file %s\n",
- xattr_name, smb_fname->base_name));
-
- ret = SMB_VFS_SETXATTR(fsp->conn,
- smb_fname,
- xattr_name,
-- &null, sizeof(null),
-+ NULL, 0,
- flags & O_EXCL ? XATTR_CREATE : 0);
- if (ret != 0) {
- goto fail;
-@@ -678,8 +727,8 @@ static int streams_xattr_rename(vfs_hand
- }
-
- /* read the old stream */
-- status = get_ea_value(talloc_tos(), handle->conn, NULL,
-- smb_fname_src, src_xattr_name, &ea);
-+ status = get_xattr_value(talloc_tos(), handle->conn,
-+ smb_fname_src, src_xattr_name, &ea);
- if (!NT_STATUS_IS_OK(status)) {
- errno = ENOENT;
- goto fail;
-@@ -766,14 +815,13 @@ static NTSTATUS walk_xattr_streams(vfs_h
- continue;
- }
-
-- status = get_ea_value(names,
-+ status = get_xattr_value(names,
- handle->conn,
-- NULL,
- smb_fname,
- names[i],
- &ea);
- if (!NT_STATUS_IS_OK(status)) {
-- DEBUG(10, ("Could not get ea %s for file %s: %s\n",
-+ DEBUG(10, ("Could not get EA %s for file %s: %s\n",
- names[i],
- smb_fname->base_name,
- nt_errstr(status)));
-@@ -835,16 +883,17 @@ struct streaminfo_state {
- NTSTATUS status;
- };
-
--static bool collect_one_stream(struct ea_struct *ea, void *private_data)
-+static bool collect_one_stream(struct ea_struct *pea, void *private_data)
- {
- struct streaminfo_state *state =
- (struct streaminfo_state *)private_data;
-
-+ // ? -1
- if (!add_one_stream(state->mem_ctx,
- &state->num_streams, &state->streams,
-- ea->name, ea->value.length-1,
-+ pea->name, pea->value.length,
- smb_roundup(state->handle->conn,
-- ea->value.length-1))) {
-+ pea->value.length))) {
- state->status = NT_STATUS_NO_MEMORY;
- return false;
- }
-@@ -964,14 +1013,17 @@ static ssize_t streams_xattr_pwrite(vfs_
- files_struct *fsp, const void *data,
- size_t n, off_t offset)
- {
-- struct stream_io *sio =
-+ struct stream_io *sio =
- (struct stream_io *)VFS_FETCH_FSP_EXTENSION(handle, fsp);
-+ struct smb_filename *smb_fname_base = NULL;
-+ TALLOC_CTX *frame = NULL;
-+
- struct ea_struct ea;
- NTSTATUS status;
-- struct smb_filename *smb_fname_base = NULL;
- int ret;
-
-- DEBUG(10, ("streams_xattr_pwrite called for %d bytes\n", (int)n));
-+ DEBUG(10, ("streams_xattr_pwrite: offset=%lu, size=%lu\n",
-+ (unsigned long)offset, (unsigned long)n));
-
- if (sio == NULL) {
- return SMB_VFS_NEXT_PWRITE(handle, fsp, data, n, offset);
-@@ -981,6 +1033,8 @@ static ssize_t streams_xattr_pwrite(vfs_
- return -1;
- }
-
-+ frame = talloc_stackframe();
-+
- /* Create an smb_filename with stream_name == NULL. */
- smb_fname_base = synthetic_smb_fname(talloc_tos(),
- sio->base,
-@@ -988,39 +1042,55 @@ static ssize_t streams_xattr_pwrite(vfs_
- NULL,
- fsp->fsp_name->flags);
- if (smb_fname_base == NULL) {
-+ TALLOC_FREE(frame);
- errno = ENOMEM;
- return -1;
- }
-
-- status = get_ea_value(talloc_tos(), handle->conn, NULL,
-- smb_fname_base, sio->xattr_name, &ea);
-- if (!NT_STATUS_IS_OK(status)) {
-- return -1;
-- }
--
-- if ((offset + n) > ea.value.length-1) {
-- uint8_t *tmp;
-+ status = get_xattr_value(talloc_tos(), handle->conn,
-+ smb_fname_base, sio->xattr_name, &ea);
-
-- tmp = talloc_realloc(talloc_tos(), ea.value.data, uint8_t,
-- offset + n + 1);
-+ if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) {
-+ /*
-+ * This can happen if we sit behind vfs_fruit:
-+ * fruit_ftruncate calls UNLINK on an attribute
-+ * truncating the "file" to zero length. A later
-+ * pwrite faces a non-existing attribute, we need to
-+ * cope with that here.
-+ *
-+ * This might be not the last word on this.
-+ */
-
-- if (tmp == NULL) {
-- TALLOC_FREE(ea.value.data);
-- errno = ENOMEM;
-- return -1;
-- }
-- ea.value.data = tmp;
-- ea.value.length = offset + n + 1;
-- ea.value.data[offset+n] = 0;
-- }
-+ ea = (struct ea_struct) {0};
-+ ea.name = talloc_strdup(talloc_tos(), sio->xattr_name);
-+ if (ea.name == NULL) {
-+ TALLOC_FREE(frame);
-+ errno = ENOMEM;
-+ return -1;
-+ }
-+ status = NT_STATUS_OK;
-+ }
-
-- memcpy(ea.value.data + offset, data, n);
-+ if (!NT_STATUS_IS_OK(status)) {
-+ TALLOC_FREE(frame);
-+ return -1;
-+ }
-+ // ? -1
-+ if ((offset + n) > ea.value.length) {
-+ if(!data_blob_realloc(talloc_tos(), &ea.value, offset + n)) {
-+ TALLOC_FREE(frame);
-+ errno = ENOMEM;
-+ return -1;
-+ }
-+ }
-+ memcpy(ea.value.data + offset, data, n);
-
- ret = SMB_VFS_SETXATTR(fsp->conn,
- fsp->fsp_name,
- sio->xattr_name,
- ea.value.data, ea.value.length, 0);
-- TALLOC_FREE(ea.value.data);
-+
-+ TALLOC_FREE(frame);
-
- if (ret == -1) {
- return -1;
-@@ -1033,15 +1103,17 @@ static ssize_t streams_xattr_pread(vfs_h
- files_struct *fsp, void *data,
- size_t n, off_t offset)
- {
-- struct stream_io *sio =
-+ struct stream_io *sio =
- (struct stream_io *)VFS_FETCH_FSP_EXTENSION(handle, fsp);
-+ struct smb_filename *smb_fname_base = NULL;
-+ TALLOC_CTX *frame = NULL;
-+
- struct ea_struct ea;
- NTSTATUS status;
-- size_t length, overlap;
-- struct smb_filename *smb_fname_base = NULL;
-+ size_t overlap;
-
-- DEBUG(10, ("streams_xattr_pread: offset=%d, size=%d\n",
-- (int)offset, (int)n));
-+ DEBUG(10, ("streams_xattr_pread: offset=%lu, size=%lu\n",
-+ (unsigned long)offset, (unsigned long)n));
-
- if (sio == NULL) {
- return SMB_VFS_NEXT_PREAD(handle, fsp, data, n, offset);
-@@ -1051,6 +1123,8 @@ static ssize_t streams_xattr_pread(vfs_h
- return -1;
- }
-
-+ frame = talloc_stackframe();
-+
- /* Create an smb_filename with stream_name == NULL. */
- smb_fname_base = synthetic_smb_fname(talloc_tos(),
- sio->base,
-@@ -1058,31 +1132,35 @@ static ssize_t streams_xattr_pread(vfs_h
- NULL,
- fsp->fsp_name->flags);
- if (smb_fname_base == NULL) {
-+ TALLOC_FREE(frame);
- errno = ENOMEM;
- return -1;
- }
-
-- status = get_ea_value(talloc_tos(), handle->conn, NULL,
-- smb_fname_base, sio->xattr_name, &ea);
-+ status = get_xattr_value(talloc_tos(), handle->conn,
-+ smb_fname_base, sio->xattr_name, &ea);
- if (!NT_STATUS_IS_OK(status)) {
-+ TALLOC_FREE(frame);
- return -1;
- }
-+ // ? -1
-+ //length = ea.value.length-1;
-
-- length = ea.value.length-1;
-+ DEBUG(10, ("streams_xattr_pread: get_xattr_value() returned %lu bytes\n",
-+ (unsigned long)ea.value.length));
-
-- DEBUG(10, ("streams_xattr_pread: get_ea_value returned %d bytes\n",
-- (int)length));
-+ /* Attempt to read past EOF. */
-+ if (ea.value.length <= offset) {
-+ TALLOC_FREE(frame);
-+ return 0;
-+ }
-
-- /* Attempt to read past EOF. */
-- if (length <= offset) {
-- return 0;
-- }
-+ overlap = (offset + n) > ea.value.length ? (ea.value.length - offset) : n;
-+ memcpy(data, ea.value.data + offset, overlap);
-
-- overlap = (offset + n) > length ? (length - offset) : n;
-- memcpy(data, ea.value.data + offset, overlap);
-+ TALLOC_FREE(frame);
-
-- TALLOC_FREE(ea.value.data);
-- return overlap;
-+ return overlap;
- }
-
- struct streams_xattr_pread_state {
-@@ -1249,16 +1327,18 @@ static int streams_xattr_ftruncate(struc
- struct files_struct *fsp,
- off_t offset)
- {
-- int ret;
-- uint8_t *tmp;
-- struct ea_struct ea;
-- NTSTATUS status;
-- struct stream_io *sio =
-+ struct stream_io *sio =
- (struct stream_io *)VFS_FETCH_FSP_EXTENSION(handle, fsp);
- struct smb_filename *smb_fname_base = NULL;
-+ TALLOC_CTX *frame = NULL;
-
-- DEBUG(10, ("streams_xattr_ftruncate called for file %s offset %.0f\n",
-- fsp_str_dbg(fsp), (double)offset));
-+ struct ea_struct ea;
-+ NTSTATUS status;
-+ size_t orig_length;
-+ int ret;
-+
-+ DEBUG(10, ("streams_xattr_ftruncate: called for file '%s' with offset %lu\n",
-+ fsp_str_dbg(fsp), (unsigned long)offset));
-
- if (sio == NULL) {
- return SMB_VFS_NEXT_FTRUNCATE(handle, fsp, offset);
-@@ -1268,6 +1348,8 @@ static int streams_xattr_ftruncate(struc
- return -1;
- }
-
-+ frame = talloc_stackframe();
-+
- /* Create an smb_filename with stream_name == NULL. */
- smb_fname_base = synthetic_smb_fname(talloc_tos(),
- sio->base,
-@@ -1275,40 +1357,46 @@ static int streams_xattr_ftruncate(struc
- NULL,
- fsp->fsp_name->flags);
- if (smb_fname_base == NULL) {
-+ TALLOC_FREE(frame);
- errno = ENOMEM;
- return -1;
- }
-
-- status = get_ea_value(talloc_tos(), handle->conn, NULL,
-- smb_fname_base, sio->xattr_name, &ea);
-+ status = get_xattr_value(talloc_tos(), handle->conn,
-+ smb_fname_base, sio->xattr_name, &ea);
- if (!NT_STATUS_IS_OK(status)) {
-+ TALLOC_FREE(frame);
- return -1;
- }
-+ orig_length = ea.value.length;
-
-- tmp = talloc_realloc(talloc_tos(), ea.value.data, uint8_t,
-- offset + 1);
-+ /* Requested size matches the original size */
-+ if(orig_length == offset) {
-+ TALLOC_FREE(frame);
-+ return 0;
-+ }
-
-- if (tmp == NULL) {
-- TALLOC_FREE(ea.value.data);
-+ /* That can both shrink and expand */
-+ /* XXX: If offset == 0 the result of talloc_realloc is NULL, but still valid */
-+ if(offset && !data_blob_realloc(talloc_tos(), &ea.value, offset)) {
-+ TALLOC_FREE(frame);
- errno = ENOMEM;
- return -1;
- }
-
-- /* Did we expand ? */
-- if (ea.value.length < offset + 1) {
-- memset(&tmp[ea.value.length], '\0',
-- offset + 1 - ea.value.length);
-+ /* If we expanded, fill up extra space with zeros */
-+ if (orig_length < offset) {
-+ memset(ea.value.data + orig_length, 0,
-+ offset - orig_length);
- }
-
-- ea.value.data = tmp;
-- ea.value.length = offset + 1;
-- ea.value.data[offset] = 0;
--
-+ /* XXX: We should use ea.value.length here, but when offset == 0
-+ it's not reset to 0 in data_blob_realloc() */
- ret = SMB_VFS_SETXATTR(fsp->conn,
- fsp->fsp_name,
- sio->xattr_name,
-- ea.value.data, ea.value.length, 0);
-- TALLOC_FREE(ea.value.data);
-+ ea.value.data, offset, 0);
-+ TALLOC_FREE(frame);
-
- if (ret == -1) {
- return -1;
-@@ -1326,9 +1414,9 @@ static int streams_xattr_fallocate(struc
- struct stream_io *sio =
- (struct stream_io *)VFS_FETCH_FSP_EXTENSION(handle, fsp);
-
-- DEBUG(10, ("streams_xattr_fallocate called for file %s offset %.0f"
-- "len = %.0f\n",
-- fsp_str_dbg(fsp), (double)offset, (double)len));
-+ DEBUG(10, ("streams_xattr_fallocate: called for file '%s' with offset %lu"
-+ "len = %lu\n",
-+ fsp_str_dbg(fsp), (unsigned long)offset, (unsigned long)len));
-
- if (sio == NULL) {
- return SMB_VFS_NEXT_FALLOCATE(handle, fsp, mode, offset, len);