The branch, v4-18-stable has been updated via a597a8767fa VERSION: Disable GIT_SNAPSHOT for the 4.18.0 release. via c82ecf68b0b WHATSNEW: Add release notes for Samba 4.18.0. via 800f4f9cc9d s3: smbd: Fix fsp/fd leak when looking up a non-existent stream name on a file. via 3fb8f2c579c s3: tests: Add new test_stream_dir_rename.sh test. via f2c9d59e5a3 s3: provision: Add new streams_xattr_nostrict share - needs "strict rename = no". via 2030aa02ce0 rpcd: With npa->need_idle_server we can have more than 256 servers via 501ae551da9 rpcd: Do blocking connects to local pipes via 06483b02e9d rpcd: Increase listening queue via 04e0412a659 torture3: test rpc scalability via 73f99903244 librpc: Remove unused sync rpc_transport_np_init() via d6ce38a197d librpc: Make rpc_pipe_open_np() public and async via 18e45f2d89f VERSION: Bump version up to Samba 4.18.0rc5... from 746b83bbd89 VERSION: Disable GIT_SNAPSHOT for the 4.18.0rc4 release.
https://git.samba.org/?p=samba.git;a=shortlog;h=v4-18-stable - Log ----------------------------------------------------------------- ----------------------------------------------------------------------- Summary of changes: VERSION | 2 +- WHATSNEW.txt | 29 +-- selftest/target/Samba3.pm | 5 + source3/librpc/idl/rpc_host.idl | 2 +- source3/rpc_client/cli_pipe.c | 132 ++++++++--- source3/rpc_client/cli_pipe.h | 13 ++ source3/rpc_client/local_np.c | 14 +- source3/rpc_client/rpc_transport.h | 3 - source3/rpc_client/rpc_transport_np.c | 31 --- source3/rpc_server/rpc_host.c | 2 +- source3/rpc_server/rpc_worker.c | 2 +- source3/script/tests/test_stream_dir_rename.sh | 72 ++++++ source3/selftest/tests.py | 4 + source3/smbd/filename.c | 21 ++ source3/torture/proto.h | 1 + source3/torture/test_rpc_scale.c | 301 +++++++++++++++++++++++++ source3/torture/torture.c | 4 + source3/torture/wscript_build | 1 + 18 files changed, 555 insertions(+), 84 deletions(-) create mode 100755 source3/script/tests/test_stream_dir_rename.sh create mode 100644 source3/torture/test_rpc_scale.c Changeset truncated at 500 lines: diff --git a/VERSION b/VERSION index f08d67023df..db0cfae1f29 100644 --- a/VERSION +++ b/VERSION @@ -87,7 +87,7 @@ SAMBA_VERSION_PRE_RELEASE= # e.g. SAMBA_VERSION_RC_RELEASE=1 # # -> "3.0.0rc1" # ######################################################## -SAMBA_VERSION_RC_RELEASE=4 +SAMBA_VERSION_RC_RELEASE= ######################################################## # To mark SVN snapshots this should be set to 'yes' # diff --git a/WHATSNEW.txt b/WHATSNEW.txt index cb386f28fde..edd3c8828b0 100644 --- a/WHATSNEW.txt +++ b/WHATSNEW.txt @@ -1,17 +1,10 @@ -Release Announcements -===================== - -This is the fourth release candidate of Samba 4.18. This is *not* -intended for production environments and is designed for testing -purposes only. Please report any defects via the Samba bug reporting -system at https://bugzilla.samba.org/. - -Samba 4.18 will be the next version of the Samba suite. - - -UPGRADING -========= + ============================== + Release Notes for Samba 4.18.0 + March 08, 2023 + ============================== +This is the first stable release of the Samba 4.18 release series. +Please read the release notes carefully before upgrading. NEW FEATURES/CHANGES ==================== @@ -139,6 +132,16 @@ smb.conf changes server addresses New +CHANGES SINCE 4.18.0rc4 +======================= + +o Jeremy Allison <j...@samba.org> + * BUG 15314: streams_xattr is creating unexpected locks on folders. + +o Volker Lendecke <v...@samba.org> + * BUG 15310: New samba-dcerpc architecture does not scale gracefully. + + CHANGES SINCE 4.18.0rc3 ======================= diff --git a/selftest/target/Samba3.pm b/selftest/target/Samba3.pm index 6f93694f1b3..fec50961617 100755 --- a/selftest/target/Samba3.pm +++ b/selftest/target/Samba3.pm @@ -3459,6 +3459,11 @@ sub provision($$) copy = tmp vfs objects = streams_xattr xattr_tdb +[streams_xattr_nostrict] + copy = tmp + strict rename = no + vfs objects = streams_xattr xattr_tdb + [acl_streams_xattr] copy = tmp vfs objects = acl_xattr streams_xattr fake_acls xattr_tdb diff --git a/source3/librpc/idl/rpc_host.idl b/source3/librpc/idl/rpc_host.idl index 0fc3f9514aa..c8abb6c4379 100644 --- a/source3/librpc/idl/rpc_host.idl +++ b/source3/librpc/idl/rpc_host.idl @@ -66,7 +66,7 @@ interface rpc_host_msg /** * @brief Which of the processes of a helper prog is this from */ - uint8 worker_index; + uint32 worker_index; /** * @brief How many clients this process serves right now diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 5e26dc1806d..2af68b169af 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -3172,74 +3172,142 @@ static int rpc_pipe_client_np_ref_destructor(struct rpc_pipe_client_np_ref *np_r * ****************************************************************************/ -static NTSTATUS rpc_pipe_open_np(struct cli_state *cli, - const struct ndr_interface_table *table, - struct rpc_pipe_client **presult) -{ +struct rpc_pipe_open_np_state { + struct cli_state *cli; + const struct ndr_interface_table *table; struct rpc_pipe_client *result; - NTSTATUS status; - struct rpc_pipe_client_np_ref *np_ref; +}; + +static void rpc_pipe_open_np_done(struct tevent_req *subreq); - /* sanity check to protect against crashes */ +struct tevent_req *rpc_pipe_open_np_send( + TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct cli_state *cli, + const struct ndr_interface_table *table) +{ + struct tevent_req *req = NULL, *subreq = NULL; + struct rpc_pipe_open_np_state *state = NULL; + struct rpc_pipe_client *result = NULL; - if ( !cli ) { - return NT_STATUS_INVALID_HANDLE; + req = tevent_req_create( + mem_ctx, &state, struct rpc_pipe_open_np_state); + if (req == NULL) { + return NULL; } + state->cli = cli; + state->table = table; - result = talloc_zero(NULL, struct rpc_pipe_client); - if (result == NULL) { - return NT_STATUS_NO_MEMORY; + state->result = talloc_zero(state, struct rpc_pipe_client); + if (tevent_req_nomem(state->result, req)) { + return tevent_req_post(req, ev); } + result = state->result; result->abstract_syntax = table->syntax_id; result->transfer_syntax = ndr_transfer_syntax_ndr; result->desthost = talloc_strdup( result, smbXcli_conn_remote_name(cli->conn)); - if (result->desthost == NULL) { - TALLOC_FREE(result); - return NT_STATUS_NO_MEMORY; + if (tevent_req_nomem(result->desthost, req)) { + return tevent_req_post(req, ev); } result->srv_name_slash = talloc_asprintf_strupper_m( result, "\\\\%s", result->desthost); - if (result->srv_name_slash == NULL) { - TALLOC_FREE(result); - return NT_STATUS_NO_MEMORY; + if (tevent_req_nomem(result->srv_name_slash, req)) { + return tevent_req_post(req, ev); } result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN; - status = rpc_transport_np_init(result, cli, table, - &result->transport); - if (!NT_STATUS_IS_OK(status)) { - TALLOC_FREE(result); - return status; + subreq = rpc_transport_np_init_send(state, ev, cli, table); + if (tevent_req_nomem(subreq, req)) { + return tevent_req_post(req, ev); + } + tevent_req_set_callback(subreq, rpc_pipe_open_np_done, req); + return req; +} + +static void rpc_pipe_open_np_done(struct tevent_req *subreq) +{ + struct tevent_req *req = tevent_req_callback_data( + subreq, struct tevent_req); + struct rpc_pipe_open_np_state *state = tevent_req_data( + req, struct rpc_pipe_open_np_state); + struct rpc_pipe_client *result = state->result; + struct rpc_pipe_client_np_ref *np_ref = NULL; + NTSTATUS status; + + status = rpc_transport_np_init_recv( + subreq, result, &result->transport); + TALLOC_FREE(subreq); + if (tevent_req_nterror(req, status)) { + return; } result->transport->transport = NCACN_NP; np_ref = talloc(result->transport, struct rpc_pipe_client_np_ref); - if (np_ref == NULL) { - TALLOC_FREE(result); - return NT_STATUS_NO_MEMORY; + if (tevent_req_nomem(np_ref, req)) { + return; } - np_ref->cli = cli; + np_ref->cli = state->cli; np_ref->pipe = result; DLIST_ADD(np_ref->cli->pipe_list, np_ref->pipe); talloc_set_destructor(np_ref, rpc_pipe_client_np_ref_destructor); - result->binding_handle = rpccli_bh_create(result, NULL, table); - if (result->binding_handle == NULL) { - TALLOC_FREE(result); - return NT_STATUS_NO_MEMORY; + result->binding_handle = rpccli_bh_create(result, NULL, state->table); + if (tevent_req_nomem(result->binding_handle, req)) { + return; } - *presult = result; + tevent_req_done(req); +} + +NTSTATUS rpc_pipe_open_np_recv( + struct tevent_req *req, + TALLOC_CTX *mem_ctx, + struct rpc_pipe_client **_result) +{ + struct rpc_pipe_open_np_state *state = tevent_req_data( + req, struct rpc_pipe_open_np_state); + NTSTATUS status; + + if (tevent_req_is_nterror(req, &status)) { + return status; + } + *_result = talloc_move(mem_ctx, &state->result); return NT_STATUS_OK; } +NTSTATUS rpc_pipe_open_np(struct cli_state *cli, + const struct ndr_interface_table *table, + struct rpc_pipe_client **presult) +{ + struct tevent_context *ev = NULL; + struct tevent_req *req = NULL; + NTSTATUS status = NT_STATUS_NO_MEMORY; + + ev = samba_tevent_context_init(cli); + if (ev == NULL) { + goto fail; + } + req = rpc_pipe_open_np_send(ev, ev, cli, table); + if (req == NULL) { + goto fail; + } + if (!tevent_req_poll_ntstatus(req, ev, &status)) { + goto fail; + } + status = rpc_pipe_open_np_recv(req, NULL, presult); +fail: + TALLOC_FREE(req); + TALLOC_FREE(ev); + return status; +} + /**************************************************************************** Open a pipe to a remote server. ****************************************************************************/ diff --git a/source3/rpc_client/cli_pipe.h b/source3/rpc_client/cli_pipe.h index d7b175456ed..d9826ca8e5c 100644 --- a/source3/rpc_client/cli_pipe.h +++ b/source3/rpc_client/cli_pipe.h @@ -38,6 +38,19 @@ NTSTATUS rpc_pipe_bind_recv(struct tevent_req *req); NTSTATUS rpc_pipe_bind(struct rpc_pipe_client *cli, struct pipe_auth_data *auth); +struct tevent_req *rpc_pipe_open_np_send( + TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct cli_state *cli, + const struct ndr_interface_table *table); +NTSTATUS rpc_pipe_open_np_recv( + struct tevent_req *req, + TALLOC_CTX *mem_ctx, + struct rpc_pipe_client **_result); +NTSTATUS rpc_pipe_open_np(struct cli_state *cli, + const struct ndr_interface_table *table, + struct rpc_pipe_client **presult); + unsigned int rpccli_set_timeout(struct rpc_pipe_client *cli, unsigned int timeout); diff --git a/source3/rpc_client/local_np.c b/source3/rpc_client/local_np.c index 5b1a818c88d..f1d61a09ee3 100644 --- a/source3/rpc_client/local_np.c +++ b/source3/rpc_client/local_np.c @@ -101,7 +101,7 @@ static struct tevent_req *np_sock_connect_send( return tevent_req_post(req, ev); } - ret = set_blocking(state->sock, false); + ret = set_blocking(state->sock, true); if (ret == -1) { tevent_req_error(req, errno); return tevent_req_post(req, ev); @@ -174,6 +174,18 @@ static void np_sock_connect_connected(struct tevent_req *subreq) return; } + /* + * As a quick workaround for bug 15310 we have done the + * connect in blocking mode (see np_sock_connect_send()). The + * rest of our code expects a nonblocking socket, activate + * this after the connect succeeded. + */ + ret = set_blocking(state->sock, false); + if (ret == -1) { + tevent_req_error(req, errno); + return; + } + ret = tstream_bsd_existing_socket( state, state->sock, &state->transport); if (ret == -1) { diff --git a/source3/rpc_client/rpc_transport.h b/source3/rpc_client/rpc_transport.h index 1c774583bdc..dccfa36cdc5 100644 --- a/source3/rpc_client/rpc_transport.h +++ b/source3/rpc_client/rpc_transport.h @@ -88,9 +88,6 @@ struct tevent_req *rpc_transport_np_init_send(TALLOC_CTX *mem_ctx, NTSTATUS rpc_transport_np_init_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, struct rpc_cli_transport **presult); -NTSTATUS rpc_transport_np_init(TALLOC_CTX *mem_ctx, struct cli_state *cli, - const struct ndr_interface_table *table, - struct rpc_cli_transport **presult); /* The following definitions come from rpc_client/rpc_transport_sock.c */ diff --git a/source3/rpc_client/rpc_transport_np.c b/source3/rpc_client/rpc_transport_np.c index 27e38235ca0..fbe9a35aa3d 100644 --- a/source3/rpc_client/rpc_transport_np.c +++ b/source3/rpc_client/rpc_transport_np.c @@ -177,34 +177,3 @@ NTSTATUS rpc_transport_np_init_recv(struct tevent_req *req, *presult = talloc_move(mem_ctx, &state->transport); return NT_STATUS_OK; } - -NTSTATUS rpc_transport_np_init(TALLOC_CTX *mem_ctx, struct cli_state *cli, - const struct ndr_interface_table *table, - struct rpc_cli_transport **presult) -{ - TALLOC_CTX *frame = talloc_stackframe(); - struct tevent_context *ev; - struct tevent_req *req; - NTSTATUS status = NT_STATUS_OK; - - ev = samba_tevent_context_init(frame); - if (ev == NULL) { - status = NT_STATUS_NO_MEMORY; - goto fail; - } - - req = rpc_transport_np_init_send(frame, ev, cli, table); - if (req == NULL) { - status = NT_STATUS_NO_MEMORY; - goto fail; - } - - if (!tevent_req_poll_ntstatus(req, ev, &status)) { - goto fail; - } - - status = rpc_transport_np_init_recv(req, mem_ctx, presult); - fail: - TALLOC_FREE(frame); - return status; -} diff --git a/source3/rpc_server/rpc_host.c b/source3/rpc_server/rpc_host.c index f58c825e7cc..a5b3f1de819 100644 --- a/source3/rpc_server/rpc_host.c +++ b/source3/rpc_server/rpc_host.c @@ -1689,7 +1689,7 @@ static void rpc_server_setup_got_endpoints(struct tevent_req *subreq) } for (j=0; j<e->num_fds; j++) { - ret = listen(e->fds[j], 5); + ret = listen(e->fds[j], 256); if (ret == -1) { tevent_req_nterror( req, map_nt_error_from_unix(errno)); diff --git a/source3/rpc_server/rpc_worker.c b/source3/rpc_server/rpc_worker.c index 1bc84531e55..11f6a721a63 100644 --- a/source3/rpc_server/rpc_worker.c +++ b/source3/rpc_server/rpc_worker.c @@ -93,7 +93,7 @@ static void rpc_worker_print_interface( static NTSTATUS rpc_worker_report_status(struct rpc_worker *worker) { - uint8_t buf[6]; + uint8_t buf[9]; DATA_BLOB blob = { .data = buf, .length = sizeof(buf), }; enum ndr_err_code ndr_err; NTSTATUS status; diff --git a/source3/script/tests/test_stream_dir_rename.sh b/source3/script/tests/test_stream_dir_rename.sh new file mode 100755 index 00000000000..7ac3194f649 --- /dev/null +++ b/source3/script/tests/test_stream_dir_rename.sh @@ -0,0 +1,72 @@ +#!/bin/sh +# +# Test a stream can rename a directory once an invalid stream path below it was requested. +# BUG: https://bugzilla.samba.org/show_bug.cgi?id=15314 + +if [ $# -lt 5 ]; then + cat <<EOF +Usage: test_stream_dir_rename.sh SERVER USERNAME PASSWORD PREFIX SMBCLIENT +EOF + exit 1 +fi + +SERVER="${1}" +USERNAME="${2}" +PASSWORD="${3}" +PREFIX="${4}" +SMBCLIENT="${5}" +SMBCLIENT="$VALGRIND ${SMBCLIENT}" +shift 5 + +incdir=$(dirname $0)/../../../testprogs/blackbox +. $incdir/subunit.sh + +failed=0 + +# Do not let deprecated option warnings muck this up +SAMBA_DEPRECATED_SUPPRESS=1 +export SAMBA_DEPRECATED_SUPPRESS + +test_stream_xattr_rename() +{ + tmpfile=$PREFIX/smbclient_interactive_prompt_commands + # + # Test against streams_xattr_nostrict + # + cat >$tmpfile <<EOF +deltree stream_xattr_test +deltree stream_xattr_test1 +mkdir stream_xattr_test +put ${PREFIX}/smbclient_interactive_prompt_commands stream_xattr_test/file.txt +get stream_xattr_test/file.txt:abcf +rename stream_xattr_test stream_xattr_test1 +deltree stream_xattr_test +deltree stream_xattr_test1 +quit +EOF + cmd='CLI_FORCE_INTERACTIVE=yes $SMBCLIENT "$@" -U$USERNAME%$PASSWORD //$SERVER/streams_xattr_nostrict < $tmpfile 2>&1' + eval echo "$cmd" + out=$(eval $cmd) + ret=$? + rm -f $tmpfile + + if [ $ret -ne 0 ]; then + echo "$out" + echo "failed rename on xattr stream test to test1 with error $ret" + return 1 + fi + + echo "$out" | grep "NT_STATUS_ACCESS_DENIED" + ret=$? + if [ $ret -eq 0 ]; then + echo "$out" + echo "failed rename on xattr stream with NT_STATUS_ACCESS_DENIED" + return 1 + fi +} + +testit "stream_rename" \ + test_stream_xattr_rename || + failed=$((failed + 1)) + +testok "$0" "$failed" diff --git a/source3/selftest/tests.py b/source3/selftest/tests.py index 93fb4a97f89..eab160908ea 100755 --- a/source3/selftest/tests.py +++ b/source3/selftest/tests.py @@ -773,6 +773,10 @@ for env in ["fileserver"]: [os.path.join(samba3srcdir, "script/tests/test_veto_files.sh"), '$SERVER', '$SERVER_IP', '$USERNAME', '$PASSWORD', '$LOCAL_PATH/veto', smbclient3]) + plantestsuite("samba3.blackbox.stream_dir_rename", env, + [os.path.join(samba3srcdir, "script/tests/test_stream_dir_rename.sh"), + '$SERVER', '$USERNAME', '$PASSWORD', '$PREFIX', smbclient3]) + # # tar command tests # diff --git a/source3/smbd/filename.c b/source3/smbd/filename.c index 73e88add2c3..b7160af0cfd 100644 --- a/source3/smbd/filename.c +++ b/source3/smbd/filename.c @@ -1378,6 +1378,16 @@ static NTSTATUS filename_convert_dirfsp_nosymlink( status = NT_STATUS_NO_MEMORY; -- Samba Shared Repository