From: Ralph Boehme Date: Sun, 25 Sep 2016 01:45:14 +0000 (-0700) Subject: libcli/smb: add FSCTL_PIPE_WAIT X-Git-Tag: talloc-2.4.2~1042 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=180f25f7bb2d89c8da0aa09797f35cd76c40bf7b;p=thirdparty%2Fsamba.git libcli/smb: add FSCTL_PIPE_WAIT Signed-off-by: Noel Power Reviewed-by: Andrew Bartlett --- diff --git a/libcli/smb/smb2cli_ioctl.c b/libcli/smb/smb2cli_ioctl.c index d638b281678..2c1d76c940b 100644 --- a/libcli/smb/smb2cli_ioctl.c +++ b/libcli/smb/smb2cli_ioctl.c @@ -22,6 +22,7 @@ #include "lib/util/tevent_ntstatus.h" #include "smb_common.h" #include "smbXcli_base.h" +#include "librpc/gen_ndr/ndr_ioctl.h" struct smb2cli_ioctl_state { uint8_t fixed[0x38]; @@ -388,3 +389,131 @@ NTSTATUS smb2cli_ioctl(struct smbXcli_conn *conn, TALLOC_FREE(frame); return status; } + +struct smb2cli_ioctl_pipe_wait_state { + DATA_BLOB in_blob; + DATA_BLOB out_blob; +}; + +static void smb2cli_ioctl_pipe_wait_done(struct tevent_req *subreq); + +struct tevent_req *smb2cli_ioctl_pipe_wait_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct smbXcli_conn *conn, + uint32_t timeout_msec, + struct smbXcli_session *session, + struct smbXcli_tcon *tcon, + const char *pipe_name, + uint64_t pipe_wait_timeout) +{ + struct tevent_req *req = NULL; + struct tevent_req *subreq = NULL; + struct smb2cli_ioctl_pipe_wait_state *state = NULL; + struct fsctl_pipe_wait fsctl = {0}; + enum ndr_err_code err; + + req = tevent_req_create(mem_ctx, &state, + struct smb2cli_ioctl_pipe_wait_state); + if (req == NULL) { + return NULL; + } + + state->out_blob = data_blob_string_const(""); + + fsctl.pipe_name = pipe_name; + fsctl.timeout = pipe_wait_timeout; + fsctl.timeout_specified = pipe_wait_timeout > 0 ? 1 : 0; + + err = ndr_push_struct_blob(&state->in_blob, mem_ctx, &fsctl, + (ndr_push_flags_fn_t)ndr_push_fsctl_pipe_wait); + if (!NDR_ERR_CODE_IS_SUCCESS(err)) { + return NULL; + } + + subreq = smb2cli_ioctl_send(mem_ctx, ev, conn, timeout_msec, + session, tcon, + UINT64_MAX, UINT64_MAX, + FSCTL_PIPE_WAIT, + 0, &state->in_blob, + 0, &state->out_blob, + SMB2_IOCTL_FLAG_IS_FSCTL); + if (tevent_req_nomem(subreq, req)) { + return tevent_req_post(subreq, ev); + } + tevent_req_set_callback(subreq, smb2cli_ioctl_pipe_wait_done, req); + + return req; +} + +static void smb2cli_ioctl_pipe_wait_done(struct tevent_req *subreq) +{ + struct tevent_req *req = tevent_req_callback_data( + subreq, struct tevent_req); + struct smb2cli_ioctl_pipe_wait_state *state = tevent_req_data( + req, struct smb2cli_ioctl_pipe_wait_state); + NTSTATUS status; + + status = smb2cli_ioctl_recv(subreq, state, NULL, NULL); + TALLOC_FREE(subreq); + if (tevent_req_nterror(req, status)) { + return; + } + + tevent_req_done(req); +} + + +NTSTATUS smb2cli_ioctl_pipe_wait_recv(struct tevent_req *req) +{ + NTSTATUS status; + + if (tevent_req_is_nterror(req, &status)) { + tevent_req_received(req); + return status; + } + + tevent_req_received(req); + return NT_STATUS_OK; +} + +NTSTATUS smb2cli_ioctl_pipe_wait(struct smbXcli_conn *conn, + uint32_t timeout_msec, + struct smbXcli_session *session, + struct smbXcli_tcon *tcon, + const char *pipe_name, + uint64_t pipe_wait_timeout) +{ + TALLOC_CTX *frame = talloc_stackframe(); + struct tevent_context *ev = NULL; + struct tevent_req *req = NULL; + NTSTATUS status = NT_STATUS_NO_MEMORY; + + if (smbXcli_conn_has_async_calls(conn)) { + /* + * Can't use sync call while an async call is in flight + */ + status = NT_STATUS_INVALID_PARAMETER_MIX; + goto fail; + } + + ev = samba_tevent_context_init(frame); + if (ev == NULL) { + goto fail; + } + + req = smb2cli_ioctl_pipe_wait_send(frame, ev, conn, timeout_msec, + session, tcon, + pipe_name, pipe_wait_timeout); + if (req == NULL) { + goto fail; + } + if (!tevent_req_poll_ntstatus(req, ev, &status)) { + goto fail; + } + + status = smb2cli_ioctl_pipe_wait_recv(req); + +fail: + TALLOC_FREE(frame); + return status; +} diff --git a/libcli/smb/smbXcli_base.h b/libcli/smb/smbXcli_base.h index f582cc9964c..25ccd84b336 100644 --- a/libcli/smb/smbXcli_base.h +++ b/libcli/smb/smbXcli_base.h @@ -948,4 +948,22 @@ NTSTATUS smb2cli_echo_recv(struct tevent_req *req); NTSTATUS smb2cli_echo(struct smbXcli_conn *conn, uint32_t timeout_msec); +struct tevent_req *smb2cli_ioctl_pipe_wait_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct smbXcli_conn *conn, + uint32_t timeout_msec, + struct smbXcli_session *session, + struct smbXcli_tcon *tcon, + const char *pipe_name, + uint64_t pipe_wait_timeout); + +NTSTATUS smb2cli_ioctl_pipe_wait_recv(struct tevent_req *req); + +NTSTATUS smb2cli_ioctl_pipe_wait(struct smbXcli_conn *conn, + uint32_t timeout_msec, + struct smbXcli_session *session, + struct smbXcli_tcon *tcon, + const char *pipe_name, + uint64_t pipe_wait_timeout); + #endif /* _SMBXCLI_BASE_H_ */ diff --git a/libcli/smb/wscript b/libcli/smb/wscript index 45d8cdb8bb5..984928424db 100644 --- a/libcli/smb/wscript +++ b/libcli/smb/wscript @@ -49,7 +49,7 @@ def build(bld): ''', deps=''' LIBCRYPTO gnutls NDR_SMB2_LEASE_STRUCT samba-errors gensec krb5samba - smb_transport GNUTLS_HELPERS + smb_transport GNUTLS_HELPERS NDR_IOCTL ''', public_deps='talloc samba-util iov_buf', private_library=True, diff --git a/librpc/idl/ioctl.idl b/librpc/idl/ioctl.idl index b2f3aec54d9..7b8b1b85215 100644 --- a/librpc/idl/ioctl.idl +++ b/librpc/idl/ioctl.idl @@ -228,3 +228,15 @@ interface trim uint32 num_ranges_processed; } fsctl_file_level_trim_rsp; } + +interface fsctl +{ + /* MS-FSCC 2.3.31 FSCTL_PIPE_WAIT */ + typedef [public] struct { + hyper timeout; + [value(2*strlen_m(pipe_name))] uint32 pipe_name_len; + uint8 timeout_specified; + uint8 padding; + [charset(UTF16)] uint8 pipe_name[pipe_name_len]; + } fsctl_pipe_wait; +}