The branch, master has been updated via 54c6cf8666b libcli/smb: allow SMB2 Negotiate responses with security_offset = 0 and security_length = 0 via 8ca99c25bac lib/util: data_blob_append() should not fail if both parts have length=0 via bc22d5ebf92 lib/util: add tests for data_blob_append() with the resulting blob length=0 via 7e2cc5eda84 s4/dsdb/repl_meta_data: Receive function arguments in correct order via 03894de3abb rpc_server/lsa: Match Windows security descriptor via 1808e5c1334 smbd: optimize and streamline smbd_smb2_close() via 4c7921e54d8 smbd: pass fsp as pointer-pointer to smbd_smb2_close() via f661ef67ba2 smbd: add fstat_before_close fsp flag and logic from 1dfa193232c s3:winbind: Remove unused functions
https://git.samba.org/?p=samba.git;a=shortlog;h=master - Log ----------------------------------------------------------------- commit 54c6cf8666b073818301d3a71a37453b44e57b5c Author: Stefan Metzmacher <me...@samba.org> Date: Tue Apr 26 10:38:15 2022 +0200 libcli/smb: allow SMB2 Negotiate responses with security_offset = 0 and security_length = 0 This fixes connections against the Azure SMB3 server. It's not possible to demonstrate the bug with a test and a knownfail entry, because it fails to even startup the test environments, but the following change to our server demonstrates the problem and shows the fix works: diff --git a/source3/smbd/smb2_negprot.c b/source3/smbd/smb2_negprot.c index da567951c0bf..25fdaea2df7b 100644 --- a/source3/smbd/smb2_negprot.c +++ b/source3/smbd/smb2_negprot.c @@ -711,6 +711,8 @@ NTSTATUS smbd_smb2_request_process_negprot(struct smbd_smb2_request *req) } } + security_buffer = data_blob_null; + if (out_negotiate_context_blob.length != 0) { static const uint8_t zeros[8]; size_t pad = 0; @@ -759,6 +761,8 @@ NTSTATUS smbd_smb2_request_process_negprot(struct smbd_smb2_request *req) return smbd_smb2_request_error(req, NT_STATUS_NO_MEMORY); } + security_offset = 0; + SSVAL(outbody.data, 0x00, 0x40 + 1); /* struct size */ SSVAL(outbody.data, 0x02, security_mode); /* security mode */ BUG: https://bugzilla.samba.org/show_bug.cgi?id=15050 Signed-off-by: Stefan Metzmacher <me...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> Autobuild-User(master): Jeremy Allison <j...@samba.org> Autobuild-Date(master): Mon May 2 20:13:10 UTC 2022 on sn-devel-184 commit 8ca99c25bacb6d9b0e6e064b37d6b726d181a487 Author: Stefan Metzmacher <me...@samba.org> Date: Thu Apr 28 16:08:42 2022 +0200 lib/util: data_blob_append() should not fail if both parts have length=0 BUG: https://bugzilla.samba.org/show_bug.cgi?id=15050 Signed-off-by: Stefan Metzmacher <me...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> commit bc22d5ebf928499e8f0b9540721e9a62db029195 Author: Stefan Metzmacher <me...@samba.org> Date: Thu Apr 28 16:08:28 2022 +0200 lib/util: add tests for data_blob_append() with the resulting blob length=0 BUG: https://bugzilla.samba.org/show_bug.cgi?id=15050 Signed-off-by: Stefan Metzmacher <me...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> commit 7e2cc5eda84cc9fc7395b86e0908e88c72a320dc Author: Joseph Sutton <josephsut...@catalyst.net.nz> Date: Wed Feb 16 12:10:19 2022 +1300 s4/dsdb/repl_meta_data: Receive function arguments in correct order The incorrect ordering was introduced in commit b9c5417b523c4c53cb275c12ec84bbc849705bec. BUG: https://bugzilla.samba.org/show_bug.cgi?id=15007 Signed-off-by: Joseph Sutton <josephsut...@catalyst.net.nz> Reviewed-by: Jeremy Allison <j...@samba.org> commit 03894de3abb02045a10886ba40f94bf9a4d8a530 Author: Joseph Sutton <josephsut...@catalyst.net.nz> Date: Tue Mar 29 10:03:55 2022 +1300 rpc_server/lsa: Match Windows security descriptor Signed-off-by: Joseph Sutton <josephsut...@catalyst.net.nz> Reviewed-by: Jeremy Allison <j...@samba.org> commit 1808e5c133474eabc9d3cf91c2a92ec4d92d9fdd Author: Ralph Boehme <s...@samba.org> Date: Mon May 2 16:29:49 2022 +0200 smbd: optimize and streamline smbd_smb2_close() Signed-off-by: Ralph Boehme <s...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> commit 4c7921e54d835b3e3aae0526d9c6170bf7a92d8c Author: Ralph Boehme <s...@samba.org> Date: Fri Apr 1 12:19:34 2022 +0200 smbd: pass fsp as pointer-pointer to smbd_smb2_close() Prepares for NULLing state->in_fsp in the next commit. Signed-off-by: Ralph Boehme <s...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> commit f661ef67ba2f99572d89a14bf5af5f0d48255788 Author: Ralph Boehme <s...@samba.org> Date: Fri Apr 29 18:55:31 2022 +0200 smbd: add fstat_before_close fsp flag and logic Signed-off-by: Ralph Boehme <s...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> ----------------------------------------------------------------------- Summary of changes: lib/util/data_blob.c | 5 ++ lib/util/tests/data_blob.c | 26 +++++++++ libcli/smb/smbXcli_base.c | 15 +++++ source3/include/vfs.h | 2 + source3/smbd/open.c | 8 +++ source3/smbd/smb2_close.c | 75 ++++++------------------- source4/dsdb/samdb/ldb_modules/repl_meta_data.c | 2 +- source4/rpc_server/lsa/lsa_init.c | 7 ++- 8 files changed, 77 insertions(+), 63 deletions(-) Changeset truncated at 500 lines: diff --git a/lib/util/data_blob.c b/lib/util/data_blob.c index 77b077f7ef9..da1730dccf5 100644 --- a/lib/util/data_blob.c +++ b/lib/util/data_blob.c @@ -229,6 +229,11 @@ _PUBLIC_ bool data_blob_append(TALLOC_CTX *mem_ctx, DATA_BLOB *blob, { size_t old_len = blob->length; size_t new_len = old_len + length; + + if (length == 0) { + return true; + } + if (new_len < length || new_len < old_len) { return false; } diff --git a/lib/util/tests/data_blob.c b/lib/util/tests/data_blob.c index d2999aba1e0..a3b2db6e604 100644 --- a/lib/util/tests/data_blob.c +++ b/lib/util/tests/data_blob.c @@ -84,6 +84,30 @@ static bool test_hex_string(struct torture_context *tctx) return true; } +static bool test_append_NULL_0(struct torture_context *tctx) +{ + DATA_BLOB z = data_blob_talloc_zero(tctx, 0); + torture_assert_int_equal(tctx, z.length, 0, "length"); + torture_assert(tctx, z.data == NULL, "data"); + torture_assert(tctx, data_blob_append(NULL, &z, NULL, 0), "append NULL,0"); + torture_assert(tctx, data_blob_append(NULL, &z, "", 0), "append '',0"); + torture_assert_int_equal(tctx, z.length, 0, "length"); + torture_assert(tctx, z.data == NULL, "data"); + return true; +} + +static bool test_append_empty_0(struct torture_context *tctx) +{ + DATA_BLOB e = data_blob_talloc(tctx, "", 0); + torture_assert_int_equal(tctx, e.length, 0, "length"); + torture_assert(tctx, e.data != NULL, "data"); + torture_assert(tctx, data_blob_append(NULL, &e, NULL, 0), "append NULL,0"); + torture_assert(tctx, data_blob_append(NULL, &e, "", 0), "append '',0"); + torture_assert_int_equal(tctx, e.length, 0, "length"); + torture_assert(tctx, e.data != NULL, "data"); + return true; +} + struct torture_suite *torture_local_util_data_blob(TALLOC_CTX *mem_ctx) { struct torture_suite *suite = torture_suite_create(mem_ctx, "datablob"); @@ -94,6 +118,8 @@ struct torture_suite *torture_local_util_data_blob(TALLOC_CTX *mem_ctx) torture_suite_add_simple_test(suite, "clear", test_clear); torture_suite_add_simple_test(suite, "cmp", test_cmp); torture_suite_add_simple_test(suite, "hex string", test_hex_string); + torture_suite_add_simple_test(suite, "append_NULL_0", test_append_NULL_0); + torture_suite_add_simple_test(suite, "append_empty_0", test_append_empty_0); return suite; } diff --git a/libcli/smb/smbXcli_base.c b/libcli/smb/smbXcli_base.c index 0f3e4fa3f90..57d39d60fca 100644 --- a/libcli/smb/smbXcli_base.c +++ b/libcli/smb/smbXcli_base.c @@ -5083,6 +5083,21 @@ static void smbXcli_negprot_smb2_done(struct tevent_req *subreq) security_offset = SVAL(body, 56); security_length = SVAL(body, 58); + if (security_offset == 0) { + /* + * Azure sends security_offset = 0 and security_length = 0 + * + * We just set security_offset to the expected value + * in order to allow the further logic to work + * as before. + */ + if (security_length != 0) { + tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE); + return; + } + security_offset = SMB2_HDR_BODY + iov[1].iov_len; + } + if (security_offset != SMB2_HDR_BODY + iov[1].iov_len) { tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE); return; diff --git a/source3/include/vfs.h b/source3/include/vfs.h index 841a930d309..ac6a3017f80 100644 --- a/source3/include/vfs.h +++ b/source3/include/vfs.h @@ -372,6 +372,7 @@ * Version 47 - Add SMB_VFS_GET_REAL_FILENAME_AT * Version 47 - Replace SMB_VFS_GET_REAL_FILENAME with SMB_VFS_GET_REAL_FILENAME_AT * Version 47 - Re-add dirfsp to CREATE_FILE + * Version 47 - Add fsp flag fstat_before_close */ #define SMB_VFS_INTERFACE_VERSION 47 @@ -445,6 +446,7 @@ typedef struct files_struct { bool closing : 1; bool lock_failure_seen : 1; bool encryption_required : 1; + bool fstat_before_close : 1; } fsp_flags; struct tevent_timer *update_write_time_event; diff --git a/source3/smbd/open.c b/source3/smbd/open.c index bee6cab6d42..8cb349d78b0 100644 --- a/source3/smbd/open.c +++ b/source3/smbd/open.c @@ -974,12 +974,20 @@ NTSTATUS fd_openat(const struct files_struct *dirfsp, NTSTATUS fd_close(files_struct *fsp) { + NTSTATUS status; int ret; if (fsp == fsp->conn->cwd_fsp) { return NT_STATUS_OK; } + if (fsp->fsp_flags.fstat_before_close) { + status = vfs_stat_fsp(fsp); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + } + if (fsp->dptr) { dptr_CloseDir(fsp); } diff --git a/source3/smbd/smb2_close.c b/source3/smbd/smb2_close.c index b434d696c3f..cb494a3a4d9 100644 --- a/source3/smbd/smb2_close.c +++ b/source3/smbd/smb2_close.c @@ -159,24 +159,9 @@ static void setup_close_full_information(connection_struct *conn, struct timespec *out_change_ts, uint16_t *out_flags, uint64_t *out_allocation_size, - uint64_t *out_end_of_file, - uint32_t *out_file_attributes) + uint64_t *out_end_of_file) { - NTSTATUS status; - - status = openat_pathref_fsp(conn->cwd_fsp, smb_fname); - if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND) && - (smb_fname->flags & SMB_FILENAME_POSIX_PATH) && - S_ISLNK(smb_fname->st.st_ex_mode)) - { - status = NT_STATUS_OK; - } - if (!NT_STATUS_IS_OK(status)) { - return; - } - *out_flags = SMB2_CLOSE_FLAGS_FULL_INFORMATION; - *out_file_attributes = fdos_mode(smb_fname->fsp); *out_last_write_ts = smb_fname->st.st_ex_mtime; *out_last_access_ts = smb_fname->st.st_ex_atime; *out_creation_ts = get_create_timespec(conn, NULL, smb_fname); @@ -188,7 +173,7 @@ static void setup_close_full_information(connection_struct *conn, dos_filetime_timespec(out_last_access_ts); dos_filetime_timespec(out_change_ts); } - if (!(*out_file_attributes & FILE_ATTRIBUTE_DIRECTORY)) { + if (!S_ISDIR(smb_fname->st.st_ex_mode)) { *out_end_of_file = get_file_size_stat(&smb_fname->st); } @@ -196,7 +181,7 @@ static void setup_close_full_information(connection_struct *conn, } static NTSTATUS smbd_smb2_close(struct smbd_smb2_request *req, - struct files_struct *fsp, + struct files_struct **_fsp, uint16_t in_flags, uint16_t *out_flags, struct timespec *out_creation_ts, @@ -210,11 +195,8 @@ static NTSTATUS smbd_smb2_close(struct smbd_smb2_request *req, NTSTATUS status; struct smb_request *smbreq; connection_struct *conn = req->tcon->compat; + struct files_struct *fsp = *_fsp; struct smb_filename *smb_fname = NULL; - uint64_t allocation_size = 0; - uint64_t file_size = 0; - uint32_t dos_attrs = 0; - uint16_t flags = 0; *out_creation_ts = (struct timespec){0, SAMBA_UTIME_OMIT}; *out_last_access_ts = (struct timespec){0, SAMBA_UTIME_OMIT}; @@ -234,33 +216,12 @@ static NTSTATUS smbd_smb2_close(struct smbd_smb2_request *req, return NT_STATUS_NO_MEMORY; } - smb_fname = cp_smb_filename(talloc_tos(), fsp->fsp_name); - if (smb_fname == NULL) { - return NT_STATUS_NO_MEMORY; - } - - if ((in_flags & SMB2_CLOSE_FLAGS_FULL_INFORMATION) && - (fsp->fsp_flags.initial_delete_on_close || - fsp->fsp_flags.delete_on_close)) - { - /* - * We might be deleting the file. Ensure we - * return valid data from before the file got - * removed. - */ - setup_close_full_information(conn, - smb_fname, - out_creation_ts, - out_last_access_ts, - out_last_write_ts, - out_change_ts, - &flags, - &allocation_size, - &file_size, - &dos_attrs); + if (in_flags & SMB2_CLOSE_FLAGS_FULL_INFORMATION) { + *out_file_attributes = fdos_mode(fsp); + fsp->fsp_flags.fstat_before_close = true; } - status = close_file_free(smbreq, &fsp, NORMAL_CLOSE); + status = close_file_smb(smbreq, fsp, NORMAL_CLOSE); if (!NT_STATUS_IS_OK(status)) { DEBUG(5,("smbd_smb2_close: close_file[%s]: %s\n", smb_fname_str_dbg(smb_fname), nt_errstr(status))); @@ -269,22 +230,18 @@ static NTSTATUS smbd_smb2_close(struct smbd_smb2_request *req, if (in_flags & SMB2_CLOSE_FLAGS_FULL_INFORMATION) { setup_close_full_information(conn, - smb_fname, + fsp->fsp_name, out_creation_ts, out_last_access_ts, out_last_write_ts, out_change_ts, - &flags, - &allocation_size, - &file_size, - &dos_attrs); + out_flags, + out_allocation_size, + out_end_of_file); } - *out_flags = flags; - *out_allocation_size = allocation_size; - *out_end_of_file = file_size; - *out_file_attributes = dos_attrs; - + file_free(smbreq, fsp); + *_fsp = fsp = NULL; return NT_STATUS_OK; } @@ -376,7 +333,7 @@ static struct tevent_req *smbd_smb2_close_send(TALLOC_CTX *mem_ctx, } status = smbd_smb2_close(smb2req, - state->in_fsp, + &state->in_fsp, state->in_flags, &state->out_flags, &state->out_creation_ts, @@ -406,7 +363,7 @@ static void smbd_smb2_close_wait_done(struct tevent_req *subreq) TALLOC_FREE(subreq); status = smbd_smb2_close(state->smb2req, - state->in_fsp, + &state->in_fsp, state->in_flags, &state->out_flags, &state->out_creation_ts, diff --git a/source4/dsdb/samdb/ldb_modules/repl_meta_data.c b/source4/dsdb/samdb/ldb_modules/repl_meta_data.c index 1aef120a123..4949e691a86 100644 --- a/source4/dsdb/samdb/ldb_modules/repl_meta_data.c +++ b/source4/dsdb/samdb/ldb_modules/repl_meta_data.c @@ -8152,8 +8152,8 @@ static int replmd_process_linked_attribute(struct ldb_module *module, const struct dsdb_attribute *attr, struct la_entry *la_entry, struct ldb_request *parent, - struct ldb_message_element *old_el, TALLOC_CTX *element_ctx, + struct ldb_message_element *old_el, struct parsed_dn *pdn_list, replmd_link_changed *change) { diff --git a/source4/rpc_server/lsa/lsa_init.c b/source4/rpc_server/lsa/lsa_init.c index cd4a1569aea..689634b9706 100644 --- a/source4/rpc_server/lsa/lsa_init.c +++ b/source4/rpc_server/lsa/lsa_init.c @@ -30,13 +30,14 @@ "O:BAG:SY" \ "D:" \ "(D;;0x00000800;;;AN)" \ - "(A;;GA;;;BA)" \ - "(A;;GX;;;WD)" \ + "(A;;0x000f1fff;;;BA)" \ + "(A;;0x00020801;;;WD)" \ "(A;;0x00000801;;;AN)" \ "(A;;0x00001000;;;LS)" \ "(A;;0x00001000;;;NS)" \ "(A;;0x00001000;;;S-1-5-17)" \ - "(A;;0x00000801;;;S-1-15-2-1)" + "(A;;0x00000801;;;AC)" \ + "(A;;0x00000801;;;S-1-15-2-2)" static const struct generic_mapping dcesrv_lsa_policy_mapping = { LSA_POLICY_READ, -- Samba Shared Repository