The branch, v4-18-test has been updated via 320d654041d s3: smbd: Add missing 'return;'s in exit paths in reply_exit_done(). via 122afc37724 s3: torture: Add a test doing an SMB1 negotiate+exit. via e6c0d4f122d s3: smbd: Ensure all callers to srvstr_pull_req_talloc() pass a zeroed-out dest pointer. via f025f51ac5c s3: smbd: Uncorrupt the pointer we were using to prove a crash. via 4c27dfe322c s3: smbd: Ensure srvstr_pull_req_talloc() always NULLs out *dest. via 6fef976770c s3: torture: Add SMB1-TRUNCATED-SESSSETUP test. via 8e31fd2d599 s3: smbd: Deliberately currupt an uninitialized pointer. via 9e5f1a30a49 mdssvc: Do an early talloc_free() in _mdssvc_open() from cd866f5c4ce s3:smbd: fix multichannel connection passing race
https://git.samba.org/?p=samba.git;a=shortlog;h=v4-18-test - Log ----------------------------------------------------------------- commit 320d654041d8f867f7bf3767486a028948136aa8 Author: Jeremy Allison <j...@samba.org> Date: Fri Aug 11 15:19:01 2023 -0700 s3: smbd: Add missing 'return;'s in exit paths in reply_exit_done(). Remove knownfail. BUG: https://bugzilla.samba.org/show_bug.cgi?id=15430 Signed-off-by: Jeremy Allison <j...@samba.org> Reviewed-by: Noel Power <npo...@samba.org> Autobuild-User(master): Noel Power <npo...@samba.org> Autobuild-Date(master): Mon Aug 14 19:52:49 UTC 2023 on atb-devel-224 (cherry picked from commit d79d0508a4b8bdc4582a350d109181ecae0bf1e2) Autobuild-User(v4-18-test): Jule Anger <jan...@samba.org> Autobuild-Date(v4-18-test): Wed Aug 16 11:49:39 UTC 2023 on atb-devel-224 commit 122afc377246f722306df2d8c1b4ca5eb0aa7bb0 Author: Jeremy Allison <j...@samba.org> Date: Fri Aug 11 15:12:05 2023 -0700 s3: torture: Add a test doing an SMB1 negotiate+exit. Robert Morris <r...@lcs.mit.edu> noticed a missing return in reply_exit_done(). Adds knownfail. BUG: https://bugzilla.samba.org/show_bug.cgi?id=15430 Signed-off-by: Jeremy Allison <j...@samba.org> Reviewed-by: Noel Power <npo...@samba.org> (cherry picked from commit 63895e03c4e8ed79a3b2cda928f58ec278cd6608) commit e6c0d4f122d8083273009d0f61e099bb34fbcf51 Author: Jeremy Allison <j...@samba.org> Date: Fri Aug 11 10:52:31 2023 -0700 s3: smbd: Ensure all callers to srvstr_pull_req_talloc() pass a zeroed-out dest pointer. Now we've fixed srvstr_pull_req_talloc() this isn't strictly needed, but ensuring pointers are initialized is best practice to avoid future bugs. BUG: https://bugzilla.samba.org/show_bug.cgi?id=15420 Signed-off-by: Jeremy Allison <j...@samba.org> Reviewed-by: Volker Lendecke <v...@samba.org> Autobuild-User(master): Volker Lendecke <v...@samba.org> Autobuild-Date(master): Mon Aug 14 15:55:43 UTC 2023 on atb-devel-224 (cherry picked from commit 5379b8d557a9a16b81eafb87b60b81debc4bfccb) commit f025f51ac5c363c37f4a80baa06c40106ae2bdae Author: Jeremy Allison <j...@samba.org> Date: Fri Aug 11 10:47:28 2023 -0700 s3: smbd: Uncorrupt the pointer we were using to prove a crash. Rather than restore to uninitialized, set to NULL as per modern coding practices. BUG: https://bugzilla.samba.org/show_bug.cgi?id=15420 Reviewed-by: Volker Lendecke <v...@samba.org> Signed-off-by: Jeremy Allison <j...@samba.org> Reviewed-by: Volker Lendecke <v...@samba.org> (cherry picked from commit 5bc50d2ea4444244721e72b4264311c7005d2f3c) commit 4c27dfe322c28e01a5657e1e707000474d2343f9 Author: Jeremy Allison <j...@samba.org> Date: Fri Aug 11 10:42:41 2023 -0700 s3: smbd: Ensure srvstr_pull_req_talloc() always NULLs out *dest. Robert Morris <r...@lcs.mit.edu> noticed that in the case where srvstr_pull_req_talloc() is being called with buffer remaining == 0, we don't NULL out the destination pointed which is *always* done in the codepaths inside pull_string_talloc(). This prevents a crash in the caller. Remove knownfail. BUG: https://bugzilla.samba.org/show_bug.cgi?id=15420 Signed-off-by: Jeremy Allison <j...@samba.org> Reviewed-by: Volker Lendecke <v...@samba.org> (cherry picked from commit 9220c45cc191b34e293190f6a923ba463edd5db9) commit 6fef976770c596e5663f49a3cf194b0e6cdf83e6 Author: Jeremy Allison <j...@samba.org> Date: Fri Aug 11 10:39:36 2023 -0700 s3: torture: Add SMB1-TRUNCATED-SESSSETUP test. Shows that we indirect through an uninitialized pointer and the client crashes it's own smbd. Add knownfail. BUG: https://bugzilla.samba.org/show_bug.cgi?id=15420 Signed-off-by: Jeremy Allison <j...@samba.org> Reviewed-by: Volker Lendecke <v...@samba.org> (cherry picked from commit 963fd8aa9b76361ab9aeb63307773f2498b17879) commit 8e31fd2d5998d08f66bad617aecbc6dc4a9490cf Author: Jeremy Allison <j...@samba.org> Date: Fri Aug 11 10:38:23 2023 -0700 s3: smbd: Deliberately currupt an uninitialized pointer. We will need this to show smbd crashing in the test code. This will be removed once we're passing the test. BUG: https://bugzilla.samba.org/show_bug.cgi?id=15420 Signed-off-by: Jeremy Allison <j...@samba.org> Reviewed-by: Volker Lendecke <v...@samba.org> (cherry picked from commit e7bf94b4e3a7f994aa6f0b859089c5add2ad380f) commit 9e5f1a30a4904d42d838461ff90be1ef917ec696 Author: Jones Syue <joness...@qnap.com> Date: Mon Aug 7 17:08:29 2023 +0800 mdssvc: Do an early talloc_free() in _mdssvc_open() Environment setup: When macOS Finder connect to a samba server with 'spotlight = yes', macOS would issue mdssvc open (mdssvc.opnum == 0) to samba and it goes through api _mdssvc_open(). After applied 578e434a94147dc2d7dbfc006d2ab84807859c1d, (this is reported by jay...@qnap.com) this line 'talloc_free(path);' is deleted if _mdssvc_open() normal exit, so memory is lazy de-allocate: delayed to smbd_tevent_trace_callback() @ smb2_process.c. [1] Supposed to explicitly free 'path' in _mdssvc_open() @ srv_mdssvc_nt.c[2] just like abnormal exit, do not wait for main loop to free 'path' which is no longer used, this is more consistent while reading source code. BUG: https://bugzilla.samba.org/show_bug.cgi?id=15449 [1] gdb tracing 'path' address 0x56204ccc67e0 to know how it is freed. Breakpoint 2, _tc_free_children_internal (tc=0x56204ccc6780, ptr=0x56204ccc67e0, location=0x7ff430d96410 "../../lib/talloc/talloc.c:1714") at ../../lib/talloc/talloc.c:1656 1656 while (tc->child) { (gdb) bt 0 _tc_free_children_internal (tc=0x56204ccc6780, ptr=0x56204ccc67e0, location=0x7ff430d96410 "../../lib/talloc/talloc.c:1714") at ../../lib/talloc/talloc.c:1656 1 0x00007ff430d92b14 in _tc_free_internal (tc=0x56204ccc6780, location=0x7ff430d96410 "../../lib/talloc/talloc.c:1714") at ../../lib/talloc/talloc.c:1183 2 0x00007ff430d93b71 in _tc_free_children_internal (tc=0x56204ccc6720, ptr=0x56204ccc6780, location=0x7ff430d96410 "../../lib/talloc/talloc.c:1714") at ../../lib/talloc/talloc.c:1668 3 0x00007ff430d93d66 in talloc_free_children (ptr=0x56204ccc6780) at ../../lib/talloc/talloc.c:1714 4 0x00007ff432235aca in talloc_pop (frame=0x56204ccc6780) at ../../lib/util/talloc_stack.c:125 5 0x00007ff430d92959 in _tc_free_internal (tc=0x56204ccc6720, location=0x7ff431f358d0 "../../source3/smbd/process.c:3726") at ../../lib/talloc/talloc.c:1157 6 0x00007ff430d92cd5 in _talloc_free_internal (ptr=0x56204ccc6780, location=0x7ff431f358d0 "../../source3/smbd/process.c:3726") at ../../lib/talloc/talloc.c:1247 7 0x00007ff430d93f96 in _talloc_free (ptr=0x56204ccc6780, location=0x7ff431f358d0 "../../source3/smbd/process.c:3726") at ../../lib/talloc/talloc.c:1791 8 0x00007ff431d81292 in smbd_tevent_trace_callback (point=TEVENT_TRACE_AFTER_LOOP_ONCE, private_data=0x7ffe46591e30) at ../../source3/smbd/process.c:3726 <...cut...> [2] gdb tracing 'path' address 0x55a6d66deed0 to know how it is freed. Breakpoint 2, _tc_free_children_internal (tc=0x55a6d66deed0, ptr=0x55a6d66def30, location=0x7fc4cca84040 "../../source3/rpc_server/mdssvc/srv_mdssvc_nt.c:189") at ../../lib/talloc/talloc.c:1656 1656 while (tc->child) { (gdb) bt 0 _tc_free_children_internal (tc=0x55a6d66deed0, ptr=0x55a6d66def30, location=0x7fc4cca84040 "../../source3/rpc_server/mdssvc/srv_mdssvc_nt.c:189") at ../../lib/talloc/talloc.c:1656 1 0x00007fc4cb892b14 in _tc_free_internal (tc=0x55a6d66deed0, location=0x7fc4cca84040 "../../source3/rpc_server/mdssvc/srv_mdssvc_nt.c:189") at ../../lib/talloc/talloc.c:1183 2 0x00007fc4cb892cd5 in _talloc_free_internal (ptr=0x55a6d66def30, location=0x7fc4cca84040 "../../source3/rpc_server/mdssvc/srv_mdssvc_nt.c:189") at ../../lib/talloc/talloc.c:1247 3 0x00007fc4cb893f96 in _talloc_free (ptr=0x55a6d66def30, location=0x7fc4cca84040 "../../source3/rpc_server/mdssvc/srv_mdssvc_nt.c:189") at ../../lib/talloc/talloc.c:1791 4 0x00007fc4cc9396e4 in _mdssvc_open (p=0x55a6d66d5600, r=0x55a6d66edc60) at ../../source3/rpc_server/mdssvc/srv_mdssvc_nt.c:189 <...cut...> Signed-off-by: Jones Syue <joness...@qnap.com> Reviewed-by: Noel Power <npo...@samba.org> Reviewed-by: Volker Lendecke <v...@samba.org> Autobuild-User(master): Noel Power <npo...@samba.org> Autobuild-Date(master): Mon Aug 14 18:11:37 UTC 2023 on atb-devel-224 (cherry picked from commit 044cb8f9d558bfcd7658cae0f05ff36330538748) ----------------------------------------------------------------------- Summary of changes: source3/rpc_server/mdssvc/srv_mdssvc_nt.c | 1 + source3/selftest/tests.py | 22 ++ source3/smbd/smb1_ipc.c | 2 +- source3/smbd/smb1_message.c | 2 +- source3/smbd/smb1_reply.c | 2 + source3/smbd/smb1_sesssetup.c | 4 +- source3/smbd/smb2_reply.c | 1 + source3/torture/torture.c | 362 ++++++++++++++++++++++++++++++ 8 files changed, 392 insertions(+), 4 deletions(-) Changeset truncated at 500 lines: diff --git a/source3/rpc_server/mdssvc/srv_mdssvc_nt.c b/source3/rpc_server/mdssvc/srv_mdssvc_nt.c index c77e7185521..9a166244df5 100644 --- a/source3/rpc_server/mdssvc/srv_mdssvc_nt.c +++ b/source3/rpc_server/mdssvc/srv_mdssvc_nt.c @@ -135,6 +135,7 @@ void _mdssvc_open(struct pipes_struct *p, struct mdssvc_open *r) } strlcpy(outpath, fake_path, 1024); + talloc_free(path); talloc_free(fake_path); return; } diff --git a/source3/selftest/tests.py b/source3/selftest/tests.py index 83d72db003c..178f550b5b7 100755 --- a/source3/selftest/tests.py +++ b/source3/selftest/tests.py @@ -217,6 +217,28 @@ plantestsuite("samba3.smbtorture_s3.hidenewfiles_showdirs", "", "-l $LOCAL_PATH"]) +plantestsuite("samba3.smbtorture_s3.smb1.SMB1-TRUNCATED-SESSSETUP", + "fileserver_smb1", + [os.path.join(samba3srcdir, + "script/tests/test_smbtorture_s3.sh"), + 'SMB1-TRUNCATED-SESSSETUP', + '//$SERVER_IP/tmp', + '$USERNAME', + '$PASSWORD', + smbtorture3, + "-mNT1"]) + +plantestsuite("samba3.smbtorture_s3.smb1.SMB1-NEGOTIATE-EXIT", + "fileserver_smb1", + [os.path.join(samba3srcdir, + "script/tests/test_smbtorture_s3.sh"), + 'SMB1-NEGOTIATE-EXIT', + '//$SERVER_IP/tmp', + '$USERNAME', + '$PASSWORD', + smbtorture3, + "-mNT1"]) + # # MSDFS attribute tests. # diff --git a/source3/smbd/smb1_ipc.c b/source3/smbd/smb1_ipc.c index 1f289e4fc3a..66e58e6c099 100644 --- a/source3/smbd/smb1_ipc.c +++ b/source3/smbd/smb1_ipc.c @@ -688,7 +688,7 @@ void reply_trans(struct smb_request *req) return; } - if ((state = talloc(conn, struct trans_state)) == NULL) { + if ((state = talloc_zero(conn, struct trans_state)) == NULL) { DEBUG(0, ("talloc failed\n")); reply_nterror(req, NT_STATUS_NO_MEMORY); END_PROFILE(SMBtrans); diff --git a/source3/smbd/smb1_message.c b/source3/smbd/smb1_message.c index 928be77f854..ca7201e2e7f 100644 --- a/source3/smbd/smb1_message.c +++ b/source3/smbd/smb1_message.c @@ -159,7 +159,7 @@ void reply_sends(struct smb_request *req) return; } - state = talloc(talloc_tos(), struct msg_state); + state = talloc_zero(talloc_tos(), struct msg_state); p = req->buf + 1; p += srvstr_pull_req_talloc( diff --git a/source3/smbd/smb1_reply.c b/source3/smbd/smb1_reply.c index de6b4d99f79..abdc40fd2b2 100644 --- a/source3/smbd/smb1_reply.c +++ b/source3/smbd/smb1_reply.c @@ -4705,6 +4705,7 @@ static void reply_exit_done(struct tevent_req *req) reply_force_doserror(smb1req, ERRSRV, ERRinvnid); smb_request_done(smb1req); END_PROFILE(SMBexit); + return; } /* @@ -4744,6 +4745,7 @@ static void reply_exit_done(struct tevent_req *req) reply_force_doserror(smb1req, ERRSRV, ERRinvnid); smb_request_done(smb1req); END_PROFILE(SMBexit); + return; } close_file_free(NULL, &fsp, SHUTDOWN_CLOSE); } diff --git a/source3/smbd/smb1_sesssetup.c b/source3/smbd/smb1_sesssetup.c index 78dd09199aa..a812d375d63 100644 --- a/source3/smbd/smb1_sesssetup.c +++ b/source3/smbd/smb1_sesssetup.c @@ -86,7 +86,7 @@ static void reply_sesssetup_and_X_spnego(struct smb_request *req) DATA_BLOB in_blob; DATA_BLOB out_blob = data_blob_null; size_t bufrem; - char *tmp; + char *tmp = NULL; const char *native_os; const char *native_lanman; const char *primary_domain; @@ -581,7 +581,7 @@ void reply_sesssetup_and_X(struct smb_request *req) struct reply_sesssetup_and_X_state *state = NULL; uint64_t sess_vuid; uint16_t smb_bufsize; - char *tmp; + char *tmp = NULL; fstring sub_user; /* Sanitised username for substitution */ const char *native_os; const char *native_lanman; diff --git a/source3/smbd/smb2_reply.c b/source3/smbd/smb2_reply.c index 76e3cf789cd..5ff6f4db8c9 100644 --- a/source3/smbd/smb2_reply.c +++ b/source3/smbd/smb2_reply.c @@ -517,6 +517,7 @@ size_t srvstr_pull_req_talloc(TALLOC_CTX *ctx, struct smb_request *req, ssize_t bufrem = smbreq_bufrem(req, src); if (bufrem == 0) { + *dest = NULL; return 0; } diff --git a/source3/torture/torture.c b/source3/torture/torture.c index c63db3f9385..63fe4ac6f7f 100644 --- a/source3/torture/torture.c +++ b/source3/torture/torture.c @@ -14645,6 +14645,359 @@ static bool run_local_canonicalize_path(int dummy) } return true; } +struct session_setup_nt1_truncated_state { + uint16_t vwv[13]; + uint8_t bytes[20]; +}; + +static void smb1_session_setup_nt1_truncated_done(struct tevent_req *subreq); + +static struct tevent_req *smb1_session_setup_nt1_truncated_send( + TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct smbXcli_conn *conn) +{ + uint16_t *vwv = NULL; + uint8_t *bytes = NULL; + const char *pass = "12345678"; + const char *uname = "z"; + struct session_setup_nt1_truncated_state *state = NULL; + struct tevent_req *req = NULL; + struct tevent_req *subreq = NULL; + + req = tevent_req_create(mem_ctx, + &state, + struct session_setup_nt1_truncated_state); + if (req == NULL) { + return NULL; + } + vwv = &state->vwv[0]; + bytes = &state->bytes[0]; + + SCVAL(vwv+0, 0, 0xff); + SCVAL(vwv+0, 1, 0); + SSVAL(vwv+1, 0, 0); + SSVAL(vwv+2, 0, 8192); + SSVAL(vwv+3, 0, 2); + SSVAL(vwv+4, 0, 1); + SIVAL(vwv+5, 0, 0); + SSVAL(vwv+7, 0, strlen(pass)); /* OEMPasswordLen */ + SSVAL(vwv+8, 0, 0); /* UnicodePasswordLen */ + SSVAL(vwv+9, 0, 0); /* reserved */ + SSVAL(vwv+10, 0, 0); /* reserved */ + SIVAL(vwv+11, 0, CAP_STATUS32); + + memcpy(bytes, pass, strlen(pass)); + bytes += strlen(pass); + memcpy(bytes, uname, strlen(uname)+1); + + subreq = smb1cli_req_send(state, ev, conn, + SMBsesssetupX, + 0, /* additional_flags */ + 0, /* clear_flags */ + 0, /* additional_flags2 */ + 0, /* clear_flags2 */ + 10000, /* timeout_msec */ + getpid(), + NULL, /* tcon */ + NULL, /* session */ + 13, /* wct */ + state->vwv, + strlen(pass), /* Truncate length at password. */ + state->bytes); + if (tevent_req_nomem(subreq, req)) { + return tevent_req_post(req, ev); + } + tevent_req_set_callback(subreq, + smb1_session_setup_nt1_truncated_done, + req); + return req; +} + +static void smb1_session_setup_nt1_truncated_done(struct tevent_req *subreq) +{ + struct tevent_req *req = + tevent_req_callback_data(subreq, + struct tevent_req); + struct session_setup_nt1_truncated_state *state = + tevent_req_data(req, + struct session_setup_nt1_truncated_state); + NTSTATUS status; + struct smb1cli_req_expected_response expected[] = { + { + .status = NT_STATUS_OK, + .wct = 3, + }, + }; + + status = smb1cli_req_recv(subreq, state, + NULL, + NULL, + NULL, + NULL, + NULL, /* pvwv_offset */ + NULL, + NULL, + NULL, /* pbytes_offset */ + NULL, + expected, ARRAY_SIZE(expected)); + TALLOC_FREE(subreq); + if (tevent_req_nterror(req, status)) { + return; + } + tevent_req_done(req); +} + +static NTSTATUS smb1_session_setup_nt1_truncated_recv(struct tevent_req *req) +{ + return tevent_req_simple_recv_ntstatus(req); +} + +static bool run_smb1_truncated_sesssetup(int dummy) +{ + struct tevent_context *ev; + struct tevent_req *req; + struct smbXcli_conn *conn; + struct sockaddr_storage ss; + NTSTATUS status; + int fd; + bool ok; + + printf("Starting send truncated SMB1 sesssetup.\n"); + + ok = resolve_name(host, &ss, 0x20, true); + if (!ok) { + d_fprintf(stderr, "Could not resolve name %s\n", host); + return false; + } + + status = open_socket_out(&ss, 445, 10000, &fd); + if (!NT_STATUS_IS_OK(status)) { + d_fprintf(stderr, "open_socket_out failed: %s\n", + nt_errstr(status)); + return false; + } + + conn = smbXcli_conn_create(talloc_tos(), fd, host, SMB_SIGNING_OFF, 0, + NULL, 0, NULL); + if (conn == NULL) { + d_fprintf(stderr, "smbXcli_conn_create failed\n"); + return false; + } + + status = smbXcli_negprot(conn, 0, PROTOCOL_NT1, PROTOCOL_NT1); + if (!NT_STATUS_IS_OK(status)) { + d_fprintf(stderr, "smbXcli_negprot failed!\n"); + return false; + } + + ev = samba_tevent_context_init(talloc_tos()); + if (ev == NULL) { + d_fprintf(stderr, "samba_tevent_context_init failed\n"); + return false; + } + + req = smb1_session_setup_nt1_truncated_send(ev, ev, conn); + if (req == NULL) { + d_fprintf(stderr, "smb1_session_setup_nt1_truncated_send failed\n"); + return false; + } + + ok = tevent_req_poll_ntstatus(req, ev, &status); + if (!ok) { + d_fprintf(stderr, "tevent_req_poll failed with status %s\n", + nt_errstr(status)); + return false; + } + + status = smb1_session_setup_nt1_truncated_recv(req); + if (!NT_STATUS_IS_OK(status)) { + d_fprintf(stderr, "smb1_session_setup_nt1_truncated_recv returned " + "%s, expected NT_STATUS_OK\n", + nt_errstr(status)); + return false; + } + + TALLOC_FREE(conn); + return true; +} + +struct smb1_negotiate_exit_state { + int dummy; +}; + +static void smb1_negotiate_exit_done(struct tevent_req *subreq); + +static struct tevent_req *smb1_negotiate_exit_send( + TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct smbXcli_conn *conn) +{ + struct smb1_negotiate_exit_state *state = NULL; + struct tevent_req *req = NULL; + struct tevent_req *subreq = NULL; + + req = tevent_req_create(mem_ctx, + &state, + struct smb1_negotiate_exit_state); + if (req == NULL) { + return NULL; + } + subreq = smb1cli_req_send(state, ev, conn, + SMBexit, + 0, /* additional_flags */ + 0, /* clear_flags */ + 0, /* additional_flags2 */ + 0, /* clear_flags2 */ + 10000, /* timeout_msec */ + getpid(), + NULL, /* tcon */ + NULL, /* session */ + 0, /* wct */ + NULL, + 0, + NULL); + if (tevent_req_nomem(subreq, req)) { + return tevent_req_post(req, ev); + } + tevent_req_set_callback(subreq, + smb1_negotiate_exit_done, + req); + return req; +} + +static void smb1_negotiate_exit_done(struct tevent_req *subreq) +{ + struct tevent_req *req = + tevent_req_callback_data(subreq, + struct tevent_req); + struct smb1_negotiate_exit_state *state = + tevent_req_data(req, + struct smb1_negotiate_exit_state); + NTSTATUS status; + struct smb1cli_req_expected_response expected[] = { + { + .status = NT_STATUS_OK, + .wct = 0, + }, + }; + + status = smb1cli_req_recv(subreq, state, + NULL, + NULL, + NULL, + NULL, + NULL, /* pvwv_offset */ + NULL, + NULL, + NULL, /* pbytes_offset */ + NULL, + expected, ARRAY_SIZE(expected)); + TALLOC_FREE(subreq); + if (tevent_req_nterror(req, status)) { + return; + } + tevent_req_done(req); +} + +static NTSTATUS smb1_negotiate_exit_recv(struct tevent_req *req) +{ + return tevent_req_simple_recv_ntstatus(req); +} + +static bool do_smb1_exit(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct smbXcli_conn *conn) +{ + struct tevent_req *req; + bool ok; + NTSTATUS status; + NTSTATUS expected_status = NT_STATUS_DOS(ERRSRV, ERRinvnid);; + + req = smb1_negotiate_exit_send(ev, ev, conn); + if (req == NULL) { + d_fprintf(stderr, "smb1_negotiate_exit_send failed\n"); + return false; + } + + ok = tevent_req_poll_ntstatus(req, ev, &status); + if (!ok) { + d_fprintf(stderr, "tevent_req_poll failed with status %s\n", + nt_errstr(status)); + return false; + } + + status = smb1_negotiate_exit_recv(req); + if (!NT_STATUS_EQUAL(status, expected_status)) { + d_fprintf(stderr, "smb1_negotiate_exit_recv returned " + "%s, expected ERRSRV, ERRinvnid\n", + nt_errstr(status)); + return false; + } + return true; +} + +static bool run_smb1_negotiate_exit(int dummy) +{ + struct tevent_context *ev; + struct smbXcli_conn *conn; + struct sockaddr_storage ss; + NTSTATUS status; + int fd; + bool ok; + + printf("Starting send SMB1 negotiate+exit.\n"); + + ok = resolve_name(host, &ss, 0x20, true); + if (!ok) { + d_fprintf(stderr, "Could not resolve name %s\n", host); + return false; + } + + status = open_socket_out(&ss, 445, 10000, &fd); + if (!NT_STATUS_IS_OK(status)) { + d_fprintf(stderr, "open_socket_out failed: %s\n", + nt_errstr(status)); + return false; + } + + conn = smbXcli_conn_create(talloc_tos(), fd, host, SMB_SIGNING_OFF, 0, + NULL, 0, NULL); + if (conn == NULL) { + d_fprintf(stderr, "smbXcli_conn_create failed\n"); + return false; + } + + status = smbXcli_negprot(conn, 0, PROTOCOL_NT1, PROTOCOL_NT1); + if (!NT_STATUS_IS_OK(status)) { + d_fprintf(stderr, "smbXcli_negprot failed!\n"); + return false; + } + + ev = samba_tevent_context_init(talloc_tos()); + if (ev == NULL) { + d_fprintf(stderr, "samba_tevent_context_init failed\n"); + return false; + } + + /* + * Call do_smb1_exit twice to catch a server crash, the + * server sends the first return code then crashes. + */ + ok = do_smb1_exit(ev, ev, conn); + if (!ok) { + d_fprintf(stderr, "do_smb1_exit (1) failed\n"); + return false; + } + ok = do_smb1_exit(ev, ev, conn); + if (!ok) { + d_fprintf(stderr, "do_smb1_exit (2) failed\n"); + return false; + } + + TALLOC_FREE(conn); + return true; +} static bool run_ign_bad_negprot(int dummy) { @@ -14721,6 +15074,7 @@ static bool run_ign_bad_negprot(int dummy) return true; } + static double create_procs(bool (*fn)(int), bool *result) { int i, status; @@ -15373,6 +15727,14 @@ static struct { .name = "SMB2-DFS-FILENAME-LEADING-BACKSLASH", .fn = run_smb2_dfs_filename_leading_backslash, -- Samba Shared Repository