The Samba-Bugzilla – Attachment 6553 Details for
Bug 8195
rpc client code doesn't work against NT4, when we need to fragment requests
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
Patch for the cli_trans and cli_read/write problems (for master)
tmp2.diff (text/plain), 30.59 KB, created by
Stefan Metzmacher
on 2011-06-09 18:29:21 UTC
(
hide
)
Description:
Patch for the cli_trans and cli_read/write problems (for master)
Filename:
MIME Type:
Creator:
Stefan Metzmacher
Created:
2011-06-09 18:29:21 UTC
Size:
30.59 KB
patch
obsolete
>From ccd6d66c0ab4db4ae8215a52d6f591ef95c7d67a Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Wed, 8 Jun 2011 00:40:54 +0200 >Subject: [PATCH 01/15] s3:libsmb/async_smb: let cli_smb_recv() initialize output values for one way requests > >metze >--- > source3/libsmb/async_smb.c | 18 ++++++++++++++++++ > 1 files changed, 18 insertions(+), 0 deletions(-) > >diff --git a/source3/libsmb/async_smb.c b/source3/libsmb/async_smb.c >index 2ce6410..45e83b8 100644 >--- a/source3/libsmb/async_smb.c >+++ b/source3/libsmb/async_smb.c >@@ -694,6 +694,24 @@ NTSTATUS cli_smb_recv(struct tevent_req *req, > } > > if (state->inbuf == NULL) { >+ if (min_wct != 0) { >+ return NT_STATUS_INVALID_NETWORK_RESPONSE; >+ } >+ if (pinbuf) { >+ *pinbuf = NULL; >+ } >+ if (pwct) { >+ *pwct = 0; >+ } >+ if (pvwv) { >+ *pvwv = NULL; >+ } >+ if (pnum_bytes) { >+ *pnum_bytes = 0; >+ } >+ if (pbytes) { >+ *pbytes = NULL; >+ } > /* This was a request without a reply */ > return NT_STATUS_OK; > } >-- >1.7.4.1 > > >From 8fe9e5e4393c0a6f3771b2031c35dc9cfd6da6ad Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Wed, 8 Jun 2011 14:14:24 +0200 >Subject: [PATCH 02/15] s3:libsmb/async_smb: call cli_smb_req_unset_pending() instead of destructor directly > >metze >--- > source3/libsmb/async_smb.c | 4 ++-- > 1 files changed, 2 insertions(+), 2 deletions(-) > >diff --git a/source3/libsmb/async_smb.c b/source3/libsmb/async_smb.c >index 45e83b8..2e0ddb9 100644 >--- a/source3/libsmb/async_smb.c >+++ b/source3/libsmb/async_smb.c >@@ -627,7 +627,7 @@ static void cli_smb_received(struct tevent_req *subreq) > if (state->chained_requests == NULL) { > state->inbuf = talloc_move(state, &inbuf); > talloc_set_destructor(req, NULL); >- cli_smb_req_destructor(req); >+ cli_smb_req_unset_pending(req); > state->chain_num = 0; > state->chain_length = 1; > tevent_req_done(req); >@@ -671,7 +671,7 @@ static void cli_smb_received(struct tevent_req *subreq) > while (talloc_array_length(cli->pending) > 0) { > req = cli->pending[0]; > talloc_set_destructor(req, NULL); >- cli_smb_req_destructor(req); >+ cli_smb_req_unset_pending(req); > tevent_req_nterror(req, status); > } > } >-- >1.7.4.1 > > >From c5acf3c48dadb485c92ed5e9a397d305d67386f8 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Wed, 8 Jun 2011 10:20:25 +0200 >Subject: [PATCH 03/15] s3:libsmb/async_smb: don't remove pending requests if the mid is set > >If the mid was set explicitly, it means the request expects more than >one reply, so leave it in the pending array. > >metze >--- > source3/libsmb/async_smb.c | 15 +++++++++++++++ > 1 files changed, 15 insertions(+), 0 deletions(-) > >diff --git a/source3/libsmb/async_smb.c b/source3/libsmb/async_smb.c >index 2e0ddb9..c09a886 100644 >--- a/source3/libsmb/async_smb.c >+++ b/source3/libsmb/async_smb.c >@@ -153,6 +153,14 @@ void cli_smb_req_unset_pending(struct tevent_req *req) > int num_pending = talloc_array_length(cli->pending); > int i; > >+ if (state->mid != 0) { >+ /* >+ * This is a [nt]trans[2] request which waits >+ * for more than one reply. >+ */ >+ return; >+ } >+ > if (num_pending == 1) { > /* > * The pending read_smb tevent_req is a child of >@@ -193,6 +201,13 @@ void cli_smb_req_unset_pending(struct tevent_req *req) > > static int cli_smb_req_destructor(struct tevent_req *req) > { >+ struct cli_smb_state *state = tevent_req_data( >+ req, struct cli_smb_state); >+ /* >+ * Make sure we really remove it from >+ * the pending array on destruction. >+ */ >+ state->mid = 0; > cli_smb_req_unset_pending(req); > return 0; > } >-- >1.7.4.1 > > >From d7b1d6bca7a73307cf1e351af64e39ce3da1316f Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Thu, 9 Jun 2011 11:49:48 +0200 >Subject: [PATCH 04/15] s3:libsmb/async_smb: add helpers to get and set the seqnum for signing > >This will be used for correct signing in [nt]trans[2][s] requests. > >metze >--- > source3/include/async_smb.h | 2 ++ > source3/libsmb/async_smb.c | 14 ++++++++++++++ > 2 files changed, 16 insertions(+), 0 deletions(-) > >diff --git a/source3/include/async_smb.h b/source3/include/async_smb.h >index a8852b2..1685d49 100644 >--- a/source3/include/async_smb.h >+++ b/source3/include/async_smb.h >@@ -51,6 +51,8 @@ void cli_smb_req_unset_pending(struct tevent_req *req); > bool cli_smb_req_set_pending(struct tevent_req *req); > uint16_t cli_smb_req_mid(struct tevent_req *req); > void cli_smb_req_set_mid(struct tevent_req *req, uint16_t mid); >+uint32_t cli_smb_req_seqnum(struct tevent_req *req); >+void cli_smb_req_set_seqnum(struct tevent_req *req, uint32_t seqnum); > struct tevent_req *cli_smb_send(TALLOC_CTX *mem_ctx, struct event_context *ev, > struct cli_state *cli, > uint8_t smb_command, uint8_t additional_flags, >diff --git a/source3/libsmb/async_smb.c b/source3/libsmb/async_smb.c >index c09a886..145e0ae 100644 >--- a/source3/libsmb/async_smb.c >+++ b/source3/libsmb/async_smb.c >@@ -270,6 +270,20 @@ void cli_smb_req_set_mid(struct tevent_req *req, uint16_t mid) > state->mid = mid; > } > >+uint32_t cli_smb_req_seqnum(struct tevent_req *req) >+{ >+ struct cli_smb_state *state = tevent_req_data( >+ req, struct cli_smb_state); >+ return state->seqnum; >+} >+ >+void cli_smb_req_set_seqnum(struct tevent_req *req, uint32_t seqnum) >+{ >+ struct cli_smb_state *state = tevent_req_data( >+ req, struct cli_smb_state); >+ state->seqnum = seqnum; >+} >+ > static size_t iov_len(const struct iovec *iov, int count) > { > size_t result = 0; >-- >1.7.4.1 > > >From 7b9b0635b6843d02e6c2a749c755d1b58bc7f683 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Wed, 8 Jun 2011 00:37:24 +0200 >Subject: [PATCH 05/15] s3:libsmb/clitrans: remove unused secondary_request_ctx > >metze >--- > source3/libsmb/clitrans.c | 2 -- > 1 files changed, 0 insertions(+), 2 deletions(-) > >diff --git a/source3/libsmb/clitrans.c b/source3/libsmb/clitrans.c >index 99a358f..e53f51b 100644 >--- a/source3/libsmb/clitrans.c >+++ b/source3/libsmb/clitrans.c >@@ -52,8 +52,6 @@ struct cli_trans_state { > struct trans_recvblob rdata; > uint16_t recv_flags2; > >- TALLOC_CTX *secondary_request_ctx; >- > struct iovec iov[4]; > uint8_t pad[4]; > uint16_t vwv[32]; >-- >1.7.4.1 > > >From 4ab5e7b9a47a650fbc7d1f2efcd2c40a29378186 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Wed, 8 Jun 2011 17:08:00 +0200 >Subject: [PATCH 06/15] s3:libsmb/clitrans: use uint32_t for param and data variables > >SMBnttrans uses 32-bit values there. > >metze >--- > source3/libsmb/clitrans.c | 6 +++--- > 1 files changed, 3 insertions(+), 3 deletions(-) > >diff --git a/source3/libsmb/clitrans.c b/source3/libsmb/clitrans.c >index e53f51b..8017948 100644 >--- a/source3/libsmb/clitrans.c >+++ b/source3/libsmb/clitrans.c >@@ -171,9 +171,9 @@ static void cli_trans_format(struct cli_trans_state *state, uint8_t *pwct, > struct iovec *iov = state->iov; > uint8_t *pad = state->pad; > uint16_t *vwv = state->vwv; >- uint16_t param_offset; >- uint16_t this_param = 0; >- uint16_t this_data = 0; >+ uint32_t param_offset; >+ uint32_t this_param = 0; >+ uint32_t this_data = 0; > uint32_t useable_space; > uint8_t cmd; > >-- >1.7.4.1 > > >From 27dfd48a5aaf68111aa30110ee8a83a769d2dfc4 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Thu, 9 Jun 2011 12:22:59 +0200 >Subject: [PATCH 07/15] s3:libsmb/clitrans: marshall SMBnttrans[2] as the others > >This is just to make the code more readable >and easier to notice how many words we're using in vwv. > >metze >--- > source3/libsmb/clitrans.c | 46 ++++++++++++++++++++++---------------------- > 1 files changed, 23 insertions(+), 23 deletions(-) > >diff --git a/source3/libsmb/clitrans.c b/source3/libsmb/clitrans.c >index 8017948..d8cd8e8 100644 >--- a/source3/libsmb/clitrans.c >+++ b/source3/libsmb/clitrans.c >@@ -289,33 +289,33 @@ static void cli_trans_format(struct cli_trans_state *state, uint8_t *pwct, > } > break; > case SMBnttrans: >- SCVAL(vwv, 0, state->max_setup); >- SSVAL(vwv, 1, 0); /* reserved */ >- SIVAL(vwv, 3, state->num_param); >- SIVAL(vwv, 7, state->num_data); >- SIVAL(vwv, 11, state->rparam.max); >- SIVAL(vwv, 15, state->rdata.max); >- SIVAL(vwv, 19, this_param); >- SIVAL(vwv, 23, param_offset); >- SIVAL(vwv, 27, this_data); >- SIVAL(vwv, 31, param_offset + this_param); >- SCVAL(vwv, 35, state->num_setup); >- SSVAL(vwv, 36, state->function); >+ SCVAL(vwv + 0, 0, state->max_setup); >+ SSVAL(vwv + 0, 1, 0); /* reserved */ >+ SIVAL(vwv + 1, 1, state->num_param); >+ SIVAL(vwv + 3, 1, state->num_data); >+ SIVAL(vwv + 5, 1, state->rparam.max); >+ SIVAL(vwv + 7, 1, state->rdata.max); >+ SIVAL(vwv + 9, 1, this_param); >+ SIVAL(vwv +11, 1, param_offset); >+ SIVAL(vwv +13, 1, this_data); >+ SIVAL(vwv +15, 1, param_offset + this_param); >+ SCVAL(vwv +17, 1, state->num_setup); >+ SSVAL(vwv +18, 0, state->function); > memcpy(vwv + 19, state->setup, > sizeof(uint16_t) * state->num_setup); > break; > case SMBnttranss: >- SSVAL(vwv, 0, 0); /* reserved */ >- SCVAL(vwv, 2, 0); /* reserved */ >- SIVAL(vwv, 3, state->num_param); >- SIVAL(vwv, 7, state->num_data); >- SIVAL(vwv, 11, this_param); >- SIVAL(vwv, 15, param_offset); >- SIVAL(vwv, 19, state->param_sent); >- SIVAL(vwv, 23, this_data); >- SIVAL(vwv, 27, param_offset + this_param); >- SIVAL(vwv, 31, state->data_sent); >- SCVAL(vwv, 35, 0); /* reserved */ >+ SSVAL(vwv + 0, 0, 0); /* reserved */ >+ SCVAL(vwv + 1, 0, 0); /* reserved */ >+ SIVAL(vwv + 1, 1, state->num_param); >+ SIVAL(vwv + 3, 1, state->num_data); >+ SIVAL(vwv + 5, 1, this_param); >+ SIVAL(vwv + 7, 1, param_offset); >+ SIVAL(vwv + 9, 1, state->param_sent); >+ SIVAL(vwv +11, 1, this_data); >+ SIVAL(vwv +13, 1, param_offset + this_param); >+ SIVAL(vwv +15, 1, state->data_sent); >+ SCVAL(vwv +17, 1, 0); /* reserved */ > break; > } > >-- >1.7.4.1 > > >From 1b0108d33d41072f3f654d96e202a9b859a7ca0b Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Wed, 8 Jun 2011 00:44:34 +0200 >Subject: [PATCH 08/15] s3:libsmb/clitrans: correctly marshall [nt]trans[s][2] requests > >We need to align params and data to 4 byte offsets. > >This also correctly recalculates the useable space after each step. > >metze >--- > source3/libsmb/clitrans.c | 53 ++++++++++++++++++++++++++++++++++---------- > 1 files changed, 41 insertions(+), 12 deletions(-) > >diff --git a/source3/libsmb/clitrans.c b/source3/libsmb/clitrans.c >index d8cd8e8..cf6809b 100644 >--- a/source3/libsmb/clitrans.c >+++ b/source3/libsmb/clitrans.c >@@ -52,8 +52,9 @@ struct cli_trans_state { > struct trans_recvblob rdata; > uint16_t recv_flags2; > >- struct iovec iov[4]; >+ struct iovec iov[6]; > uint8_t pad[4]; >+ uint8_t zero_pad[4]; > uint16_t vwv[32]; > }; > >@@ -173,7 +174,10 @@ static void cli_trans_format(struct cli_trans_state *state, uint8_t *pwct, > uint16_t *vwv = state->vwv; > uint32_t param_offset; > uint32_t this_param = 0; >+ uint32_t param_pad; >+ uint32_t data_offset; > uint32_t this_data = 0; >+ uint32_t data_pad; > uint32_t useable_space; > uint8_t cmd; > >@@ -221,7 +225,18 @@ static void cli_trans_format(struct cli_trans_state *state, uint8_t *pwct, > break; > } > >- useable_space = state->cli->max_xmit - smb_size - sizeof(uint16_t)*wct; >+ param_offset += wct * sizeof(uint16_t); >+ useable_space = state->cli->max_xmit - param_offset; >+ >+ param_pad = param_offset % 4; >+ if (param_pad > 0) { >+ param_pad = MIN(param_pad, useable_space); >+ iov[0].iov_base = (void *)state->zero_pad; >+ iov[0].iov_len = param_pad; >+ iov += 1; >+ param_offset += param_pad; >+ } >+ useable_space = state->cli->max_xmit - param_offset; > > if (state->param_sent < state->num_param) { > this_param = MIN(state->num_param - state->param_sent, >@@ -231,27 +246,41 @@ static void cli_trans_format(struct cli_trans_state *state, uint8_t *pwct, > iov += 1; > } > >+ data_offset = param_offset + this_param; >+ useable_space = state->cli->max_xmit - data_offset; >+ >+ data_pad = data_offset % 4; >+ if (data_pad > 0) { >+ data_pad = MIN(data_pad, useable_space); >+ iov[0].iov_base = (void *)state->zero_pad; >+ iov[0].iov_len = data_pad; >+ iov += 1; >+ data_offset += data_pad; >+ } >+ useable_space = state->cli->max_xmit - data_offset; >+ > if (state->data_sent < state->num_data) { > this_data = MIN(state->num_data - state->data_sent, >- useable_space - this_param); >+ useable_space); > iov[0].iov_base = (void *)(state->data + state->data_sent); > iov[0].iov_len = this_data; > iov += 1; > } > >- param_offset += wct * sizeof(uint16_t); >- > DEBUG(10, ("num_setup=%u, max_setup=%u, " > "param_total=%u, this_param=%u, max_param=%u, " > "data_total=%u, this_data=%u, max_data=%u, " >- "param_offset=%u, param_disp=%u, data_disp=%u\n", >+ "param_offset=%u, param_pad=%u, param_disp=%u, " >+ "data_offset=%u, data_pad=%u, data_disp=%u\n", > (unsigned)state->num_setup, (unsigned)state->max_setup, > (unsigned)state->num_param, (unsigned)this_param, > (unsigned)state->rparam.max, > (unsigned)state->num_data, (unsigned)this_data, > (unsigned)state->rdata.max, >- (unsigned)param_offset, >- (unsigned)state->param_sent, (unsigned)state->data_sent)); >+ (unsigned)param_offset, (unsigned)param_pad, >+ (unsigned)state->param_sent, >+ (unsigned)data_offset, (unsigned)data_pad, >+ (unsigned)state->data_sent)); > > switch (cmd) { > case SMBtrans: >@@ -268,7 +297,7 @@ static void cli_trans_format(struct cli_trans_state *state, uint8_t *pwct, > SSVAL(vwv + 9, 0, this_param); > SSVAL(vwv +10, 0, param_offset); > SSVAL(vwv +11, 0, this_data); >- SSVAL(vwv +12, 0, param_offset + this_param); >+ SSVAL(vwv +12, 0, data_offset); > SCVAL(vwv +13, 0, state->num_setup); > SCVAL(vwv +13, 1, 0); /* reserved */ > memcpy(vwv + 14, state->setup, >@@ -282,7 +311,7 @@ static void cli_trans_format(struct cli_trans_state *state, uint8_t *pwct, > SSVAL(vwv + 3, 0, param_offset); > SSVAL(vwv + 4, 0, state->param_sent); > SSVAL(vwv + 5, 0, this_data); >- SSVAL(vwv + 6, 0, param_offset + this_param); >+ SSVAL(vwv + 6, 0, data_offset); > SSVAL(vwv + 7, 0, state->data_sent); > if (cmd == SMBtranss2) { > SSVAL(vwv + 8, 0, state->fid); >@@ -298,7 +327,7 @@ static void cli_trans_format(struct cli_trans_state *state, uint8_t *pwct, > SIVAL(vwv + 9, 1, this_param); > SIVAL(vwv +11, 1, param_offset); > SIVAL(vwv +13, 1, this_data); >- SIVAL(vwv +15, 1, param_offset + this_param); >+ SIVAL(vwv +15, 1, data_offset); > SCVAL(vwv +17, 1, state->num_setup); > SSVAL(vwv +18, 0, state->function); > memcpy(vwv + 19, state->setup, >@@ -313,7 +342,7 @@ static void cli_trans_format(struct cli_trans_state *state, uint8_t *pwct, > SIVAL(vwv + 7, 1, param_offset); > SIVAL(vwv + 9, 1, state->param_sent); > SIVAL(vwv +11, 1, this_data); >- SIVAL(vwv +13, 1, param_offset + this_param); >+ SIVAL(vwv +13, 1, data_offset); > SIVAL(vwv +15, 1, state->data_sent); > SCVAL(vwv +17, 1, 0); /* reserved */ > break; >-- >1.7.4.1 > > >From d8f19cf3c5d63e1a1ff476285e45712013e8b8ee Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Wed, 8 Jun 2011 16:11:00 +0200 >Subject: [PATCH 09/15] s3:libsmb/clitrans: move MID handling to the end of cli_trans_send() and add a comment > >metze >--- > source3/libsmb/clitrans.c | 13 +++++++++++-- > 1 files changed, 11 insertions(+), 2 deletions(-) > >diff --git a/source3/libsmb/clitrans.c b/source3/libsmb/clitrans.c >index cf6809b..82a73ee 100644 >--- a/source3/libsmb/clitrans.c >+++ b/source3/libsmb/clitrans.c >@@ -441,14 +441,23 @@ struct tevent_req *cli_trans_send( > if (tevent_req_nomem(subreq, req)) { > return tevent_req_post(req, ev); > } >- state->mid = cli_smb_req_mid(subreq); > status = cli_smb_req_send(subreq); > if (!NT_STATUS_IS_OK(status)) { > tevent_req_nterror(req, status); > return tevent_req_post(req, state->ev); > } >- cli_state_seqnum_persistent(cli, state->mid); > tevent_req_set_callback(subreq, cli_trans_done, req); >+ >+ /* >+ * Now get the MID of the primary request >+ * and mark it as persistent. This means >+ * we will able to send and receive multiple >+ * SMB pdus using this MID in both directions >+ * (including correct SMB signing). >+ */ >+ state->mid = cli_smb_req_mid(subreq); >+ cli_state_seqnum_persistent(cli, state->mid); >+ > return req; > } > >-- >1.7.4.1 > > >From 39ee9849dd7ee33ea819fc6745794994e96f584d Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Wed, 8 Jun 2011 16:41:11 +0200 >Subject: [PATCH 10/15] s3:libsmb/clitrans: use subreq2 as variable for the secondary requests > >metze >--- > source3/libsmb/clitrans.c | 16 +++++++++------- > 1 files changed, 9 insertions(+), 7 deletions(-) > >diff --git a/source3/libsmb/clitrans.c b/source3/libsmb/clitrans.c >index 82a73ee..cf1f725 100644 >--- a/source3/libsmb/clitrans.c >+++ b/source3/libsmb/clitrans.c >@@ -516,25 +516,27 @@ static void cli_trans_done(struct tevent_req *subreq) > > if (!sent_all) { > int iov_count; >+ struct tevent_req *subreq2; > > TALLOC_FREE(subreq); > > cli_trans_format(state, &wct, &iov_count); > >- subreq = cli_smb_req_create(state, state->ev, state->cli, >- state->cmd + 1, 0, wct, state->vwv, >- iov_count, state->iov); >- if (tevent_req_nomem(subreq, req)) { >+ subreq2 = cli_smb_req_create(state, state->ev, state->cli, >+ state->cmd + 1, 0, wct, state->vwv, >+ iov_count, state->iov); >+ if (tevent_req_nomem(subreq2, req)) { > return; > } >- cli_smb_req_set_mid(subreq, state->mid); >+ cli_smb_req_set_mid(subreq2, state->mid); > >- status = cli_smb_req_send(subreq); >+ status = cli_smb_req_send(subreq2); > > if (!NT_STATUS_IS_OK(status)) { > goto fail; > } >- tevent_req_set_callback(subreq, cli_trans_done, req); >+ tevent_req_set_callback(subreq2, cli_trans_done2, req); >+ > return; > } > >-- >1.7.4.1 > > >From 42d0e3f569c3770e62b1831fc175d454a4301e66 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Wed, 8 Jun 2011 10:31:23 +0200 >Subject: [PATCH 11/15] s3:libsmb/clitrans: fix handling of multi pdu [nt]trans[s][2] calls > >We now keep the primary request open for the whole logical request. >The primary request is the one that gets all incoming replies. >While secondary requests are handled as separate one-way requests. > >metze >--- > source3/libsmb/clitrans.c | 88 ++++++++++++++++++++++++++++++++++++++++---- > 1 files changed, 80 insertions(+), 8 deletions(-) > >diff --git a/source3/libsmb/clitrans.c b/source3/libsmb/clitrans.c >index cf1f725..e23598c 100644 >--- a/source3/libsmb/clitrans.c >+++ b/source3/libsmb/clitrans.c >@@ -56,8 +56,26 @@ struct cli_trans_state { > uint8_t pad[4]; > uint8_t zero_pad[4]; > uint16_t vwv[32]; >+ >+ struct tevent_req *primary_subreq; > }; > >+static void cli_trans_cleanup_primary(struct cli_trans_state *state) >+{ >+ if (state->primary_subreq) { >+ cli_smb_req_set_mid(state->primary_subreq, 0); >+ cli_smb_req_unset_pending(state->primary_subreq); >+ cli_state_seqnum_remove(state->cli, state->mid); >+ TALLOC_FREE(state->primary_subreq); >+ } >+} >+ >+static int cli_trans_state_destructor(struct cli_trans_state *state) >+{ >+ cli_trans_cleanup_primary(state); >+ return 0; >+} >+ > static NTSTATUS cli_pull_trans(uint8_t *inbuf, > uint8_t wct, uint16_t *vwv, > uint16_t num_bytes, uint8_t *bytes, >@@ -456,11 +474,16 @@ struct tevent_req *cli_trans_send( > * (including correct SMB signing). > */ > state->mid = cli_smb_req_mid(subreq); >+ cli_smb_req_set_mid(subreq, state->mid); > cli_state_seqnum_persistent(cli, state->mid); >+ state->primary_subreq = subreq; >+ talloc_set_destructor(state, cli_trans_state_destructor); > > return req; > } > >+static void cli_trans_done2(struct tevent_req *subreq); >+ > static void cli_trans_done(struct tevent_req *subreq) > { > struct tevent_req *req = tevent_req_callback_data( >@@ -518,8 +541,6 @@ static void cli_trans_done(struct tevent_req *subreq) > int iov_count; > struct tevent_req *subreq2; > >- TALLOC_FREE(subreq); >- > cli_trans_format(state, &wct, &iov_count); > > subreq2 = cli_smb_req_create(state, state->ev, state->cli, >@@ -561,23 +582,72 @@ static void cli_trans_done(struct tevent_req *subreq) > if ((state->rparam.total == state->rparam.received) > && (state->rdata.total == state->rdata.received)) { > state->recv_flags2 = SVAL(inbuf, smb_flg2); >- TALLOC_FREE(subreq); >- cli_state_seqnum_remove(state->cli, state->mid); >+ cli_trans_cleanup_primary(state); > tevent_req_done(req); > return; > } > > TALLOC_FREE(inbuf); > >- if (!cli_smb_req_set_pending(subreq)) { >- status = NT_STATUS_NO_MEMORY; >+ return; >+ >+ fail: >+ cli_trans_cleanup_primary(state); >+ tevent_req_nterror(req, status); >+} >+ >+static void cli_trans_done2(struct tevent_req *subreq2) >+{ >+ struct tevent_req *req = tevent_req_callback_data( >+ subreq2, struct tevent_req); >+ struct cli_trans_state *state = tevent_req_data( >+ req, struct cli_trans_state); >+ NTSTATUS status; >+ bool sent_all; >+ uint8_t wct; >+ >+ status = cli_smb_recv(subreq2, state, NULL, 0, &wct, NULL, >+ NULL, NULL); >+ TALLOC_FREE(subreq2); >+ >+ if (!NT_STATUS_IS_OK(status)) { > goto fail; > } >+ >+ if (wct != 0) { >+ status = NT_STATUS_INVALID_NETWORK_RESPONSE; >+ goto fail; >+ } >+ >+ sent_all = ((state->param_sent == state->num_param) >+ && (state->data_sent == state->num_data)); >+ >+ if (!sent_all) { >+ int iov_count; >+ >+ cli_trans_format(state, &wct, &iov_count); >+ >+ subreq2 = cli_smb_req_create(state, state->ev, state->cli, >+ state->cmd + 1, 0, wct, state->vwv, >+ iov_count, state->iov); >+ if (tevent_req_nomem(subreq2, req)) { >+ return; >+ } >+ cli_smb_req_set_mid(subreq2, state->mid); >+ >+ status = cli_smb_req_send(subreq2); >+ >+ if (!NT_STATUS_IS_OK(status)) { >+ goto fail; >+ } >+ tevent_req_set_callback(subreq2, cli_trans_done2, req); >+ return; >+ } >+ > return; > > fail: >- cli_state_seqnum_remove(state->cli, state->mid); >- TALLOC_FREE(subreq); >+ cli_trans_cleanup_primary(state); > tevent_req_nterror(req, status); > } > >@@ -594,6 +664,8 @@ NTSTATUS cli_trans_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, > req, struct cli_trans_state); > NTSTATUS status; > >+ cli_trans_cleanup_primary(state); >+ > if (tevent_req_is_nterror(req, &status)) { > return status; > } >-- >1.7.4.1 > > >From f726c0a8fb00b3cbd2e76d9d22bd52f9d90ed73e Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Thu, 9 Jun 2011 11:57:55 +0200 >Subject: [PATCH 12/15] s3:libsmb/clitrans: correctly transfer the seqnum between secondary and primary requests > >This is needed to implement SMB signing correct. > >metze >--- > source3/libsmb/clitrans.c | 11 ++++++++--- > 1 files changed, 8 insertions(+), 3 deletions(-) > >diff --git a/source3/libsmb/clitrans.c b/source3/libsmb/clitrans.c >index e23598c..dd8063b 100644 >--- a/source3/libsmb/clitrans.c >+++ b/source3/libsmb/clitrans.c >@@ -32,7 +32,6 @@ struct cli_trans_state { > struct event_context *ev; > uint8_t cmd; > uint16_t mid; >- uint32_t seqnum; > const char *pipe_name; > uint8_t *pipe_name_conv; > size_t pipe_name_conv_len; >@@ -65,7 +64,6 @@ static void cli_trans_cleanup_primary(struct cli_trans_state *state) > if (state->primary_subreq) { > cli_smb_req_set_mid(state->primary_subreq, 0); > cli_smb_req_unset_pending(state->primary_subreq); >- cli_state_seqnum_remove(state->cli, state->mid); > TALLOC_FREE(state->primary_subreq); > } > } >@@ -475,7 +473,6 @@ struct tevent_req *cli_trans_send( > */ > state->mid = cli_smb_req_mid(subreq); > cli_smb_req_set_mid(subreq, state->mid); >- cli_state_seqnum_persistent(cli, state->mid); > state->primary_subreq = subreq; > talloc_set_destructor(state, cli_trans_state_destructor); > >@@ -605,6 +602,14 @@ static void cli_trans_done2(struct tevent_req *subreq2) > NTSTATUS status; > bool sent_all; > uint8_t wct; >+ uint32_t seqnum; >+ >+ /* >+ * First backup the seqnum of the secondary request >+ * and attach it to the primary request. >+ */ >+ seqnum = cli_smb_req_seqnum(subreq2); >+ cli_smb_req_set_seqnum(state->primary_subreq, seqnum); > > status = cli_smb_recv(subreq2, state, NULL, 0, &wct, NULL, > NULL, NULL); >-- >1.7.4.1 > > >From 68ab9dec0e9bb513dfd14722a95c5847e294c80b Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Wed, 8 Jun 2011 18:59:39 +0200 >Subject: [PATCH 13/15] s3:libsmb/clireadwrite: calculate cli_read_max_bufsize() correct based on max_xmit > >This is important in order to support DCERPC over ncacn_np against NT4 servers, >where max_xmit is just 4356. > >metze >--- > source3/libsmb/clireadwrite.c | 13 ++++++++++++- > 1 files changed, 12 insertions(+), 1 deletions(-) > >diff --git a/source3/libsmb/clireadwrite.c b/source3/libsmb/clireadwrite.c >index c19151e..e8baeba 100644 >--- a/source3/libsmb/clireadwrite.c >+++ b/source3/libsmb/clireadwrite.c >@@ -28,6 +28,11 @@ > ****************************************************************************/ > static size_t cli_read_max_bufsize(struct cli_state *cli) > { >+ size_t data_offset = smb_size - 4; >+ size_t wct = 12; >+ >+ size_t useable_space; >+ > if (!client_is_signing_on(cli) && !cli_encryption_on(cli) > && (cli->server_posix_capabilities & CIFS_UNIX_LARGE_READ_CAP)) { > return CLI_SAMBA_MAX_POSIX_LARGE_READX_SIZE; >@@ -37,7 +42,13 @@ static size_t cli_read_max_bufsize(struct cli_state *cli) > ? CLI_SAMBA_MAX_LARGE_READX_SIZE > : CLI_WINDOWS_MAX_LARGE_READX_SIZE; > } >- return (cli->max_xmit - (smb_size+32)) & ~1023; >+ >+ data_offset += wct * sizeof(uint16_t); >+ data_offset += 1; /* pad */ >+ >+ useable_space = cli->max_xmit - data_offset; >+ >+ return useable_space; > } > > /**************************************************************************** >-- >1.7.4.1 > > >From cf76a6bc010ea4ac60286b31f66060f1644598ce Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Wed, 8 Jun 2011 19:01:13 +0200 >Subject: [PATCH 14/15] s3:libsmb/clireadwrite: calculate cli_write_max_bufsize() correct based on max_xmit > >This is important in order to support DCERPC over ncacn_np against NT4 servers, >where max_xmit is just 4356. > >metze >--- > source3/libsmb/clireadwrite.c | 20 ++++++++++++-------- > 1 files changed, 12 insertions(+), 8 deletions(-) > >diff --git a/source3/libsmb/clireadwrite.c b/source3/libsmb/clireadwrite.c >index e8baeba..14b6401 100644 >--- a/source3/libsmb/clireadwrite.c >+++ b/source3/libsmb/clireadwrite.c >@@ -54,7 +54,9 @@ static size_t cli_read_max_bufsize(struct cli_state *cli) > /**************************************************************************** > Calculate the recommended write buffer size > ****************************************************************************/ >-static size_t cli_write_max_bufsize(struct cli_state *cli, uint16_t write_mode) >+static size_t cli_write_max_bufsize(struct cli_state *cli, >+ uint16_t write_mode, >+ uint8_t wct) > { > if (write_mode == 0 && > !client_is_signing_on(cli) && >@@ -73,13 +75,15 @@ static size_t cli_write_max_bufsize(struct cli_state *cli, uint16_t write_mode) > if (((cli->capabilities & CAP_LARGE_WRITEX) == 0) > || client_is_signing_on(cli) > || strequal(cli->dev, "LPT1:")) { >+ size_t data_offset = smb_size - 4; >+ size_t useable_space; > >- /* >- * Printer devices are restricted to max_xmit writesize in >- * Vista and XPSP3 as are signing connections. >- */ >+ data_offset += wct * sizeof(uint16_t); >+ data_offset += 1; /* pad */ >+ >+ useable_space = cli->max_xmit - data_offset; > >- return (cli->max_xmit - (smb_size+32)) & ~1023; >+ return useable_space; > } > > return CLI_WINDOWS_MAX_LARGE_WRITEX_SIZE; >@@ -795,7 +799,7 @@ struct tevent_req *cli_write_andx_create(TALLOC_CTX *mem_ctx, > struct cli_write_andx_state *state; > bool bigoffset = ((cli->capabilities & CAP_LARGE_FILES) != 0); > uint8_t wct = bigoffset ? 14 : 12; >- size_t max_write = cli_write_max_bufsize(cli, mode); >+ size_t max_write = cli_write_max_bufsize(cli, mode, wct); > uint16_t *vwv; > > req = tevent_req_create(mem_ctx, &state, struct cli_write_andx_state); >@@ -1148,7 +1152,7 @@ struct tevent_req *cli_push_send(TALLOC_CTX *mem_ctx, struct event_context *ev, > state->pending = 0; > state->next_offset = start_offset; > >- state->chunk_size = cli_write_max_bufsize(cli, mode); >+ state->chunk_size = cli_write_max_bufsize(cli, mode, 14); > > if (window_size == 0) { > window_size = cli->max_mux * state->chunk_size; >-- >1.7.4.1 > > >From 6ce3aa061635e497f6297eac7c6908872c4d817c Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Thu, 9 Jun 2011 11:59:58 +0200 >Subject: [PATCH 15/15] s3:libsmb: remove unused cli_state_seqnum infrastructure > >metze >--- > source3/include/client.h | 8 -------- > source3/libsmb/clientgen.c | 32 -------------------------------- > source3/libsmb/proto.h | 4 ---- > 3 files changed, 0 insertions(+), 44 deletions(-) > >diff --git a/source3/include/client.h b/source3/include/client.h >index 7d66bf9..a853e90 100644 >--- a/source3/include/client.h >+++ b/source3/include/client.h >@@ -46,13 +46,6 @@ struct print_job_info { > time_t t; > }; > >-struct cli_state_seqnum { >- struct cli_state_seqnum *prev, *next; >- uint16_t mid; >- uint32_t seqnum; >- bool persistent; >-}; >- > struct cli_state { > /** > * A list of subsidiary connections for DFS. >@@ -103,7 +96,6 @@ struct cli_state { > size_t max_xmit; > size_t max_mux; > char *outbuf; >- struct cli_state_seqnum *seqnum; > char *inbuf; > unsigned int bufsize; > int initialised; >diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c >index 1122bbb..d3b66b6 100644 >--- a/source3/libsmb/clientgen.c >+++ b/source3/libsmb/clientgen.c >@@ -68,37 +68,6 @@ bool cli_ucs2(struct cli_state *cli) > return ((cli->capabilities & CAP_UNICODE) != 0); > } > >-bool cli_state_seqnum_persistent(struct cli_state *cli, >- uint16_t mid) >-{ >- struct cli_state_seqnum *c; >- >- for (c = cli->seqnum; c; c = c->next) { >- if (c->mid == mid) { >- c->persistent = true; >- return true; >- } >- } >- >- return false; >-} >- >-bool cli_state_seqnum_remove(struct cli_state *cli, >- uint16_t mid) >-{ >- struct cli_state_seqnum *c; >- >- for (c = cli->seqnum; c; c = c->next) { >- if (c->mid == mid) { >- DLIST_REMOVE(cli->seqnum, c); >- TALLOC_FREE(c); >- return true; >- } >- } >- >- return false; >-} >- > /**************************************************************************** > Setup basics in a outgoing packet. > ****************************************************************************/ >@@ -233,7 +202,6 @@ struct cli_state *cli_initialise_ex(int signing_state) > cli->bufsize = CLI_BUFFER_SIZE+4; > cli->max_xmit = cli->bufsize; > cli->outbuf = (char *)SMB_MALLOC(cli->bufsize+SAFETY_MARGIN); >- cli->seqnum = 0; > cli->inbuf = (char *)SMB_MALLOC(cli->bufsize+SAFETY_MARGIN); > cli->oplock_handler = cli_oplock_ack; > cli->case_sensitive = false; >diff --git a/source3/libsmb/proto.h b/source3/libsmb/proto.h >index 37a928e..2b32c10 100644 >--- a/source3/libsmb/proto.h >+++ b/source3/libsmb/proto.h >@@ -146,10 +146,6 @@ bool cli_check_msdfs_proxy(TALLOC_CTX *ctx, > int cli_set_message(char *buf,int num_words,int num_bytes,bool zero); > unsigned int cli_set_timeout(struct cli_state *cli, unsigned int timeout); > void cli_set_port(struct cli_state *cli, int port); >-bool cli_state_seqnum_persistent(struct cli_state *cli, >- uint16_t mid); >-bool cli_state_seqnum_remove(struct cli_state *cli, >- uint16_t mid); > void cli_setup_packet_buf(struct cli_state *cli, char *buf); > NTSTATUS cli_set_domain(struct cli_state *cli, const char *domain); > NTSTATUS cli_set_username(struct cli_state *cli, const char *username); >-- >1.7.4.1 >
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Raw
Flags:
vl
:
review+
jra
:
review+
Actions:
View
Attachments on
bug 8195
:
6506
|
6539
|
6552
| 6553 |
6584