diff options
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.c | 526 |
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); |