The Samba-Bugzilla – Attachment 15283 Details for
Bug 14025
libsmbclient notfiy API fails with NT_STATUS_REVISION_MISMATCH
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
Patch that went into the 4.10.x code base
l1 (text/plain), 27.66 KB, created by
Jeremy Allison
on 2019-07-03 16:56:20 UTC
(
hide
)
Description:
Patch that went into the 4.10.x code base
Filename:
MIME Type:
Creator:
Jeremy Allison
Created:
2019-07-03 16:56:20 UTC
Size:
27.66 KB
patch
obsolete
>From bb843be3bfe4a9e15f345edb8acb290d63b28781 Mon Sep 17 00:00:00 2001 >From: Volker Lendecke <vl@samba.org> >Date: Fri, 16 Nov 2018 21:01:19 +0100 >Subject: [PATCH 1/6] libsmb: Make cli_trans a normal subreq function > >A lot of "state" variables, but still I don't think the additional complexity >is justified by saving a few lines. Make this a completely regular tevent_req >"req/subreq" function. > >Signed-off-by: Volker Lendecke <vl@samba.org> >Reviewed-by: Jeremy Allison <jra@samba.org> >--- > source3/libsmb/clitrans.c | 208 +++++++++++++++++++++----------------- > 1 file changed, 113 insertions(+), 95 deletions(-) > >diff --git a/source3/libsmb/clitrans.c b/source3/libsmb/clitrans.c >index a96d8bf4769..7817fd4b3c5 100644 >--- a/source3/libsmb/clitrans.c >+++ b/source3/libsmb/clitrans.c >@@ -25,28 +25,16 @@ > > struct cli_trans_state { > struct cli_state *cli; >- struct tevent_req *req; >- struct cli_trans_state **ptr; >+ uint16_t recv_flags2; >+ uint16_t *setup; >+ uint8_t num_setup; >+ uint8_t *param; >+ uint32_t num_param; >+ uint8_t *data; >+ uint32_t num_data; > }; > >-static int cli_trans_state_destructor(struct cli_trans_state *state) >-{ >- talloc_set_destructor(state->ptr, NULL); >- talloc_free(state->ptr); >- return 0; >-} >- >-static int cli_trans_state_ptr_destructor(struct cli_trans_state **ptr) >-{ >- struct cli_trans_state *state = *ptr; >- void *parent = talloc_parent(state); >- >- talloc_set_destructor(state, NULL); >- >- talloc_reparent(state, parent, state->req); >- talloc_free(state); >- return 0; >-} >+static void cli_trans_done(struct tevent_req *subreq); > > struct tevent_req *cli_trans_send( > TALLOC_CTX *mem_ctx, struct tevent_context *ev, >@@ -56,45 +44,57 @@ struct tevent_req *cli_trans_send( > uint8_t *param, uint32_t num_param, uint32_t max_param, > uint8_t *data, uint32_t num_data, uint32_t max_data) > { >+ struct tevent_req *req, *subreq; > struct cli_trans_state *state; > uint8_t additional_flags = 0; > uint8_t clear_flags = 0; > uint16_t clear_flags2 = 0; > >- state = talloc_zero(mem_ctx, struct cli_trans_state); >- if (state == NULL) { >+ req = tevent_req_create(mem_ctx, &state, struct cli_trans_state); >+ if (req == NULL) { > return NULL; > } > state->cli = cli; >- state->ptr = talloc(state, struct cli_trans_state *); >- if (state->ptr == NULL) { >- talloc_free(state); >- return NULL; >- } >- *state->ptr = state; >- >- state->req = smb1cli_trans_send(state, ev, >- cli->conn, cmd, >- additional_flags, clear_flags, >- additional_flags2, clear_flags2, >- cli->timeout, >- cli->smb1.pid, >- cli->smb1.tcon, >- cli->smb1.session, >- pipe_name, fid, function, flags, >- setup, num_setup, max_setup, >- param, num_param, max_param, >- data, num_data, max_data); >- if (state->req == NULL) { >- talloc_free(state); >- return NULL; >+ >+ subreq = smb1cli_trans_send(state, ev, >+ cli->conn, cmd, >+ additional_flags, clear_flags, >+ additional_flags2, clear_flags2, >+ cli->timeout, >+ cli->smb1.pid, >+ cli->smb1.tcon, >+ cli->smb1.session, >+ pipe_name, fid, function, flags, >+ setup, num_setup, max_setup, >+ param, num_param, max_param, >+ data, num_data, max_data); >+ if (tevent_req_nomem(subreq, req)) { >+ return tevent_req_post(req, ev); > } >+ tevent_req_set_callback(subreq, cli_trans_done, req); >+ return req; >+} > >- talloc_reparent(state, state->req, state->ptr); >- talloc_set_destructor(state, cli_trans_state_destructor); >- talloc_set_destructor(state->ptr, cli_trans_state_ptr_destructor); >+static void cli_trans_done(struct tevent_req *subreq) >+{ >+ struct tevent_req *req = tevent_req_callback_data( >+ subreq, struct tevent_req); >+ struct cli_trans_state *state = tevent_req_data( >+ req, struct cli_trans_state); >+ NTSTATUS status; > >- return state->req; >+ status = smb1cli_trans_recv( >+ subreq, >+ state, >+ &state->recv_flags2, >+ &state->setup, 0, &state->num_setup, >+ &state->param, 0, &state->num_param, >+ &state->data, 0, &state->num_data); >+ TALLOC_FREE(subreq); >+ if (tevent_req_nterror(req, status)) { >+ return; >+ } >+ tevent_req_done(req); > } > > NTSTATUS cli_trans_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, >@@ -106,25 +106,41 @@ NTSTATUS cli_trans_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, > uint8_t **data, uint32_t min_data, > uint32_t *num_data) > { >- NTSTATUS status; >- void *parent = talloc_parent(req); >- struct cli_trans_state *state = >- talloc_get_type(parent, >- struct cli_trans_state); >+ struct cli_trans_state *state = tevent_req_data( >+ req, struct cli_trans_state); >+ NTSTATUS status = NT_STATUS_OK; > bool map_dos_errors = true; > >- status = smb1cli_trans_recv(req, mem_ctx, recv_flags2, >- setup, min_setup, num_setup, >- param, min_param, num_param, >- data, min_data, num_data); >+ if (tevent_req_is_nterror(req, &status)) { >+ goto map_error; >+ } >+ >+ if ((state->num_setup < min_setup) || >+ (state->num_param < min_param) || >+ (state->num_data < min_data)) { >+ return NT_STATUS_INVALID_NETWORK_RESPONSE; >+ } > >- if (state) { >- map_dos_errors = state->cli->map_dos_errors; >- state->cli->raw_status = status; >- talloc_free(state->ptr); >- state = NULL; >+ if (recv_flags2 != NULL) { >+ *recv_flags2 = state->recv_flags2; >+ } >+ if (setup != NULL) { >+ *setup = talloc_move(mem_ctx, &state->setup); >+ *num_setup = state->num_setup; >+ } >+ if (param != NULL) { >+ *param = talloc_move(mem_ctx, &state->param); >+ *num_param = state->num_param; >+ } >+ if (data != NULL) { >+ *data = talloc_move(mem_ctx, &state->data); >+ *num_data = state->num_data; > } > >+map_error: >+ map_dos_errors = state->cli->map_dos_errors; >+ state->cli->raw_status = status; >+ > if (NT_STATUS_IS_DOS(status) && map_dos_errors) { > uint8_t eclass = NT_STATUS_DOS_CLASS(status); > uint16_t ecode = NT_STATUS_DOS_CODE(status); >@@ -152,42 +168,44 @@ NTSTATUS cli_trans(TALLOC_CTX *mem_ctx, struct cli_state *cli, > uint8_t **rparam, uint32_t min_rparam, uint32_t *num_rparam, > uint8_t **rdata, uint32_t min_rdata, uint32_t *num_rdata) > { >- NTSTATUS status; >- uint8_t additional_flags = 0; >- uint8_t clear_flags = 0; >- uint16_t additional_flags2 = 0; >- uint16_t clear_flags2 = 0; >+ TALLOC_CTX *frame = talloc_stackframe(); >+ struct tevent_context *ev; >+ struct tevent_req *req; >+ NTSTATUS status = NT_STATUS_NO_MEMORY; > >- status = smb1cli_trans(mem_ctx, >- cli->conn, trans_cmd, >- additional_flags, clear_flags, >- additional_flags2, clear_flags2, >- cli->timeout, >- cli->smb1.pid, >- cli->smb1.tcon, >- cli->smb1.session, >- pipe_name, fid, function, flags, >- setup, num_setup, max_setup, >- param, num_param, max_param, >- data, num_data, max_data, >- recv_flags2, >- rsetup, min_rsetup, num_rsetup, >- rparam, min_rparam, num_rparam, >- rdata, min_rdata, num_rdata); >- >- cli->raw_status = status; >- >- if (NT_STATUS_IS_DOS(status) && cli->map_dos_errors) { >- uint8_t eclass = NT_STATUS_DOS_CLASS(status); >- uint16_t ecode = NT_STATUS_DOS_CODE(status); >+ if (smbXcli_conn_has_async_calls(cli->conn)) { > /* >- * TODO: is it really a good idea to do a mapping here? >- * >- * The old cli_pull_error() also does it, so I do not change >- * the behavior yet. >+ * Can't use sync call while an async call is in flight > */ >- status = dos_to_ntstatus(eclass, ecode); >+ status = NT_STATUS_INVALID_PARAMETER; >+ goto fail; > } >- >+ ev = samba_tevent_context_init(frame); >+ if (ev == NULL) { >+ goto fail; >+ } >+ req = cli_trans_send( >+ frame, /* mem_ctx */ >+ ev, /* ev */ >+ cli, /* cli */ >+ 0, /* additional_flags2 */ >+ trans_cmd, /* cmd */ >+ pipe_name, fid, function, flags, >+ setup, num_setup, max_setup, >+ param, num_param, max_param, >+ data, num_data, max_data); >+ if (req == NULL) { >+ goto fail; >+ } >+ if (!tevent_req_poll_ntstatus(req, ev, &status)) { >+ goto fail; >+ } >+ status = cli_trans_recv( >+ req, mem_ctx, recv_flags2, >+ rsetup, min_rsetup, num_rsetup, >+ rparam, min_rparam, num_rparam, >+ rdata, min_rdata, num_rdata); >+fail: >+ TALLOC_FREE(frame); > return status; > } >-- >2.22.0.410.gd8fdbe21b5-goog > > >From 9c9ccf234989a28e0f3d8f46fa7bce070e44c5a4 Mon Sep 17 00:00:00 2001 >From: Volker Lendecke <vl@samba.org> >Date: Fri, 16 Nov 2018 21:03:45 +0100 >Subject: [PATCH 2/6] libsmb: Make cli_trans_send cancellable > >Required to cancel SMB1 notify > >Signed-off-by: Volker Lendecke <vl@samba.org> >Reviewed-by: Jeremy Allison <jra@samba.org> >--- > source3/libsmb/clitrans.c | 43 +++++++++++++++++++++++++-------------- > 1 file changed, 28 insertions(+), 15 deletions(-) > >diff --git a/source3/libsmb/clitrans.c b/source3/libsmb/clitrans.c >index 7817fd4b3c5..e5b4c4a4618 100644 >--- a/source3/libsmb/clitrans.c >+++ b/source3/libsmb/clitrans.c >@@ -25,6 +25,7 @@ > > struct cli_trans_state { > struct cli_state *cli; >+ struct tevent_req *subreq; > uint16_t recv_flags2; > uint16_t *setup; > uint8_t num_setup; >@@ -35,6 +36,7 @@ struct cli_trans_state { > }; > > static void cli_trans_done(struct tevent_req *subreq); >+static bool cli_trans_cancel(struct tevent_req *req); > > struct tevent_req *cli_trans_send( > TALLOC_CTX *mem_ctx, struct tevent_context *ev, >@@ -44,7 +46,7 @@ struct tevent_req *cli_trans_send( > uint8_t *param, uint32_t num_param, uint32_t max_param, > uint8_t *data, uint32_t num_data, uint32_t max_data) > { >- struct tevent_req *req, *subreq; >+ struct tevent_req *req; > struct cli_trans_state *state; > uint8_t additional_flags = 0; > uint8_t clear_flags = 0; >@@ -56,25 +58,36 @@ struct tevent_req *cli_trans_send( > } > state->cli = cli; > >- subreq = smb1cli_trans_send(state, ev, >- cli->conn, cmd, >- additional_flags, clear_flags, >- additional_flags2, clear_flags2, >- cli->timeout, >- cli->smb1.pid, >- cli->smb1.tcon, >- cli->smb1.session, >- pipe_name, fid, function, flags, >- setup, num_setup, max_setup, >- param, num_param, max_param, >- data, num_data, max_data); >- if (tevent_req_nomem(subreq, req)) { >+ state->subreq = smb1cli_trans_send(state, ev, >+ cli->conn, cmd, >+ additional_flags, clear_flags, >+ additional_flags2, clear_flags2, >+ cli->timeout, >+ cli->smb1.pid, >+ cli->smb1.tcon, >+ cli->smb1.session, >+ pipe_name, fid, function, flags, >+ setup, num_setup, max_setup, >+ param, num_param, max_param, >+ data, num_data, max_data); >+ if (tevent_req_nomem(state->subreq, req)) { > return tevent_req_post(req, ev); > } >- tevent_req_set_callback(subreq, cli_trans_done, req); >+ tevent_req_set_callback(state->subreq, cli_trans_done, req); >+ tevent_req_set_cancel_fn(req, cli_trans_cancel); > return req; > } > >+static bool cli_trans_cancel(struct tevent_req *req) >+{ >+ struct cli_trans_state *state = tevent_req_data( >+ req, struct cli_trans_state); >+ bool ok; >+ >+ ok = tevent_req_cancel(state->subreq); >+ return ok; >+} >+ > static void cli_trans_done(struct tevent_req *subreq) > { > struct tevent_req *req = tevent_req_callback_data( >-- >2.22.0.410.gd8fdbe21b5-goog > > >From 499d97b38c4477751d2dd38e9882bc7a5c7a8337 Mon Sep 17 00:00:00 2001 >From: Volker Lendecke <vl@samba.org> >Date: Fri, 16 Nov 2018 19:01:57 +0100 >Subject: [PATCH 3/6] libcli: Make smb2cli_notify_send cancellable > >Signed-off-by: Volker Lendecke <vl@samba.org> >Reviewed-by: Jeremy Allison <jra@samba.org> >--- > libcli/smb/smb2cli_notify.c | 31 +++++++++++++++++++++++++------ > 1 file changed, 25 insertions(+), 6 deletions(-) > >diff --git a/libcli/smb/smb2cli_notify.c b/libcli/smb/smb2cli_notify.c >index 1a2a2793a32..9026a6b1c30 100644 >--- a/libcli/smb/smb2cli_notify.c >+++ b/libcli/smb/smb2cli_notify.c >@@ -32,10 +32,12 @@ struct smb2cli_notify_state { > uint32_t data_length; > > struct tevent_req *subreq; >+ struct tevent_req *timeout_subreq; > }; > > static void smb2cli_notify_done(struct tevent_req *subreq); > static void smb2cli_notify_timedout(struct tevent_req *subreq); >+static bool smb2cli_notify_cancel(struct tevent_req *req); > > struct tevent_req *smb2cli_notify_send(TALLOC_CTX *mem_ctx, > struct tevent_context *ev, >@@ -49,7 +51,7 @@ struct tevent_req *smb2cli_notify_send(TALLOC_CTX *mem_ctx, > uint32_t completion_filter, > bool recursive) > { >- struct tevent_req *req, *subreq; >+ struct tevent_req *req; > struct smb2cli_notify_state *state; > uint8_t *fixed; > uint16_t watch_tree; >@@ -83,16 +85,33 @@ struct tevent_req *smb2cli_notify_send(TALLOC_CTX *mem_ctx, > } > tevent_req_set_callback(state->subreq, smb2cli_notify_done, req); > >- subreq = tevent_wakeup_send(state, ev, >- timeval_current_ofs_msec(timeout_msec)); >- if (tevent_req_nomem(subreq, req)) { >- return tevent_req_post(req, ev); >+ if (timeout_msec != 0) { >+ state->timeout_subreq = tevent_wakeup_send( >+ state, ev, timeval_current_ofs_msec(timeout_msec)); >+ if (tevent_req_nomem(state->timeout_subreq, req)) { >+ return tevent_req_post(req, ev); >+ } >+ tevent_req_set_callback( >+ state->timeout_subreq, smb2cli_notify_timedout, req); > } >- tevent_req_set_callback(subreq, smb2cli_notify_timedout, req); >+ >+ tevent_req_set_cancel_fn(req, smb2cli_notify_cancel); > > return req; > } > >+static bool smb2cli_notify_cancel(struct tevent_req *req) >+{ >+ struct smb2cli_notify_state *state = tevent_req_data( >+ req, struct smb2cli_notify_state); >+ bool ok; >+ >+ TALLOC_FREE(state->timeout_subreq); >+ >+ ok = tevent_req_cancel(state->subreq); >+ return ok; >+} >+ > static void smb2cli_notify_timedout(struct tevent_req *subreq) > { > struct tevent_req *req = tevent_req_callback_data( >-- >2.22.0.410.gd8fdbe21b5-goog > > >From d4a8bed85512b6d80e2a256f0343b4f59e3f63ad Mon Sep 17 00:00:00 2001 >From: Volker Lendecke <vl@samba.org> >Date: Fri, 16 Nov 2018 13:47:00 +0100 >Subject: [PATCH 4/6] libsmb: Introduce cli_smb2_notify_send/recv > >This only existed as a sync wrapper where the underlying function could do >send/recv already. > >Signed-off-by: Volker Lendecke <vl@samba.org> >Reviewed-by: Jeremy Allison <jra@samba.org> >--- > source3/libsmb/cli_smb2_fnum.c | 207 ++++++++++++++++++++++++--------- > source3/libsmb/cli_smb2_fnum.h | 12 ++ > 2 files changed, 167 insertions(+), 52 deletions(-) > >diff --git a/source3/libsmb/cli_smb2_fnum.c b/source3/libsmb/cli_smb2_fnum.c >index 3cf16b325dd..35edec88809 100644 >--- a/source3/libsmb/cli_smb2_fnum.c >+++ b/source3/libsmb/cli_smb2_fnum.c >@@ -4196,52 +4196,95 @@ NTSTATUS cli_smb2_ftruncate(struct cli_state *cli, > return status; > } > >-NTSTATUS cli_smb2_notify(struct cli_state *cli, uint16_t fnum, >- uint32_t buffer_size, uint32_t completion_filter, >- bool recursive, TALLOC_CTX *mem_ctx, >- struct notify_change **pchanges, >- uint32_t *pnum_changes) >+struct cli_smb2_notify_state { >+ struct tevent_req *subreq; >+ struct notify_change *changes; >+ size_t num_changes; >+}; >+ >+static void cli_smb2_notify_done(struct tevent_req *subreq); >+static bool cli_smb2_notify_cancel(struct tevent_req *req); >+ >+struct tevent_req *cli_smb2_notify_send( >+ TALLOC_CTX *mem_ctx, >+ struct tevent_context *ev, >+ struct cli_state *cli, >+ uint16_t fnum, >+ uint32_t buffer_size, >+ uint32_t completion_filter, >+ bool recursive) > { >- NTSTATUS status; >+ struct tevent_req *req = NULL; >+ struct cli_smb2_notify_state *state = NULL; > struct smb2_hnd *ph = NULL; >- TALLOC_CTX *frame = talloc_stackframe(); >- uint8_t *base; >- uint32_t len, ofs; >- struct notify_change *changes = NULL; >- size_t num_changes = 0; >+ NTSTATUS status; > >- if (smbXcli_conn_has_async_calls(cli->conn)) { >- /* >- * Can't use sync call while an async call is in flight >- */ >- status = NT_STATUS_INVALID_PARAMETER; >- goto fail; >+ req = tevent_req_create(mem_ctx, &state, >+ struct cli_smb2_notify_state); >+ if (req == NULL) { >+ return NULL; > } > > if (smbXcli_conn_protocol(cli->conn) < PROTOCOL_SMB2_02) { >- status = NT_STATUS_INVALID_PARAMETER; >- goto fail; >+ tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER); >+ return tevent_req_post(req, ev); > } > > status = map_fnum_to_smb2_handle(cli, fnum, &ph); >- if (!NT_STATUS_IS_OK(status)) { >- goto fail; >+ if (tevent_req_nterror(req, status)) { >+ return tevent_req_post(req, ev); > } > >- status = smb2cli_notify(cli->conn, cli->timeout, >- cli->smb2.session, cli->smb2.tcon, >- buffer_size, >- ph->fid_persistent, ph->fid_volatile, >- completion_filter, recursive, >- frame, &base, &len); >+ state->subreq = smb2cli_notify_send( >+ state, >+ ev, >+ cli->conn, >+ cli->timeout, >+ cli->smb2.session, >+ cli->smb2.tcon, >+ buffer_size, >+ ph->fid_persistent, >+ ph->fid_volatile, >+ completion_filter, >+ recursive); >+ if (tevent_req_nomem(state->subreq, req)) { >+ return tevent_req_post(req, ev); >+ } >+ tevent_req_set_callback(state->subreq, cli_smb2_notify_done, req); >+ tevent_req_set_cancel_fn(req, cli_smb2_notify_cancel); >+ return req; >+} >+ >+static bool cli_smb2_notify_cancel(struct tevent_req *req) >+{ >+ struct cli_smb2_notify_state *state = tevent_req_data( >+ req, struct cli_smb2_notify_state); >+ bool ok; >+ >+ ok = tevent_req_cancel(state->subreq); >+ return ok; >+} >+ >+static void cli_smb2_notify_done(struct tevent_req *subreq) >+{ >+ struct tevent_req *req = tevent_req_callback_data( >+ subreq, struct tevent_req); >+ struct cli_smb2_notify_state *state = tevent_req_data( >+ req, struct cli_smb2_notify_state); >+ uint8_t *base; >+ uint32_t len; >+ uint32_t ofs; >+ NTSTATUS status; >+ >+ status = smb2cli_notify_recv(subreq, state, &base, &len); >+ TALLOC_FREE(subreq); > > if (NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT)) { >- len = 0; >- status = NT_STATUS_OK; >+ tevent_req_done(req); >+ return; > } >- >- if (!NT_STATUS_IS_OK(status)) { >- goto fail; >+ if (tevent_req_nterror(req, status)) { >+ return; > } > > ofs = 0; >@@ -4254,30 +4297,39 @@ NTSTATUS cli_smb2_notify(struct cli_state *cli, uint16_t fnum, > size_t namelen; > bool ok; > >- tmp = talloc_realloc(frame, changes, struct notify_change, >- num_changes + 1); >- if (tmp == NULL) { >- status = NT_STATUS_NO_MEMORY; >- goto fail; >+ tmp = talloc_realloc( >+ state, >+ state->changes, >+ struct notify_change, >+ state->num_changes + 1); >+ if (tevent_req_nomem(tmp, req)) { >+ return; > } >- changes = tmp; >- c = &changes[num_changes]; >- num_changes += 1; >+ state->changes = tmp; >+ c = &state->changes[state->num_changes]; >+ state->num_changes += 1; > > if (smb_buffer_oob(len, ofs, next_ofs) || > smb_buffer_oob(len, ofs+12, file_name_length)) { >- status = NT_STATUS_INVALID_NETWORK_RESPONSE; >- goto fail; >+ tevent_req_nterror( >+ req, NT_STATUS_INVALID_NETWORK_RESPONSE); >+ return; > } > > c->action = IVAL(base, ofs+4); > >- ok = convert_string_talloc(changes, CH_UTF16LE, CH_UNIX, >- base + ofs + 12, file_name_length, >- &c->name, &namelen); >+ ok = convert_string_talloc( >+ state->changes, >+ CH_UTF16LE, >+ CH_UNIX, >+ base + ofs + 12, >+ file_name_length, >+ &c->name, >+ &namelen); > if (!ok) { >- status = NT_STATUS_INVALID_NETWORK_RESPONSE; >- goto fail; >+ tevent_req_nterror( >+ req, NT_STATUS_INVALID_NETWORK_RESPONSE); >+ return; > } > > if (next_ofs == 0) { >@@ -4286,13 +4338,64 @@ NTSTATUS cli_smb2_notify(struct cli_state *cli, uint16_t fnum, > ofs += next_ofs; > } > >- *pchanges = talloc_move(mem_ctx, &changes); >- *pnum_changes = num_changes; >- status = NT_STATUS_OK; >+ tevent_req_done(req); >+} > >-fail: >- cli->raw_status = status; >+NTSTATUS cli_smb2_notify_recv(struct tevent_req *req, >+ TALLOC_CTX *mem_ctx, >+ struct notify_change **pchanges, >+ uint32_t *pnum_changes) >+{ >+ struct cli_smb2_notify_state *state = tevent_req_data( >+ req, struct cli_smb2_notify_state); >+ NTSTATUS status; > >+ if (tevent_req_is_nterror(req, &status)) { >+ return status; >+ } >+ *pchanges = talloc_move(mem_ctx, &state->changes); >+ *pnum_changes = state->num_changes; >+ return NT_STATUS_OK; >+} >+ >+NTSTATUS cli_smb2_notify(struct cli_state *cli, uint16_t fnum, >+ uint32_t buffer_size, uint32_t completion_filter, >+ bool recursive, TALLOC_CTX *mem_ctx, >+ struct notify_change **pchanges, >+ uint32_t *pnum_changes) >+{ >+ TALLOC_CTX *frame = talloc_stackframe(); >+ struct tevent_context *ev; >+ struct tevent_req *req; >+ NTSTATUS status = NT_STATUS_NO_MEMORY; >+ >+ if (smbXcli_conn_has_async_calls(cli->conn)) { >+ /* >+ * Can't use sync call while an async call is in flight >+ */ >+ status = NT_STATUS_INVALID_PARAMETER; >+ goto fail; >+ } >+ ev = samba_tevent_context_init(frame); >+ if (ev == NULL) { >+ goto fail; >+ } >+ req = cli_smb2_notify_send( >+ frame, >+ ev, >+ cli, >+ fnum, >+ buffer_size, >+ completion_filter, >+ recursive); >+ if (req == NULL) { >+ goto fail; >+ } >+ if (!tevent_req_poll_ntstatus(req, ev, &status)) { >+ goto fail; >+ } >+ status = cli_smb2_notify_recv(req, mem_ctx, pchanges, pnum_changes); >+fail: > TALLOC_FREE(frame); > return status; > } >diff --git a/source3/libsmb/cli_smb2_fnum.h b/source3/libsmb/cli_smb2_fnum.h >index 0ceddd0b9ab..4fce5fce1c3 100644 >--- a/source3/libsmb/cli_smb2_fnum.h >+++ b/source3/libsmb/cli_smb2_fnum.h >@@ -237,6 +237,18 @@ NTSTATUS cli_smb2_shadow_copy_data(TALLOC_CTX *mem_ctx, > NTSTATUS cli_smb2_ftruncate(struct cli_state *cli, > uint16_t fnum, > uint64_t newsize); >+struct tevent_req *cli_smb2_notify_send( >+ TALLOC_CTX *mem_ctx, >+ struct tevent_context *ev, >+ struct cli_state *cli, >+ uint16_t fnum, >+ uint32_t buffer_size, >+ uint32_t completion_filter, >+ bool recursive); >+NTSTATUS cli_smb2_notify_recv(struct tevent_req *req, >+ TALLOC_CTX *mem_ctx, >+ struct notify_change **pchanges, >+ uint32_t *pnum_changes); > NTSTATUS cli_smb2_notify(struct cli_state *cli, uint16_t fnum, > uint32_t buffer_size, uint32_t completion_filter, > bool recursive, TALLOC_CTX *mem_ctx, >-- >2.22.0.410.gd8fdbe21b5-goog > > >From 4c984f3f50c74a9f9fc35583ac00576faab1d0c5 Mon Sep 17 00:00:00 2001 >From: Volker Lendecke <vl@samba.org> >Date: Fri, 16 Nov 2018 13:53:01 +0100 >Subject: [PATCH 5/6] libsmb: Make cli_notify_send/recv smb2-aware > >smb2-awareness only existed in the sync wrapper > >Signed-off-by: Volker Lendecke <vl@samba.org> >Reviewed-by: Jeremy Allison <jra@samba.org> >--- > source3/libsmb/clifile.c | 43 ++++++++++++++++++++++++++++++++++------ > 1 file changed, 37 insertions(+), 6 deletions(-) > >diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c >index 5f6e98ce460..1964a155005 100644 >--- a/source3/libsmb/clifile.c >+++ b/source3/libsmb/clifile.c >@@ -5497,6 +5497,7 @@ struct cli_notify_state { > }; > > static void cli_notify_done(struct tevent_req *subreq); >+static void cli_notify_done_smb2(struct tevent_req *subreq); > > struct tevent_req *cli_notify_send(TALLOC_CTX *mem_ctx, > struct tevent_context *ev, >@@ -5513,6 +5514,22 @@ struct tevent_req *cli_notify_send(TALLOC_CTX *mem_ctx, > return NULL; > } > >+ if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) { >+ subreq = cli_smb2_notify_send( >+ state, >+ ev, >+ cli, >+ fnum, >+ buffer_size, >+ completion_filter, >+ recursive); >+ if (tevent_req_nomem(subreq, req)) { >+ return tevent_req_post(req, ev); >+ } >+ tevent_req_set_callback(subreq, cli_notify_done_smb2, req); >+ return req; >+ } >+ > SIVAL(state->setup, 0, completion_filter); > SSVAL(state->setup, 4, fnum); > SSVAL(state->setup, 6, recursive); >@@ -5622,6 +5639,26 @@ static void cli_notify_done(struct tevent_req *subreq) > tevent_req_done(req); > } > >+static void cli_notify_done_smb2(struct tevent_req *subreq) >+{ >+ struct tevent_req *req = tevent_req_callback_data( >+ subreq, struct tevent_req); >+ struct cli_notify_state *state = tevent_req_data( >+ req, struct cli_notify_state); >+ NTSTATUS status; >+ >+ status = cli_smb2_notify_recv( >+ subreq, >+ state, >+ &state->changes, >+ &state->num_changes); >+ TALLOC_FREE(subreq); >+ if (tevent_req_nterror(req, status)) { >+ return; >+ } >+ tevent_req_done(req); >+} >+ > NTSTATUS cli_notify_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, > uint32_t *pnum_changes, > struct notify_change **pchanges) >@@ -5649,12 +5686,6 @@ NTSTATUS cli_notify(struct cli_state *cli, uint16_t fnum, uint32_t buffer_size, > struct tevent_req *req; > NTSTATUS status = NT_STATUS_NO_MEMORY; > >- if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) { >- return cli_smb2_notify(cli, fnum, buffer_size, >- completion_filter, recursive, >- mem_ctx, pchanges, pnum_changes); >- } >- > frame = talloc_stackframe(); > > if (smbXcli_conn_has_async_calls(cli->conn)) { >-- >2.22.0.410.gd8fdbe21b5-goog > > >From 88d82b44c326cfb3ab1cf1f7288eada2566ab4bc Mon Sep 17 00:00:00 2001 >From: Volker Lendecke <vl@samba.org> >Date: Fri, 16 Nov 2018 21:11:57 +0100 >Subject: [PATCH 6/6] libsmb: Make cli_notify_send cancellable > >Signed-off-by: Volker Lendecke <vl@samba.org> >Reviewed-by: Jeremy Allison <jra@samba.org> > >Autobuild-User(master): Volker Lendecke <vl@samba.org> >Autobuild-Date(master): Wed Nov 21 20:50:13 CET 2018 on sn-devel-144 >--- > source3/libsmb/clifile.c | 40 ++++++++++++++++++++++++++++++++-------- > 1 file changed, 32 insertions(+), 8 deletions(-) > >diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c >index 1964a155005..b50926307a5 100644 >--- a/source3/libsmb/clifile.c >+++ b/source3/libsmb/clifile.c >@@ -5491,6 +5491,7 @@ NTSTATUS cli_posix_rmdir(struct cli_state *cli, const char *fname) > ****************************************************************************/ > > struct cli_notify_state { >+ struct tevent_req *subreq; > uint8_t setup[8]; > uint32_t num_changes; > struct notify_change *changes; >@@ -5498,6 +5499,7 @@ struct cli_notify_state { > > static void cli_notify_done(struct tevent_req *subreq); > static void cli_notify_done_smb2(struct tevent_req *subreq); >+static bool cli_notify_cancel(struct tevent_req *req); > > struct tevent_req *cli_notify_send(TALLOC_CTX *mem_ctx, > struct tevent_context *ev, >@@ -5505,7 +5507,7 @@ struct tevent_req *cli_notify_send(TALLOC_CTX *mem_ctx, > uint32_t buffer_size, > uint32_t completion_filter, bool recursive) > { >- struct tevent_req *req, *subreq; >+ struct tevent_req *req; > struct cli_notify_state *state; > unsigned old_timeout; > >@@ -5515,7 +5517,12 @@ struct tevent_req *cli_notify_send(TALLOC_CTX *mem_ctx, > } > > if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) { >- subreq = cli_smb2_notify_send( >+ /* >+ * Notifies should not time out >+ */ >+ old_timeout = cli_set_timeout(cli, 0); >+ >+ state->subreq = cli_smb2_notify_send( > state, > ev, > cli, >@@ -5523,11 +5530,15 @@ struct tevent_req *cli_notify_send(TALLOC_CTX *mem_ctx, > buffer_size, > completion_filter, > recursive); >- if (tevent_req_nomem(subreq, req)) { >+ >+ cli_set_timeout(cli, old_timeout); >+ >+ if (tevent_req_nomem(state->subreq, req)) { > return tevent_req_post(req, ev); > } >- tevent_req_set_callback(subreq, cli_notify_done_smb2, req); >- return req; >+ tevent_req_set_callback( >+ state->subreq, cli_notify_done_smb2, req); >+ goto done; > } > > SIVAL(state->setup, 0, completion_filter); >@@ -5539,7 +5550,7 @@ struct tevent_req *cli_notify_send(TALLOC_CTX *mem_ctx, > */ > old_timeout = cli_set_timeout(cli, 0); > >- subreq = cli_trans_send( >+ state->subreq = cli_trans_send( > state, /* mem ctx. */ > ev, /* event ctx. */ > cli, /* cli_state. */ >@@ -5561,13 +5572,25 @@ struct tevent_req *cli_notify_send(TALLOC_CTX *mem_ctx, > > cli_set_timeout(cli, old_timeout); > >- if (tevent_req_nomem(subreq, req)) { >+ if (tevent_req_nomem(state->subreq, req)) { > return tevent_req_post(req, ev); > } >- tevent_req_set_callback(subreq, cli_notify_done, req); >+ tevent_req_set_callback(state->subreq, cli_notify_done, req); >+done: >+ tevent_req_set_cancel_fn(req, cli_notify_cancel); > return req; > } > >+static bool cli_notify_cancel(struct tevent_req *req) >+{ >+ struct cli_notify_state *state = tevent_req_data( >+ req, struct cli_notify_state); >+ bool ok; >+ >+ ok = tevent_req_cancel(state->subreq); >+ return ok; >+} >+ > static void cli_notify_done(struct tevent_req *subreq) > { > struct tevent_req *req = tevent_req_callback_data( >@@ -5582,6 +5605,7 @@ static void cli_notify_done(struct tevent_req *subreq) > status = cli_trans_recv(subreq, talloc_tos(), &flags2, NULL, 0, NULL, > ¶ms, 0, &num_params, NULL, 0, NULL); > TALLOC_FREE(subreq); >+ state->subreq = NULL; > if (tevent_req_nterror(req, status)) { > DEBUG(10, ("cli_trans_recv returned %s\n", nt_errstr(status))); > return; >-- >2.22.0.410.gd8fdbe21b5-goog >
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
Actions:
View
Attachments on
bug 14025
:
15282
| 15283