diff options
Diffstat (limited to 'source4/libcli/smb_composite')
-rw-r--r-- | source4/libcli/smb_composite/smb2.c | 184 |
1 files changed, 127 insertions, 57 deletions
diff --git a/source4/libcli/smb_composite/smb2.c b/source4/libcli/smb_composite/smb2.c index c2985f2ae8..1f8ec834ca 100644 --- a/source4/libcli/smb_composite/smb2.c +++ b/source4/libcli/smb_composite/smb2.c @@ -25,6 +25,8 @@ #include "includes.h" +#include <tevent.h> +#include "lib/util/tevent_ntstatus.h" #include "libcli/raw/libcliraw.h" #include "libcli/raw/raw_proto.h" #include "libcli/composite/composite.h" @@ -264,107 +266,145 @@ NTSTATUS smb2_composite_rmdir(struct smb2_tree *tree, struct smb_rmdir *io) return composite_wait_free(c); } +struct smb2_composite_setpathinfo_state { + struct smb2_tree *tree; + union smb_setfileinfo io; + NTSTATUS set_status; + struct smb2_create cr; + struct smb2_close cl; +}; + static void smb2_composite_setpathinfo_create_done(struct smb2_request *smb2req); /* composite SMB2 setpathinfo call */ -struct composite_context *smb2_composite_setpathinfo_send(struct smb2_tree *tree, - union smb_setfileinfo *io) +struct tevent_req *smb2_composite_setpathinfo_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct smb2_tree *tree, + const union smb_setfileinfo *io) { - struct composite_context *ctx; - struct smb2_create create_parm; + struct tevent_req *req; + struct smb2_composite_setpathinfo_state *state; struct smb2_request *smb2req; - union smb_setfileinfo *io2; - ctx = composite_create(tree, tree->session->transport->socket->event.ctx); - if (ctx == NULL) return NULL; + req = tevent_req_create(mem_ctx, &state, + struct smb2_composite_setpathinfo_state); + if (req == NULL) { + return NULL; + } - ZERO_STRUCT(create_parm); - create_parm.in.desired_access = SEC_FLAG_MAXIMUM_ALLOWED; - create_parm.in.create_disposition = NTCREATEX_DISP_OPEN; - create_parm.in.share_access = + state->tree = tree; + state->io = *io; + + state->cr.in.desired_access = SEC_FLAG_MAXIMUM_ALLOWED; + state->cr.in.create_disposition = NTCREATEX_DISP_OPEN; + state->cr.in.share_access = NTCREATEX_SHARE_ACCESS_DELETE| NTCREATEX_SHARE_ACCESS_READ| NTCREATEX_SHARE_ACCESS_WRITE; - create_parm.in.create_options = 0; - create_parm.in.fname = io->generic.in.file.path; - if (create_parm.in.fname[0] == '\\') { - create_parm.in.fname++; + state->cr.in.create_options = 0; + state->cr.in.fname = state->io.generic.in.file.path; + if (state->cr.in.fname[0] == '\\') { + state->cr.in.fname++; } - smb2req = smb2_create_send(tree, &create_parm); - - io2 = talloc(ctx, union smb_setfileinfo); - if (composite_nomem(io2, ctx)) { - return ctx; + smb2req = smb2_create_send(tree, &state->cr); + if (tevent_req_nomem(smb2req, req)) { + return tevent_req_post(req, ev); } - *io2 = *io; + smb2req->async.fn = smb2_composite_setpathinfo_create_done; + smb2req->async.private_data = req; - ctx->private_data = io2; - - composite_continue_smb2(ctx, smb2req, smb2_composite_setpathinfo_create_done, ctx); - return ctx; + return req; } static void smb2_composite_setpathinfo_setinfo_done(struct smb2_request *smb2req); static void smb2_composite_setpathinfo_create_done(struct smb2_request *smb2req) { - struct composite_context *ctx = talloc_get_type(smb2req->async.private_data, - struct composite_context); - struct smb2_tree *tree = smb2req->tree; - struct smb2_create create_parm; + struct tevent_req *req = + talloc_get_type_abort(smb2req->async.private_data, + struct tevent_req); + struct smb2_composite_setpathinfo_state *state = + tevent_req_data(req, + struct smb2_composite_setpathinfo_state); NTSTATUS status; - union smb_setfileinfo *io2 = talloc_get_type(ctx->private_data, - union smb_setfileinfo); - status = smb2_create_recv(smb2req, ctx, &create_parm); - if (!NT_STATUS_IS_OK(status)) { - composite_error(ctx, status); + status = smb2_create_recv(smb2req, state, &state->cr); + if (tevent_req_nterror(req, status)) { return; } - io2->generic.in.file.handle = create_parm.out.file.handle; + state->io.generic.in.file.handle = state->cr.out.file.handle; - smb2req = smb2_setinfo_file_send(tree, io2); - composite_continue_smb2(ctx, smb2req, smb2_composite_setpathinfo_setinfo_done, ctx); + smb2req = smb2_setinfo_file_send(state->tree, &state->io); + if (tevent_req_nomem(smb2req, req)) { + return; + } + smb2req->async.fn = smb2_composite_setpathinfo_setinfo_done; + smb2req->async.private_data = req; } static void smb2_composite_setpathinfo_close_done(struct smb2_request *smb2req); static void smb2_composite_setpathinfo_setinfo_done(struct smb2_request *smb2req) { - struct composite_context *ctx = talloc_get_type(smb2req->async.private_data, - struct composite_context); - struct smb2_tree *tree = smb2req->tree; - struct smb2_close close_parm; + struct tevent_req *req = + talloc_get_type_abort(smb2req->async.private_data, + struct tevent_req); + struct smb2_composite_setpathinfo_state *state = + tevent_req_data(req, + struct smb2_composite_setpathinfo_state); NTSTATUS status; - union smb_setfileinfo *io2 = talloc_get_type(ctx->private_data, - union smb_setfileinfo); status = smb2_setinfo_recv(smb2req); - if (!NT_STATUS_IS_OK(status)) { - composite_error(ctx, status); + state->set_status = status; + + state->cl.in.file.handle = state->io.generic.in.file.handle; + + smb2req = smb2_close_send(state->tree, &state->cl); + if (tevent_req_nomem(smb2req, req)) { return; } + smb2req->async.fn = smb2_composite_setpathinfo_close_done; + smb2req->async.private_data = req; +} - ZERO_STRUCT(close_parm); - close_parm.in.file.handle = io2->generic.in.file.handle; +static void smb2_composite_setpathinfo_close_done(struct smb2_request *smb2req) +{ + struct tevent_req *req = + talloc_get_type_abort(smb2req->async.private_data, + struct tevent_req); + struct smb2_composite_setpathinfo_state *state = + tevent_req_data(req, + struct smb2_composite_setpathinfo_state); + NTSTATUS status; + + status = smb2_close_recv(smb2req, &state->cl); + + if (tevent_req_nterror(req, state->set_status)) { + return; + } - smb2req = smb2_close_send(tree, &close_parm); - composite_continue_smb2(ctx, smb2req, smb2_composite_setpathinfo_close_done, ctx); + if (tevent_req_nterror(req, status)) { + return; + } + + tevent_req_done(req); } -static void smb2_composite_setpathinfo_close_done(struct smb2_request *smb2req) +NTSTATUS smb2_composite_setpathinfo_recv(struct tevent_req *req) { - struct composite_context *ctx = talloc_get_type(smb2req->async.private_data, - struct composite_context); NTSTATUS status; - struct smb2_close close_parm; - status = smb2_close_recv(smb2req, &close_parm); - composite_error(ctx, status); + if (tevent_req_is_nterror(req, &status)) { + tevent_req_received(req); + return status; + } + + tevent_req_received(req); + return NT_STATUS_OK; } /* @@ -372,6 +412,36 @@ static void smb2_composite_setpathinfo_close_done(struct smb2_request *smb2req) */ NTSTATUS smb2_composite_setpathinfo(struct smb2_tree *tree, union smb_setfileinfo *io) { - struct composite_context *c = smb2_composite_setpathinfo_send(tree, io); - return composite_wait_free(c); + struct tevent_req *subreq; + NTSTATUS status; + bool ok; + TALLOC_CTX *frame = talloc_stackframe(); + struct tevent_context *ev = tree->session->transport->socket->event.ctx; + + if (frame == NULL) { + return NT_STATUS_NO_MEMORY; + } + + subreq = smb2_composite_setpathinfo_send(frame, ev, tree, io); + if (subreq == NULL) { + TALLOC_FREE(frame); + return NT_STATUS_NO_MEMORY; + } + + ok = tevent_req_poll(subreq, ev); + if (!ok) { + status = map_nt_error_from_unix(errno); + TALLOC_FREE(frame); + return status; + } + + status = smb2_composite_setpathinfo_recv(subreq); + TALLOC_FREE(subreq); + if (!NT_STATUS_IS_OK(status)) { + TALLOC_FREE(frame); + return status; + } + + TALLOC_FREE(frame); + return NT_STATUS_OK; } |