s4:libcli/smb2: implement on top of smbXcli_conn/req
authorStefan Metzmacher <metze@samba.org>
Tue, 20 Sep 2011 18:59:45 +0000 (20:59 +0200)
committerStefan Metzmacher <metze@samba.org>
Thu, 24 Nov 2011 18:02:33 +0000 (19:02 +0100)
metze

15 files changed:
source4/libcli/smb2/cancel.c
source4/libcli/smb2/connect.c
source4/libcli/smb2/logoff.c
source4/libcli/smb2/negprot.c [deleted file]
source4/libcli/smb2/read.c
source4/libcli/smb2/request.c
source4/libcli/smb2/session.c
source4/libcli/smb2/smb2.h
source4/libcli/smb2/tcon.c
source4/libcli/smb2/transport.c
source4/libcli/smb2/wscript_build
source4/libcli/smb_composite/smb2.c
source4/librpc/rpc/dcerpc_smb2.c
source4/torture/gentest.c
source4/torture/smb2/compound.c

index 9fcb8cffb51b066d189b1eb60de721f98d03cadc..cc40b34a12d9c28df2fa826b56be666d9e61e953 100644 (file)
@@ -20,6 +20,7 @@
 */
 
 #include "includes.h"
+#include <tevent.h>
 #include "libcli/raw/libcliraw.h"
 #include "libcli/smb2/smb2.h"
 #include "libcli/smb2/smb2_calls.h"
 */
 NTSTATUS smb2_cancel(struct smb2_request *r)
 {
-       NTSTATUS status;
-       struct smb2_request *c;
-       uint32_t old_timeout;
-       uint64_t old_seqnum;
+       bool ok;
 
-       /* 
-        * if we don't get a pending id yet, we just
-        * mark the request for pending, so that we directly
-        * send the cancel after getting the pending id
-        */
-       if (!r->cancel.can_cancel) {
-               r->cancel.do_cancel++;
+       if (r->subreq == NULL) {
                return NT_STATUS_OK;
        }
 
-       /* we don't want a seqmun for a SMB2 Cancel */
-       old_seqnum = r->transport->seqnum;
-       c = smb2_request_init(r->transport, SMB2_OP_CANCEL, 0x04, false, 0);
-       r->transport->seqnum = old_seqnum;
-       NT_STATUS_HAVE_NO_MEMORY(c);
-       c->seqnum = 0;
-
-       SIVAL(c->out.hdr, SMB2_HDR_FLAGS,       0x00000002);
-       SSVAL(c->out.hdr, SMB2_HDR_CREDIT,      0x0030);
-       SBVAL(c->out.hdr, SMB2_HDR_ASYNC_ID,    r->cancel.async_id);
-       SBVAL(c->out.hdr, SMB2_HDR_MESSAGE_ID,  c->seqnum);
-       if (r->session) {
-               SBVAL(c->out.hdr, SMB2_HDR_SESSION_ID,  r->session->uid);
-               c->session = r->session;
-       }
-
-       SSVAL(c->out.body, 0x02, 0);
-
-       old_timeout = c->transport->options.request_timeout;
-       c->transport->options.request_timeout = 0;
-       smb2_transport_send(c);
-       c->transport->options.request_timeout = old_timeout;
-
-       if (c->state == SMB2_REQUEST_ERROR) {
-               status = c->status;
-       } else {
-               status = NT_STATUS_OK;
+       ok = tevent_req_cancel(r->subreq);
+       if (!ok) {
+               return NT_STATUS_INTERNAL_ERROR;
        }
 
-       talloc_free(c);
-       return status;
+       return NT_STATUS_OK;
 }
index 2e837287f559b07e1f574e2298ff0d44c47b33b0..0d97691a440582bf2dd66dbdc7cf747f392be614 100644 (file)
@@ -29,6 +29,7 @@
 #include "libcli/composite/composite.h"
 #include "libcli/resolve/resolve.h"
 #include "param/param.h"
+#include "../libcli/smb/smbXcli_base.h"
 
 struct smb2_connect_state {
        struct tevent_context *ev;
@@ -40,7 +41,7 @@ struct smb2_connect_state {
        const char *socket_options;
        struct gensec_settings *gensec_settings;
        struct smbcli_options options;
-       struct smb2_negprot negprot;
+       struct smb2_transport *transport;
        struct smb2_tree_connect tcon;
        struct smb2_session *session;
        struct smb2_tree *tree;
@@ -132,7 +133,7 @@ static void smb2_connect_resolve_done(struct composite_context *creq)
        creq->async.private_data = req;
 }
 
-static void smb2_connect_negprot_done(struct smb2_request *smb2req);
+static void smb2_connect_negprot_done(struct tevent_req *subreq);
 
 static void smb2_connect_socket_done(struct composite_context *creq)
 {
@@ -143,103 +144,52 @@ static void smb2_connect_socket_done(struct composite_context *creq)
                tevent_req_data(req,
                struct smb2_connect_state);
        struct smbcli_socket *sock;
-       struct smb2_transport *transport;
-       struct smb2_request *smb2req;
+       struct tevent_req *subreq;
        NTSTATUS status;
-       uint16_t dialects[3] = {
-               SMB2_DIALECT_REVISION_000,
-               SMB2_DIALECT_REVISION_202,
-               SMB2_DIALECT_REVISION_210
-       };
+       uint32_t timeout_msec;
 
        status = smbcli_sock_connect_recv(creq, state, &sock);
        if (tevent_req_nterror(req, status)) {
                return;
        }
 
-       transport = smb2_transport_init(sock, state, &state->options);
-       if (tevent_req_nomem(transport, req)) {
+       state->transport = smb2_transport_init(sock, state, &state->options);
+       if (tevent_req_nomem(state->transport, req)) {
                return;
        }
 
-       ZERO_STRUCT(state->negprot);
-       state->negprot.in.dialect_count = ARRAY_SIZE(dialects);
-       switch (transport->options.signing) {
-       case SMB_SIGNING_OFF:
-               state->negprot.in.security_mode = 0;
-               break;
-       case SMB_SIGNING_DEFAULT:
-       case SMB_SIGNING_IF_REQUIRED:
-               state->negprot.in.security_mode = SMB2_NEGOTIATE_SIGNING_ENABLED;
-               break;
-       case SMB_SIGNING_REQUIRED:
-               state->negprot.in.security_mode =
-                       SMB2_NEGOTIATE_SIGNING_ENABLED | SMB2_NEGOTIATE_SIGNING_REQUIRED;
-               break;
-       }
-       state->negprot.in.capabilities  = 0;
-       unix_to_nt_time(&state->negprot.in.start_time, time(NULL));
-       state->negprot.in.dialects = dialects;
+       timeout_msec = state->transport->options.request_timeout * 1000;
 
-       smb2req = smb2_negprot_send(transport, &state->negprot);
-       if (tevent_req_nomem(smb2req, req)) {
+       subreq = smbXcli_negprot_send(state, state->ev,
+                                     state->transport->conn, timeout_msec,
+                                     PROTOCOL_SMB2_02, PROTOCOL_SMB2_22);
+       if (tevent_req_nomem(subreq, req)) {
                return;
        }
-       smb2req->async.fn = smb2_connect_negprot_done;
-       smb2req->async.private_data = req;
+       tevent_req_set_callback(subreq, smb2_connect_negprot_done, req);
 }
 
 static void smb2_connect_session_done(struct tevent_req *subreq);
 
-static void smb2_connect_negprot_done(struct smb2_request *smb2req)
+static void smb2_connect_negprot_done(struct tevent_req *subreq)
 {
        struct tevent_req *req =
-               talloc_get_type_abort(smb2req->async.private_data,
+               tevent_req_callback_data(subreq,
                struct tevent_req);
        struct smb2_connect_state *state =
                tevent_req_data(req,
                struct smb2_connect_state);
-       struct smb2_transport *transport = smb2req->transport;
-       struct tevent_req *subreq;
+       struct smb2_transport *transport = state->transport;
        NTSTATUS status;
 
-       status = smb2_negprot_recv(smb2req, state, &state->negprot);
+       status = smbXcli_negprot_recv(subreq);
+       TALLOC_FREE(subreq);
        if (tevent_req_nterror(req, status)) {
                return;
        }
 
-       transport->negotiate.secblob = state->negprot.out.secblob;
-       talloc_steal(transport, transport->negotiate.secblob.data);
-       transport->negotiate.system_time = state->negprot.out.system_time;
-       transport->negotiate.server_start_time = state->negprot.out.server_start_time;
-       transport->negotiate.security_mode = state->negprot.out.security_mode;
-       transport->negotiate.dialect_revision = state->negprot.out.dialect_revision;
-
-       switch (transport->options.signing) {
-       case SMB_SIGNING_OFF:
-               if (transport->negotiate.security_mode & SMB2_NEGOTIATE_SIGNING_REQUIRED) {
-                       tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
-                       return;
-               }
-               transport->signing_required = false;
-               break;
-       case SMB_SIGNING_DEFAULT:
-       case SMB_SIGNING_IF_REQUIRED:
-               if (transport->negotiate.security_mode & SMB2_NEGOTIATE_SIGNING_REQUIRED) {
-                       transport->signing_required = true;
-               } else {
-                       transport->signing_required = false;
-               }
-               break;
-       case SMB_SIGNING_REQUIRED:
-               if (transport->negotiate.security_mode & SMB2_NEGOTIATE_SIGNING_ENABLED) {
-                       transport->signing_required = true;
-               } else {
-                       tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
-                       return;
-               }
-               break;
-       }
+       /* This is a hack... */
+       smb2cli_conn_set_max_credits(transport->conn, 30);
 
        state->session = smb2_session_init(transport, state->gensec_settings, state, true);
        if (tevent_req_nomem(state->session, req)) {
index e3f83f27d884f6de9786a84fae8c7f672d2b09a7..12cd55311f272473170dbd787ee8850fdd55d209 100644 (file)
@@ -35,8 +35,6 @@ struct smb2_request *smb2_logoff_send(struct smb2_session *session)
 
        req->session = session;
 
-       SBVAL(req->out.hdr,  SMB2_HDR_SESSION_ID, session->uid);
-
        SSVAL(req->out.body, 0x02, 0);
 
        smb2_transport_send(req);
diff --git a/source4/libcli/smb2/negprot.c b/source4/libcli/smb2/negprot.c
deleted file mode 100644 (file)
index 1ff4193..0000000
+++ /dev/null
@@ -1,112 +0,0 @@
-/* 
-   Unix SMB/CIFS implementation.
-
-   SMB2 client negprot handling
-
-   Copyright (C) Andrew Tridgell 2005
-   
-   This program is free software; you can redistribute it and/or modify
-   it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 3 of the License, or
-   (at your option) any later version.
-   
-   This program is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
-   
-   You should have received a copy of the GNU General Public License
-   along with this program.  If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include "includes.h"
-#include "libcli/raw/libcliraw.h"
-#include "libcli/raw/raw_proto.h"
-#include "libcli/smb2/smb2.h"
-#include "libcli/smb2/smb2_calls.h"
-#include "librpc/ndr/libndr.h"
-
-/*
-  send a negprot request
-*/
-struct smb2_request *smb2_negprot_send(struct smb2_transport *transport, 
-                                      struct smb2_negprot *io)
-{
-       struct smb2_request *req;
-       uint16_t size = 0x24 + io->in.dialect_count*2;
-       int i;
-       NTSTATUS status;
-
-       req = smb2_request_init(transport, SMB2_OP_NEGPROT, size, false, 0);
-       if (req == NULL) return NULL;
-
-
-       SSVAL(req->out.body, 0x00, 0x24);
-       SSVAL(req->out.body, 0x02, io->in.dialect_count);
-       SSVAL(req->out.body, 0x04, io->in.security_mode);
-       SSVAL(req->out.body, 0x06, io->in.reserved);
-       SIVAL(req->out.body, 0x08, io->in.capabilities);
-       status = smbcli_push_guid(req->out.body, 0x0C, &io->in.client_guid);
-       if (!NT_STATUS_IS_OK(status)) {
-               talloc_free(req);
-               return NULL;
-       }
-       smbcli_push_nttime(req->out.body, 0x1C, io->in.start_time);
-       for (i=0;i<io->in.dialect_count;i++) {
-               SSVAL(req->out.body, 0x24 + i*2, io->in.dialects[i]);           
-       }
-
-       smb2_transport_send(req);
-
-       return req;
-}
-
-/*
-  recv a negprot reply
-*/
-NTSTATUS smb2_negprot_recv(struct smb2_request *req, TALLOC_CTX *mem_ctx, 
-                          struct smb2_negprot *io)
-{
-       NTSTATUS status;
-
-       if (!smb2_request_receive(req) ||
-           smb2_request_is_error(req)) {
-               return smb2_request_destroy(req);
-       }
-
-       SMB2_CHECK_PACKET_RECV(req, 0x40, true);
-
-       io->out.security_mode      = SVAL(req->in.body, 0x02);
-       io->out.dialect_revision   = SVAL(req->in.body, 0x04);
-       io->out.reserved           = SVAL(req->in.body, 0x06);
-       status = smbcli_pull_guid(req->in.body, 0x08, &io->in.client_guid);
-       if (!NT_STATUS_IS_OK(status)) {
-               smb2_request_destroy(req);
-               return status;
-       }
-       io->out.capabilities       = IVAL(req->in.body, 0x18);
-       io->out.max_transact_size  = IVAL(req->in.body, 0x1C);
-       io->out.max_read_size      = IVAL(req->in.body, 0x20);
-       io->out.max_write_size     = IVAL(req->in.body, 0x24);
-       io->out.system_time        = smbcli_pull_nttime(req->in.body, 0x28);
-       io->out.server_start_time  = smbcli_pull_nttime(req->in.body, 0x30);
-       io->out.reserved2          = IVAL(req->in.body, 0x3C);
-
-       status = smb2_pull_o16s16_blob(&req->in, mem_ctx, req->in.body+0x38, &io->out.secblob);
-       if (!NT_STATUS_IS_OK(status)) {
-               smb2_request_destroy(req);
-               return status;
-       }
-
-       return smb2_request_destroy(req);
-}
-
-/*
-  sync negprot request
-*/
-NTSTATUS smb2_negprot(struct smb2_transport *transport, 
-                     TALLOC_CTX *mem_ctx, struct smb2_negprot *io)
-{
-       struct smb2_request *req = smb2_negprot_send(transport, io);
-       return smb2_negprot_recv(req, mem_ctx, io);
-}
index 9d40e32a4d767766c57093d8262d4aab51893581..ca487a74a17cba1171649e431e4cf10bb6f43684 100644 (file)
@@ -44,6 +44,8 @@ struct smb2_request *smb2_read_send(struct smb2_tree *tree, struct smb2_read *io
        SSVAL(req->out.body, 0x2C, io->in.channel_offset);
        SSVAL(req->out.body, 0x2E, io->in.channel_length);
 
+       req->credit_charge = (MAX(io->in.length, 1) - 1)/ 65536 + 1;
+
        smb2_transport_send(req);
 
        return req;
index cf416a61cfb2d600b57899fbcea61f8b5f52053c..fae995a3967ea8161d8c25ee8cf800f04092a779 100644 (file)
@@ -42,18 +42,6 @@ void smb2_setup_bufinfo(struct smb2_request *req)
        }
 }
 
-
-/* destroy a request structure */
-static int smb2_request_destructor(struct smb2_request *req)
-{
-       if (req->transport) {
-               /* remove it from the list of pending requests (a null op if
-                  its not in the list) */
-               DLIST_REMOVE(req->transport->pending_recv, req);
-       }
-       return 0;
-}
-
 /*
   initialise a smb2 request
 */
@@ -62,9 +50,7 @@ struct smb2_request *smb2_request_init(struct smb2_transport *transport, uint16_
                                       uint32_t body_dynamic_size)
 {
        struct smb2_request *req;
-       uint64_t seqnum;
        uint32_t hdr_offset;
-       uint32_t flags = 0;
        bool compound = false;
 
        if (body_dynamic_present) {
@@ -78,36 +64,17 @@ struct smb2_request *smb2_request_init(struct smb2_transport *transport, uint16_
        req = talloc(transport, struct smb2_request);
        if (req == NULL) return NULL;
 
-       seqnum = transport->seqnum;
-       if (transport->credits.charge > 0) {
-               transport->seqnum += transport->credits.charge;
-       } else {
-               transport->seqnum += 1;
-       }
-
        req->state     = SMB2_REQUEST_INIT;
        req->transport = transport;
        req->session   = NULL;
        req->tree      = NULL;
-       req->seqnum    = seqnum;
+       req->recv_iov  = NULL;
        req->status    = NT_STATUS_OK;
        req->async.fn  = NULL;
-       req->next = req->prev = NULL;
 
        ZERO_STRUCT(req->cancel);
        ZERO_STRUCT(req->in);
-
-       if (transport->compound.missing > 0) {
-               compound = true;
-               transport->compound.missing -= 1;
-               req->out = transport->compound.buffer;
-               ZERO_STRUCT(transport->compound.buffer);
-               if (transport->compound.related) {
-                       flags |= SMB2_HDR_FLAG_CHAINED;
-               }
-       } else {
-               ZERO_STRUCT(req->out);
-       }
+       ZERO_STRUCT(req->out);
 
        if (req->out.size > 0) {
                hdr_offset = req->out.size;
@@ -133,13 +100,13 @@ struct smb2_request *smb2_request_init(struct smb2_transport *transport, uint16_
 
        SIVAL(req->out.hdr, 0,                          SMB2_MAGIC);
        SSVAL(req->out.hdr, SMB2_HDR_LENGTH,            SMB2_HDR_BODY);
-       SSVAL(req->out.hdr, SMB2_HDR_EPOCH,             transport->credits.charge);
+       SSVAL(req->out.hdr, SMB2_HDR_CREDIT_CHARGE,     0);
        SIVAL(req->out.hdr, SMB2_HDR_STATUS,            0);
        SSVAL(req->out.hdr, SMB2_HDR_OPCODE,            opcode);
-       SSVAL(req->out.hdr, SMB2_HDR_CREDIT,            transport->credits.ask_num);
-       SIVAL(req->out.hdr, SMB2_HDR_FLAGS,             flags);
+       SSVAL(req->out.hdr, SMB2_HDR_CREDIT,            0);
+       SIVAL(req->out.hdr, SMB2_HDR_FLAGS,             0);
        SIVAL(req->out.hdr, SMB2_HDR_NEXT_COMMAND,      0);
-       SBVAL(req->out.hdr, SMB2_HDR_MESSAGE_ID,        req->seqnum);
+       SBVAL(req->out.hdr, SMB2_HDR_MESSAGE_ID,        0);
        SIVAL(req->out.hdr, SMB2_HDR_PID,               0);
        SIVAL(req->out.hdr, SMB2_HDR_TID,               0);
        SBVAL(req->out.hdr, SMB2_HDR_SESSION_ID,                0);
@@ -157,8 +124,6 @@ struct smb2_request *smb2_request_init(struct smb2_transport *transport, uint16_
                SCVAL(req->out.dynamic, 0, 0);
        }
 
-       talloc_set_destructor(req, smb2_request_destructor);
-
        return req;
 }
 
@@ -174,7 +139,6 @@ struct smb2_request *smb2_request_init_tree(struct smb2_tree *tree, uint16_t opc
                                                     body_dynamic_size);
        if (req == NULL) return NULL;
 
-       SBVAL(req->out.hdr,  SMB2_HDR_SESSION_ID, tree->session->uid);
        SIVAL(req->out.hdr,  SMB2_HDR_PID, tree->session->pid);
        SIVAL(req->out.hdr,  SMB2_HDR_TID, tree->tid);
        req->session = tree->session;
@@ -214,7 +178,7 @@ bool smb2_request_receive(struct smb2_request *req)
 
        /* keep receiving packets until this one is replied to */
        while (req->state <= SMB2_REQUEST_RECV) {
-               if (tevent_loop_once(req->transport->socket->event.ctx) != 0) {
+               if (tevent_loop_once(req->transport->ev) != 0) {
                        return false;
                }
        }
index 74b8668462f70b72e6bae3549a5a3d30093e66d7..e35a4734de0d0e9d1e9b60ec02c1dc70d2006ab8 100644 (file)
@@ -27,6 +27,8 @@
 #include "libcli/smb2/smb2.h"
 #include "libcli/smb2/smb2_calls.h"
 #include "auth/gensec/gensec.h"
+#include "../libcli/smb/smbXcli_base.h"
+#include "../source3/libsmb/smb2cli.h"
 
 /**
   initialise a smb2_session structure
@@ -50,8 +52,14 @@ struct smb2_session *smb2_session_init(struct smb2_transport *transport,
 
        session->pid = getpid();
 
+       session->smbXcli = smbXcli_session_create(session, transport->conn);
+       if (session->smbXcli == NULL) {
+               talloc_free(session);
+               return NULL;
+       }
+
        /* prepare a gensec context for later use */
-       status = gensec_client_start(session, &session->gensec, 
+       status = gensec_client_start(session, &session->gensec,
                                     settings);
        if (!NT_STATUS_IS_OK(status)) {
                talloc_free(session);
@@ -63,85 +71,16 @@ struct smb2_session *smb2_session_init(struct smb2_transport *transport,
        return session;
 }
 
-/**
-  send a session setup request
-*/
-struct smb2_request *smb2_session_setup_send(struct smb2_session *session, 
-                                            struct smb2_session_setup *io)
-{
-       struct smb2_request *req;
-       NTSTATUS status;
-       
-       req = smb2_request_init(session->transport, SMB2_OP_SESSSETUP, 
-                               0x18, true, io->in.secblob.length);
-       if (req == NULL) return NULL;
-
-       SBVAL(req->out.hdr,  SMB2_HDR_SESSION_ID, session->uid);
-       SCVAL(req->out.body, 0x02, io->in.vc_number);
-       SCVAL(req->out.body, 0x03, io->in.security_mode);
-       SIVAL(req->out.body, 0x04, io->in.capabilities);
-       SIVAL(req->out.body, 0x08, io->in.channel);
-       SBVAL(req->out.body, 0x10, io->in.previous_sessionid);
-
-       req->session = session;
-
-       status = smb2_push_o16s16_blob(&req->out, 0x0C, io->in.secblob);
-       if (!NT_STATUS_IS_OK(status)) {
-               talloc_free(req);
-               return NULL;
-       }
-
-       smb2_transport_send(req);
-
-       return req;
-}
-
-
-/**
-  recv a session setup reply
-*/
-NTSTATUS smb2_session_setup_recv(struct smb2_request *req, TALLOC_CTX *mem_ctx, 
-                                struct smb2_session_setup *io)
-{
-       NTSTATUS status;
-
-       if (!smb2_request_receive(req) || 
-           (smb2_request_is_error(req) && 
-            !NT_STATUS_EQUAL(req->status, NT_STATUS_MORE_PROCESSING_REQUIRED))) {
-               return smb2_request_destroy(req);
-       }
-
-       SMB2_CHECK_PACKET_RECV(req, 0x08, true);
-
-       io->out.session_flags = SVAL(req->in.body, 0x02);
-       io->out.uid           = BVAL(req->in.hdr,  SMB2_HDR_SESSION_ID);
-       
-       status = smb2_pull_o16s16_blob(&req->in, mem_ctx, req->in.body+0x04, &io->out.secblob);
-       if (!NT_STATUS_IS_OK(status)) {
-               smb2_request_destroy(req);
-               return status;
-       }
-
-       return smb2_request_destroy(req);
-}
-
-/*
-  sync session setup request
-*/
-NTSTATUS smb2_session_setup(struct smb2_session *session, 
-                           TALLOC_CTX *mem_ctx, struct smb2_session_setup *io)
-{
-       struct smb2_request *req = smb2_session_setup_send(session, io);
-       return smb2_session_setup_recv(req, mem_ctx, io);
-}
-
 struct smb2_session_setup_spnego_state {
-       struct smb2_session_setup io;
-       struct smb2_request *req;
+       struct tevent_context *ev;
+       struct smb2_session *session;
+       struct cli_credentials *credentials;
        NTSTATUS gensec_status;
+       DATA_BLOB in_secblob;
+       DATA_BLOB out_secblob;
 };
 
-static void smb2_session_setup_spnego_handler(struct smb2_request *req);
+static void smb2_session_setup_spnego_done(struct tevent_req *subreq);
 
 /*
   a composite function that does a full SPNEGO session setup
@@ -154,24 +93,27 @@ struct tevent_req *smb2_session_setup_spnego_send(TALLOC_CTX *mem_ctx,
        struct tevent_req *req;
        struct smb2_session_setup_spnego_state *state;
        const char *chosen_oid;
-       struct smb2_request *subreq;
+       struct tevent_req *subreq;
        NTSTATUS status;
+       const DATA_BLOB *server_gss_blob;
+       DATA_BLOB negprot_secblob = data_blob_null;
+       uint32_t timeout_msec;
+
+       timeout_msec = session->transport->options.request_timeout * 1000;
 
        req = tevent_req_create(mem_ctx, &state,
                                struct smb2_session_setup_spnego_state);
        if (req == NULL) {
                return NULL;
        }
+       state->ev = ev;
+       state->session = session;
+       state->credentials = credentials;
 
-       ZERO_STRUCT(state->io);
-       state->io.in.vc_number          = 0;
-       if (session->transport->signing_required) {
-               state->io.in.security_mode =
-                       SMB2_NEGOTIATE_SIGNING_ENABLED | SMB2_NEGOTIATE_SIGNING_REQUIRED;
+       server_gss_blob = smbXcli_conn_server_gss_blob(session->transport->conn);
+       if (server_gss_blob) {
+               negprot_secblob = *server_gss_blob;
        }
-       state->io.in.capabilities       = 0;
-       state->io.in.channel            = 0;
-       state->io.in.previous_sessionid = 0;
 
        status = gensec_set_credentials(session->gensec, credentials);
        if (tevent_req_nterror(req, status)) {
@@ -179,7 +121,7 @@ struct tevent_req *smb2_session_setup_spnego_send(TALLOC_CTX *mem_ctx,
        }
 
        status = gensec_set_target_hostname(session->gensec,
-                                           session->transport->socket->hostname);
+                                           smbXcli_conn_remote_name(session->transport->conn));
        if (tevent_req_nterror(req, status)) {
                return tevent_req_post(req, ev);
        }
@@ -189,7 +131,7 @@ struct tevent_req *smb2_session_setup_spnego_send(TALLOC_CTX *mem_ctx,
                return tevent_req_post(req, ev);
        }
 
-       if (session->transport->negotiate.secblob.length > 0) {
+       if (negprot_secblob.length > 0) {
                chosen_oid = GENSEC_OID_SPNEGO;
        } else {
                chosen_oid = GENSEC_OID_NTLMSSP;
@@ -201,21 +143,28 @@ struct tevent_req *smb2_session_setup_spnego_send(TALLOC_CTX *mem_ctx,
        }
 
        status = gensec_update(session->gensec, state,
-                              session->transport->socket->event.ctx,
-                              session->transport->negotiate.secblob,
-                              &state->io.in.secblob);
+                              state->ev,
+                              negprot_secblob,
+                              &state->in_secblob);
        if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
                tevent_req_nterror(req, status);
                return tevent_req_post(req, ev);
        }
        state->gensec_status = status;
 
-       subreq = smb2_session_setup_send(session, &state->io);
+       subreq = smb2cli_session_setup_send(state, state->ev,
+                                           session->transport->conn,
+                                           timeout_msec,
+                                           session->smbXcli,
+                                           0, /* in_flags */
+                                           0, /* in_capabilities */
+                                           0, /* in_channel */
+                                           NULL, /* in_previous_session */
+                                           &state->in_secblob);
        if (tevent_req_nomem(subreq, req)) {
                return tevent_req_post(req, ev);
        }
-       subreq->async.fn = smb2_session_setup_spnego_handler;
-       subreq->async.private_data = req;
+       tevent_req_set_callback(subreq, smb2_session_setup_spnego_done, req);
 
        return req;
 }
@@ -223,29 +172,38 @@ struct tevent_req *smb2_session_setup_spnego_send(TALLOC_CTX *mem_ctx,
 /*
   handle continuations of the spnego session setup
 */
-static void smb2_session_setup_spnego_handler(struct smb2_request *subreq)
+static void smb2_session_setup_spnego_done(struct tevent_req *subreq)
 {
        struct tevent_req *req =
-               talloc_get_type_abort(subreq->async.private_data,
+               tevent_req_callback_data(subreq,
                struct tevent_req);
        struct smb2_session_setup_spnego_state *state =
                tevent_req_data(req,
                struct smb2_session_setup_spnego_state);
-       struct smb2_session *session = subreq->session;
+       struct smb2_session *session = state->session;
        NTSTATUS peer_status;
        NTSTATUS status;
+       struct iovec *recv_iov;
+       uint32_t timeout_msec;
+
+       timeout_msec = session->transport->options.request_timeout * 1000;
 
-       status = smb2_session_setup_recv(subreq, state, &state->io);
+       status = smb2cli_session_setup_recv(subreq, state,
+                                           &recv_iov,
+                                           &state->out_secblob);
+       if (!NT_STATUS_IS_OK(status) &&
+           !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
+               tevent_req_nterror(req, status);
+               return;
+       }
        peer_status = status;
-       if (NT_STATUS_EQUAL(peer_status, NT_STATUS_MORE_PROCESSING_REQUIRED) ||
-           (NT_STATUS_IS_OK(peer_status) &&
-            NT_STATUS_EQUAL(state->gensec_status, NT_STATUS_MORE_PROCESSING_REQUIRED))) {
+
+       if (NT_STATUS_EQUAL(state->gensec_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
                status = gensec_update(session->gensec, state,
-                                      session->transport->socket->event.ctx,
-                                      state->io.out.secblob,
-                                      &state->io.in.secblob);
+                                      state->ev,
+                                      state->out_secblob,
+                                      &state->in_secblob);
                state->gensec_status = status;
-               session->uid = state->io.out.uid;
        }
 
        if (!NT_STATUS_IS_OK(status) &&
@@ -254,30 +212,37 @@ static void smb2_session_setup_spnego_handler(struct smb2_request *subreq)
                return;
        }
 
-       if (NT_STATUS_EQUAL(peer_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
-               subreq = smb2_session_setup_send(session, &state->io);
-               if (tevent_req_nomem(subreq, req)) {
+       if (NT_STATUS_IS_OK(peer_status) && NT_STATUS_IS_OK(state->gensec_status)) {
+               status = gensec_session_key(session->gensec, session,
+                                           &session->session_key);
+               if (tevent_req_nterror(req, status)) {
                        return;
                }
 
-               subreq->async.fn = smb2_session_setup_spnego_handler;
-               subreq->async.private_data = req;
-               return;
-       }
-
-       gensec_session_key(session->gensec, session, &session->session_key);
-
-       if (session->transport->signing_required) {
-               if (session->session_key.length == 0) {
-                       DEBUG(0,("Wrong session key length %u for SMB2 signing\n",
-                                (unsigned)session->session_key.length));
-                       tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
+               status = smb2cli_session_update_session_key(session->smbXcli,
+                                                           session->session_key,
+                                                           recv_iov);
+               if (tevent_req_nterror(req, status)) {
                        return;
                }
-               session->signing_active = true;
+
+               tevent_req_done(req);
+               return;
        }
 
-       tevent_req_done(req);
+       subreq = smb2cli_session_setup_send(state, state->ev,
+                                           session->transport->conn,
+                                           timeout_msec,
+                                           session->smbXcli,
+                                           0, /* in_flags */
+                                           0, /* in_capabilities */
+                                           0, /* in_channel */
+                                           NULL, /* in_previous_session */
+                                           &state->in_secblob);
+       if (tevent_req_nomem(subreq, req)) {
+               return;
+       }
+       tevent_req_set_callback(subreq, smb2_session_setup_spnego_done, req);
 }
 
 /*
@@ -298,7 +263,7 @@ NTSTATUS smb2_session_setup_spnego(struct smb2_session *session,
        NTSTATUS status;
        bool ok;
        TALLOC_CTX *frame = talloc_stackframe();
-       struct tevent_context *ev = session->transport->socket->event.ctx;
+       struct tevent_context *ev = session->transport->ev;
 
        if (frame == NULL) {
                return NT_STATUS_NO_MEMORY;
index aaafedd28f00d50a387822f68009d200c3f82367..e8ccdd9dc0e458896c94dd5801dcd9d22fe043c0 100644 (file)
 struct smb2_handle;
 struct smb2_lease_break;
 
-/*
-  information returned from the negotiate process
-*/
-struct smb2_negotiate {
-       DATA_BLOB secblob;
-       NTTIME system_time;
-       NTTIME server_start_time;
-       uint16_t security_mode;
-       uint16_t dialect_revision;
-};
-
 struct smb2_request_buffer {
        /* the raw SMB2 buffer, including the 4 byte length header */
        uint8_t *buffer;
@@ -70,33 +59,15 @@ struct smb2_request_buffer {
 
 /* this is the context for the smb2 transport layer */
 struct smb2_transport {
-       /* socket level info */
-       struct smbcli_socket *socket;
-
-       struct smb2_negotiate negotiate;
-
-       /* next seqnum to allocate */
-       uint64_t seqnum;
+       struct tevent_context *ev; /* TODO: remove this !!! */
+       struct smbXcli_conn *conn;
 
        /* the details for coumpounded requests */
        struct {
-               uint32_t missing;
                bool related;
-               struct smb2_request_buffer buffer;
+               struct tevent_req **reqs;
        } compound;
 
-       struct {
-               uint16_t charge;
-               uint16_t ask_num;
-       } credits;
-
-       /* a list of requests that are pending for receive on this
-          connection */
-       struct smb2_request *pending_recv;
-
-       /* context of the stream -> packet parser */
-       struct packet_context *packet;
-
        /* an idle function - if this is defined then it will be
           called once every period microseconds while we are waiting
           for a packet */
@@ -123,10 +94,9 @@ struct smb2_transport {
                /* private data passed to the oplock handler */
                void *private_data;
        } lease;
+       struct tevent_req *break_subreq;
 
        struct smbcli_options options;
-
-       bool signing_required;
 };
 
 
@@ -144,10 +114,9 @@ struct smb2_tree {
 struct smb2_session {
        struct smb2_transport *transport;
        struct gensec_security *gensec;
-       uint64_t uid;
        uint32_t pid;
        DATA_BLOB session_key;
-       bool signing_active;
+       struct smbXcli_session *smbXcli;
 };
 
 
@@ -162,22 +131,17 @@ enum smb2_request_state {SMB2_REQUEST_INIT, /* we are creating the request */
 
 /* the context for a single SMB2 request */
 struct smb2_request {
-       /* allow a request to be part of a list of requests */
-       struct smb2_request *next, *prev;
-
        /* each request is in one of 3 possible states */
        enum smb2_request_state state;
 
+       struct tevent_req *subreq;
+
        struct smb2_transport *transport;
        struct smb2_session   *session;
        struct smb2_tree      *tree;
 
-       uint64_t seqnum;
-
        struct {
-               bool do_cancel;
                bool can_cancel;
-               uint64_t async_id;
        } cancel;
 
        /* the NT status for this request. Set by packet receive code
@@ -186,6 +150,9 @@ struct smb2_request {
 
        struct smb2_request_buffer in;
        struct smb2_request_buffer out;
+       struct iovec *recv_iov;
+
+       uint16_t credit_charge;
 
        /* information on what to do with a reply when it is received
           asyncronously. If this is not setup when a reply is received then
index ec7152b264edacdbeea34895e2e79617f0b859d6..c5e5b99f73e5c3cb47c71895b737bc220b6c6988 100644 (file)
@@ -56,7 +56,6 @@ struct smb2_request *smb2_tree_connect_send(struct smb2_tree *tree,
                                0x08, true, 0);
        if (req == NULL) return NULL;
 
-       SBVAL(req->out.hdr,  SMB2_HDR_SESSION_ID, tree->session->uid);
        req->session = tree->session;
 
        SSVAL(req->out.body, 0x02, io->in.reserved);
index da0fba8e8e3b66e170e58240933e28a9c87e12e0..01f363b0a09c0c301f0129f376f011a4dda3baea 100644 (file)
@@ -20,6 +20,7 @@
 */
 
 #include "includes.h"
+#include "system/network.h"
 #include "libcli/raw/libcliraw.h"
 #include "libcli/raw/raw_proto.h"
 #include "libcli/smb2/smb2.h"
 #include "lib/events/events.h"
 #include "lib/stream/packet.h"
 #include "../lib/util/dlinklist.h"
-
-
-/*
-  an event has happened on the socket
-*/
-static void smb2_transport_event_handler(struct tevent_context *ev, 
-                                        struct tevent_fd *fde, 
-                                        uint16_t flags, void *private_data)
-{
-       struct smb2_transport *transport = talloc_get_type(private_data,
-                                                          struct smb2_transport);
-       if (flags & TEVENT_FD_READ) {
-               packet_recv(transport->packet);
-               return;
-       }
-       if (flags & TEVENT_FD_WRITE) {
-               packet_queue_run(transport->packet);
-       }
-}
+#include "../libcli/smb/smbXcli_base.h"
 
 /*
   destroy a transport
@@ -57,19 +40,6 @@ static int transport_destructor(struct smb2_transport *transport)
        return 0;
 }
 
-
-/*
-  handle receive errors
-*/
-static void smb2_transport_error(void *private_data, NTSTATUS status)
-{
-       struct smb2_transport *transport = talloc_get_type(private_data,
-                                                          struct smb2_transport);
-       smb2_transport_dead(transport, status);
-}
-
-static NTSTATUS smb2_transport_finish_recv(void *private_data, DATA_BLOB blob);
-
 /*
   create a transport structure based on an established socket
 */
@@ -82,37 +52,24 @@ struct smb2_transport *smb2_transport_init(struct smbcli_socket *sock,
        transport = talloc_zero(parent_ctx, struct smb2_transport);
        if (!transport) return NULL;
 
-       transport->socket = talloc_steal(transport, sock);
+       transport->ev = sock->event.ctx;
        transport->options = *options;
-       transport->credits.charge = 0;
-       transport->credits.ask_num = 1;
 
-       /* setup the stream -> packet parser */
-       transport->packet = packet_init(transport);
-       if (transport->packet == NULL) {
+       TALLOC_FREE(sock->event.fde);
+       TALLOC_FREE(sock->event.te);
+
+       transport->conn = smbXcli_conn_create(transport,
+                                             sock->sock->fd,
+                                             sock->hostname,
+                                             options->signing,
+                                             0, /* smb1_capabilities */
+                                             NULL); /* client_guid */
+       if (transport->conn == NULL) {
                talloc_free(transport);
                return NULL;
        }
-       packet_set_private(transport->packet, transport);
-       packet_set_socket(transport->packet, transport->socket->sock);
-       packet_set_callback(transport->packet, smb2_transport_finish_recv);
-       packet_set_full_request(transport->packet, packet_full_request_nbt);
-       packet_set_error_handler(transport->packet, smb2_transport_error);
-       packet_set_event_context(transport->packet, transport->socket->event.ctx);
-       packet_set_nofree(transport->packet);
-
-       /* take over event handling from the socket layer - it only
-          handles events up until we are connected */
-       talloc_free(transport->socket->event.fde);
-       transport->socket->event.fde = tevent_add_fd(transport->socket->event.ctx,
-                                                   transport->socket,
-                                                   socket_get_fd(transport->socket->sock),
-                                                   TEVENT_FD_READ,
-                                                   smb2_transport_event_handler,
-                                                   transport);
-
-       packet_set_fde(transport->packet, transport->socket->event.fde);
-       packet_set_serialise(transport->packet);
+       sock->sock->fd = -1;
+       TALLOC_FREE(sock);
 
        talloc_set_destructor(transport, transport_destructor);
 
@@ -124,431 +81,343 @@ struct smb2_transport *smb2_transport_init(struct smbcli_socket *sock,
 */
 void smb2_transport_dead(struct smb2_transport *transport, NTSTATUS status)
 {
-       smbcli_sock_dead(transport->socket);
-
        if (NT_STATUS_EQUAL(NT_STATUS_UNSUCCESSFUL, status)) {
                status = NT_STATUS_UNEXPECTED_NETWORK_ERROR;
        }
-
-       /* kill all pending receives */
-       while (transport->pending_recv) {
-               struct smb2_request *req = transport->pending_recv;
-               req->state = SMB2_REQUEST_ERROR;
-               req->status = status;
-               DLIST_REMOVE(transport->pending_recv, req);
-               if (req->async.fn) {
-                       req->async.fn(req);
-               }
+       if (NT_STATUS_IS_OK(status)) {
+               status = NT_STATUS_LOCAL_DISCONNECT;
        }
-}
 
-static NTSTATUS smb2_handle_oplock_break(struct smb2_transport *transport,
-                                        const DATA_BLOB *blob)
-{
-       uint8_t *hdr;
-       uint8_t *body;
-       uint16_t len, bloblen;
-       bool lease;
+       smbXcli_conn_disconnect(transport->conn, status);
+}
 
-       hdr = blob->data+NBT_HDR_SIZE;
-       body = hdr+SMB2_HDR_BODY;
-       bloblen = blob->length - SMB2_HDR_BODY;
+static void smb2_request_done(struct tevent_req *subreq);
+static void smb2_transport_break_handler(struct tevent_req *subreq);
 
-       if (bloblen < 2) {
-               DEBUG(1,("Discarding smb2 oplock reply of size %u\n",
-                       (unsigned)blob->length));
-               return NT_STATUS_INVALID_NETWORK_RESPONSE;
+/*
+  put a request into the send queue
+*/
+void smb2_transport_send(struct smb2_request *req)
+{
+       NTSTATUS status;
+       struct smb2_transport *transport = req->transport;
+       struct tevent_req **reqs = transport->compound.reqs;
+       size_t num_reqs = talloc_array_length(reqs);
+       size_t i;
+       uint16_t cmd = SVAL(req->out.hdr, SMB2_HDR_OPCODE);
+       uint32_t additional_flags = IVAL(req->out.hdr, SMB2_HDR_FLAGS);
+       uint32_t clear_flags = 0;
+       uint32_t pid = IVAL(req->out.hdr, SMB2_HDR_PID);
+       uint32_t tid = IVAL(req->out.hdr, SMB2_HDR_TID);
+       struct smbXcli_session *session = NULL;
+       bool need_pending_break = false;
+       size_t hdr_ofs;
+       size_t pdu_len;
+       DATA_BLOB body = data_blob_null;
+       DATA_BLOB dyn = data_blob_null;
+       uint32_t timeout_msec = transport->options.request_timeout * 1000;
+
+       if (transport->oplock.handler) {
+               need_pending_break = true;
+       }
+
+       if (transport->lease.handler) {
+               need_pending_break = true;
+       }
+
+       if (transport->break_subreq) {
+               need_pending_break = false;
+       }
+
+       if (need_pending_break) {
+               struct tevent_req *subreq;
+
+               subreq = smb2cli_req_create(transport,
+                                           transport->ev,
+                                           transport->conn,
+                                           SMB2_OP_BREAK,
+                                           0, /* additional_flags */
+                                           0, /*clear_flags */
+                                           0, /* timeout_msec */
+                                           0, /* pid */
+                                           0, /* tid */
+                                           NULL, /* session */
+                                           NULL, /* body */
+                                           0, /* body_fixed */
+                                           NULL, /* dyn */
+                                           0); /* dyn_len */
+               if (subreq != NULL) {
+                       smbXcli_req_set_pending(subreq);
+                       tevent_req_set_callback(subreq,
+                                               smb2_transport_break_handler,
+                                               transport);
+                       transport->break_subreq = subreq;
+               }
        }
 
-       len = CVAL(body, 0x00);
-       if (len > bloblen) {
-               DEBUG(1,("Discarding smb2 oplock reply,"
-                       "packet claims %u byte body, only %u bytes seen\n",
-                       len, bloblen));
-               return NT_STATUS_INVALID_NETWORK_RESPONSE;
+       if (req->session) {
+               session = req->session->smbXcli;
        }
 
-       if (len == 24) {
-               lease = false;
-       } else if (len == 44) {
-               lease = true;
-       } else {
-               DEBUG(1,("Discarding smb2 oplock reply of invalid size %u\n",
-                       (unsigned)blob->length));
-               return NT_STATUS_INVALID_NETWORK_RESPONSE;
+       if (transport->compound.related) {
+               additional_flags |= SMB2_HDR_FLAG_CHAINED;
        }
 
-       if (!lease && transport->oplock.handler) {
-               struct smb2_handle h;
-               uint8_t level;
-
-               level = CVAL(body, 0x02);
-               smb2_pull_handle(body+0x08, &h);
-
-               transport->oplock.handler(transport, &h, level,
-                                         transport->oplock.private_data);
-       } else if (lease && transport->lease.handler) {
-               struct smb2_lease_break lb;
+       hdr_ofs = PTR_DIFF(req->out.hdr, req->out.buffer);
+       pdu_len = req->out.size - hdr_ofs;
+       body.data = req->out.body;
+       body.length = req->out.body_fixed;
+       dyn.data = req->out.body + req->out.body_fixed;
+       dyn.length = pdu_len - (SMB2_HDR_BODY + req->out.body_fixed);
 
-               ZERO_STRUCT(lb);
-               lb.break_flags =                SVAL(body, 0x4);
-               memcpy(&lb.current_lease.lease_key, body+0x8,
-                   sizeof(struct smb2_lease_key));
-               lb.current_lease.lease_state =  SVAL(body, 0x18);
-               lb.new_lease_state =            SVAL(body, 0x1C);
-               lb.break_reason =               SVAL(body, 0x20);
-               lb.access_mask_hint =           SVAL(body, 0x24);
-               lb.share_mask_hint =            SVAL(body, 0x28);
-
-               transport->lease.handler(transport, &lb,
-                   transport->lease.private_data);
-       } else {
-               DEBUG(5,("Got SMB2 %s break with no handler\n",
-                       lease ? "lease" : "oplock"));
+       req->subreq = smb2cli_req_create(req,
+                                        transport->ev,
+                                        transport->conn,
+                                        cmd,
+                                        additional_flags,
+                                        clear_flags,
+                                        timeout_msec,
+                                        pid,
+                                        tid,
+                                        session,
+                                        body.data, body.length,
+                                        dyn.data, dyn.length);
+       if (req->subreq == NULL) {
+               req->state = SMB2_REQUEST_ERROR;
+               req->status = NT_STATUS_NO_MEMORY;
+               return;
        }
 
-       return NT_STATUS_OK;
-}
-
-struct smb2_transport_compount_response_state {
-       struct smb2_transport *transport;
-       DATA_BLOB blob;
-};
-
-static void smb2_transport_compound_response_handler(struct tevent_context *ctx,
-                                                    struct tevent_immediate *im,
-                                                    void *private_data)
-{
-       struct smb2_transport_compount_response_state *state =
-               talloc_get_type_abort(private_data,
-               struct smb2_transport_compount_response_state);
-       struct smb2_transport *transport = state->transport;
-       NTSTATUS status;
-
-       status = smb2_transport_finish_recv(transport, state->blob);
-       TALLOC_FREE(state);
-       if (!NT_STATUS_IS_OK(status)) {
-               smb2_transport_error(transport, status);
+       if (!tevent_req_is_in_progress(req->subreq)) {
+               req->state = SMB2_REQUEST_ERROR;
+               req->status = NT_STATUS_INTERNAL_ERROR;/* TODO */
+               return;
        }
-}
 
-/*
-  we have a full request in our receive buffer - match it to a pending request
-  and process
- */
-static NTSTATUS smb2_transport_finish_recv(void *private_data, DATA_BLOB blob)
-{
-       struct smb2_transport *transport = talloc_get_type(private_data,
-                                                            struct smb2_transport);
-       uint8_t *buffer, *hdr;
-       int len;
-       struct smb2_request *req = NULL;
-       uint64_t seqnum;
-       uint32_t flags;
-       uint16_t buffer_code;
-       uint32_t dynamic_size;
-       uint32_t i;
-       uint16_t opcode;
-       NTSTATUS status;
-       uint32_t next_ofs;
-
-       buffer = blob.data;
-       len = blob.length;
-
-       hdr = buffer+NBT_HDR_SIZE;
+       tevent_req_set_callback(req->subreq, smb2_request_done, req);
 
-       if (len < SMB2_MIN_SIZE) {
-               DEBUG(1,("Discarding smb2 reply of size %d\n", len));
-               goto error;
+       smb2cli_req_set_notify_async(req->subreq);
+       if (req->credit_charge) {
+               smb2cli_req_set_credit_charge(req->subreq, req->credit_charge);
        }
 
-       flags   = IVAL(hdr, SMB2_HDR_FLAGS);
-       seqnum  = BVAL(hdr, SMB2_HDR_MESSAGE_ID);
-       opcode  = SVAL(hdr, SMB2_HDR_OPCODE);
+       ZERO_STRUCT(req->out);
+       req->state = SMB2_REQUEST_RECV;
 
-       /* see MS-SMB2 3.2.5.19 */
-       if (seqnum == UINT64_MAX) {
-               if (opcode != SMB2_OP_BREAK) {
-                       DEBUG(1,("Discarding packet with invalid seqnum, "
-                               "opcode %u\n", opcode));
-                       return NT_STATUS_INVALID_NETWORK_RESPONSE;
-               }
+       if (num_reqs > 0) {
+               for (i=0; i < num_reqs; i++) {
+                       if (reqs[i] != NULL) {
+                               continue;
+                       }
 
-               return smb2_handle_oplock_break(transport, &blob);
-       }
+                       reqs[i] = req->subreq;
+                       i++;
+                       break;
+               }
 
-       if (opcode == SMB2_OP_CANCEL) {
-               /*
-                * ignore responses to cancel requests,
-                * this can happen if signing was wrong or
-                * we specified the wrong session id
-                */
-               talloc_free(buffer);
-               return NT_STATUS_OK;
+               if (i < num_reqs) {
+                       return;
+               }
+       } else {
+               reqs = &req->subreq;
+               num_reqs = 1;
        }
+       status = smb2cli_req_compound_submit(reqs, num_reqs);
 
-       /* match the incoming request against the list of pending requests */
-       for (req=transport->pending_recv; req; req=req->next) {
-               if (req->seqnum == seqnum) break;
-       }
+       TALLOC_FREE(transport->compound.reqs);
 
-       if (!req) {
-               DEBUG(1,("Discarding unmatched reply with seqnum 0x%llx op %d\n", 
-                        (long long)seqnum, SVAL(hdr, SMB2_HDR_OPCODE)));
-               goto error;
+       if (!NT_STATUS_IS_OK(status)) {
+               smbXcli_conn_disconnect(transport->conn, status);
        }
+}
 
-       /* fill in the 'in' portion of the matching request */
-       req->in.buffer = buffer;
-       talloc_steal(req, buffer);
-       req->in.size = len;
-       req->in.allocated = req->in.size;
+static void smb2_request_done(struct tevent_req *subreq)
+{
+       struct smb2_request *req =
+               tevent_req_callback_data(subreq,
+               struct smb2_request);
+       ssize_t len;
+       size_t i;
 
-       req->in.hdr       = hdr;
-       req->in.body      = hdr+SMB2_HDR_BODY;
-       req->in.body_size = req->in.size - (SMB2_HDR_BODY+NBT_HDR_SIZE);
-       req->status       = NT_STATUS(IVAL(hdr, SMB2_HDR_STATUS));
+       req->recv_iov = NULL;
 
-       if ((flags & SMB2_HDR_FLAG_ASYNC) &&
-           NT_STATUS_EQUAL(req->status, STATUS_PENDING)) {
+       req->status = smb2cli_req_recv(req->subreq, req, &req->recv_iov, NULL, 0);
+       if (NT_STATUS_EQUAL(req->status, STATUS_PENDING)) {
                req->cancel.can_cancel = true;
-               req->cancel.async_id = BVAL(hdr, SMB2_HDR_ASYNC_ID);
-               for (i=0; i< req->cancel.do_cancel; i++) {
-                       smb2_cancel(req);
-               }
-               talloc_free(buffer);
-               return NT_STATUS_OK;
-       }
-
-       next_ofs = IVAL(req->in.hdr, SMB2_HDR_NEXT_COMMAND);
-       if (next_ofs > 0) {
-               if (smb2_oob(&req->in, req->in.hdr + next_ofs, SMB2_HDR_BODY + 2)) {
-                       DEBUG(1,("SMB2 request invalid next offset 0x%x\n",
-                                next_ofs));
-                       goto error;
-               }
-
-               req->in.size = NBT_HDR_SIZE + next_ofs;
-               req->in.body_size = req->in.size - (SMB2_HDR_BODY+NBT_HDR_SIZE);
-       }
-
-       if (req->session && req->session->signing_active &&
-           !NT_STATUS_EQUAL(req->status, NT_STATUS_USER_SESSION_DELETED)) {
-               status = smb2_check_signature(&req->in, 
-                                             req->session->session_key);
-               if (!NT_STATUS_IS_OK(status)) {
-                       /* the spec says to ignore packets with a bad signature */
-                       talloc_free(buffer);
-                       return status;
-               }
+               return;
        }
-
-       buffer_code = SVAL(req->in.body, 0);
-       req->in.body_fixed = (buffer_code & ~1);
-       req->in.dynamic = NULL;
-       dynamic_size = req->in.body_size - req->in.body_fixed;
-       if (dynamic_size != 0 && (buffer_code & 1)) {
-               req->in.dynamic = req->in.body + req->in.body_fixed;
-               if (smb2_oob(&req->in, req->in.dynamic, dynamic_size)) {
-                       DEBUG(1,("SMB2 request invalid dynamic size 0x%x\n", 
-                                dynamic_size));
-                       goto error;
+       TALLOC_FREE(req->subreq);
+       if (!NT_STATUS_IS_OK(req->status)) {
+               if (req->recv_iov == NULL) {
+                       req->state = SMB2_REQUEST_ERROR;
+                       if (req->async.fn) {
+                               req->async.fn(req);
+                       }
+                       return;
                }
        }
 
-       smb2_setup_bufinfo(req);
-
-       DEBUG(2, ("SMB2 RECV seqnum=0x%llx\n", (long long)req->seqnum));
-       dump_data(5, req->in.body, req->in.body_size);
+       len = req->recv_iov[0].iov_len;
+       for (i=1; i < 3; i++) {
+               uint8_t *p = req->recv_iov[i-1].iov_base;
+               uint8_t *c1 = req->recv_iov[i].iov_base;
+               uint8_t *c2 = p + req->recv_iov[i-1].iov_len;
 
-       if (next_ofs > 0) {
-               struct tevent_immediate *im;
-               struct smb2_transport_compount_response_state *state;
+               len += req->recv_iov[i].iov_len;
 
-               state = talloc(transport,
-                              struct smb2_transport_compount_response_state);
-               if (!state) {
-                       goto error;
+               if (req->recv_iov[i].iov_len == 0) {
+                       continue;
                }
-               state->transport = transport;
 
-               state->blob = data_blob_talloc(state, NULL,
-                                              blob.length - next_ofs);
-               if (!state->blob.data) {
-                       goto error;
-               }
-               im = tevent_create_immediate(state);
-               if (!im) {
-                       TALLOC_FREE(state);
-                       goto error;
+               if (c1 != c2) {
+                       req->status = NT_STATUS_INTERNAL_ERROR;
+                       req->state = SMB2_REQUEST_ERROR;
+                       if (req->async.fn) {
+                               req->async.fn(req);
+                       }
+                       return;
                }
-               _smb_setlen_tcp(state->blob.data, state->blob.length - NBT_HDR_SIZE);
-               memcpy(state->blob.data + NBT_HDR_SIZE,
-                      req->in.hdr + next_ofs,
-                      req->in.allocated - req->in.size);
-               tevent_schedule_immediate(im, transport->socket->event.ctx,
-                                         smb2_transport_compound_response_handler,
-                                         state);
        }
 
-       /* if this request has an async handler then call that to
-          notify that the reply has been received. This might destroy
-          the request so it must happen last */
-       DLIST_REMOVE(transport->pending_recv, req);
-       req->state = SMB2_REQUEST_DONE;
-       if (req->async.fn) {
-               req->async.fn(req);
-       }
-       return NT_STATUS_OK;
+       req->in.buffer = req->recv_iov[0].iov_base;
+       req->in.size = len;
+       req->in.allocated = req->in.size;
 
-error:
-       dump_data(5, buffer, len);
-       if (req) {
-               DLIST_REMOVE(transport->pending_recv, req);
-               req->state = SMB2_REQUEST_ERROR;
-               if (req->async.fn) {
-                       req->async.fn(req);
-               }
-       } else {
-               talloc_free(buffer);
-       }
-       return NT_STATUS_UNSUCCESSFUL;
-}
+       req->in.hdr        =  req->recv_iov[0].iov_base;
+       req->in.body       =  req->recv_iov[1].iov_base;
+       req->in.dynamic    =  req->recv_iov[2].iov_base;
+       req->in.body_fixed =  req->recv_iov[1].iov_len;
+       req->in.body_size  =  req->in.body_fixed;
+       req->in.body_size  += req->recv_iov[2].iov_len;
 
-/*
-  handle timeouts of individual smb requests
-*/
-static void smb2_timeout_handler(struct tevent_context *ev, struct tevent_timer *te, 
-                                struct timeval t, void *private_data)
-{
-       struct smb2_request *req = talloc_get_type(private_data, struct smb2_request);
+       smb2_setup_bufinfo(req);
 
-       if (req->state == SMB2_REQUEST_RECV) {
-               DLIST_REMOVE(req->transport->pending_recv, req);
-       }
-       req->status = NT_STATUS_IO_TIMEOUT;
-       req->state = SMB2_REQUEST_ERROR;
+       req->state = SMB2_REQUEST_DONE;
        if (req->async.fn) {
                req->async.fn(req);
        }
 }
 
-
-/*
-  destroy a request
-*/
-static int smb2_request_destructor(struct smb2_request *req)
-{
-       if (req->state == SMB2_REQUEST_RECV) {
-               DLIST_REMOVE(req->transport->pending_recv, req);
-       }
-       return 0;
-}
-
-static NTSTATUS smb2_transport_raw_send(struct smb2_transport *transport,
-                                       struct smb2_request_buffer *buffer)
+static void smb2_transport_break_handler(struct tevent_req *subreq)
 {
-       DATA_BLOB blob;
+       struct smb2_transport *transport =
+               tevent_req_callback_data(subreq,
+               struct smb2_transport);
        NTSTATUS status;
+       uint8_t *hdr;
+       uint8_t *body;
+       uint16_t len = 0;
+       bool lease;
+       struct iovec *recv_iov = NULL;
 
-       /* check if the transport is dead */
-       if (transport->socket->sock == NULL) {
-               return NT_STATUS_NET_WRITE_FAULT;
-       }
+       transport->break_subreq = NULL;
 
-       _smb_setlen_tcp(buffer->buffer, buffer->size - NBT_HDR_SIZE);
-       blob = data_blob_const(buffer->buffer, buffer->size);
-       status = packet_send(transport->packet, blob);
+       status = smb2cli_req_recv(subreq, transport, &recv_iov, NULL, 0);
+       TALLOC_FREE(subreq);
        if (!NT_STATUS_IS_OK(status)) {
-               return status;
+               TALLOC_FREE(recv_iov);
+               smb2_transport_dead(transport, status);
+               return;
        }
 
-       return NT_STATUS_OK;
-}
-
-/*
-  put a request into the send queue
-*/
-void smb2_transport_send(struct smb2_request *req)
-{
-       NTSTATUS status;
-
-       DEBUG(2, ("SMB2 send seqnum=0x%llx\n", (long long)req->seqnum));
-       dump_data(5, req->out.body, req->out.body_size);
+       /*
+        * Setup the subreq to handle the
+        * next incoming SMB2 Break.
+        */
+       subreq = smb2cli_req_create(transport,
+                                   transport->ev,
+                                   transport->conn,
+                                   SMB2_OP_BREAK,
+                                   0, /* additional_flags */
+                                   0, /*clear_flags */
+                                   0, /* timeout_msec */
+                                   0, /* pid */
+                                   0, /* tid */
+                                   NULL, /* session */
+                                   NULL, /* body */
+                                   0, /* body_fixed */
+                                   NULL, /* dyn */
+                                   0); /* dyn_len */
+       if (subreq != NULL) {
+               smbXcli_req_set_pending(subreq);
+               tevent_req_set_callback(subreq,
+                                       smb2_transport_break_handler,
+                                       transport);
+               transport->break_subreq = subreq;
+       }
+
+       hdr = recv_iov[0].iov_base;
+       body = recv_iov[1].iov_base;
+
+       len = recv_iov[1].iov_len;
+       if (recv_iov[1].iov_len >= 2) {
+               len = CVAL(body, 0x00);
+               if (len != recv_iov[1].iov_len) {
+                       len = recv_iov[1].iov_len;
+               }
+       }
 
-       if (req->transport->compound.missing > 0) {
-               off_t next_ofs;
-               size_t pad = 0;
-               uint8_t *end;
+       if (len == 24) {
+               lease = false;
+       } else if (len == 44) {
+               lease = true;
+       } else {
+               DEBUG(1,("Discarding smb2 oplock reply of invalid size %u\n",
+                       (unsigned)len));
+               TALLOC_FREE(recv_iov);
+               status = NT_STATUS_INVALID_NETWORK_RESPONSE;
+               smb2_transport_dead(transport, status);
+               return;
+       }
 
-               end = req->out.buffer + req->out.size;
+       if (!lease && transport->oplock.handler) {
+               struct smb2_handle h;
+               uint8_t level;
 
-               /*
-                * we need to set dynamic otherwise
-                * smb2_grow_buffer segfaults
-                */
-               if (req->out.dynamic == NULL) {
-                       req->out.dynamic = end;
-               }
+               level = CVAL(body, 0x02);
+               smb2_pull_handle(body+0x08, &h);
 
-               next_ofs = end - req->out.hdr;
-               if ((next_ofs % 8) > 0) {
-                       pad = 8 - (next_ofs % 8);
-               }
-               next_ofs += pad;
+               TALLOC_FREE(recv_iov);
 
-               status = smb2_grow_buffer(&req->out, pad);
-               if (!NT_STATUS_IS_OK(status)) {
-                       req->state = SMB2_REQUEST_ERROR;
-                       req->status = status;
-                       return;
-               }
-               req->out.size += pad;
+               transport->oplock.handler(transport, &h, level,
+                                         transport->oplock.private_data);
+       } else if (lease && transport->lease.handler) {
+               struct smb2_lease_break lb;
 
-               SIVAL(req->out.hdr, SMB2_HDR_NEXT_COMMAND, next_ofs);
-       }
+               ZERO_STRUCT(lb);
+               lb.break_flags =                SVAL(body, 0x4);
+               memcpy(&lb.current_lease.lease_key, body+0x8,
+                   sizeof(struct smb2_lease_key));
+               lb.current_lease.lease_state =  SVAL(body, 0x18);
+               lb.new_lease_state =            SVAL(body, 0x1C);
+               lb.break_reason =               SVAL(body, 0x20);
+               lb.access_mask_hint =           SVAL(body, 0x24);
+               lb.share_mask_hint =            SVAL(body, 0x28);
 
-       /* possibly sign the message */
-       if (req->session && req->session->signing_active) {
-               status = smb2_sign_message(&req->out, req->session->session_key);
-               if (!NT_STATUS_IS_OK(status)) {
-                       req->state = SMB2_REQUEST_ERROR;
-                       req->status = status;
-                       return;
-               }
-       }
+               TALLOC_FREE(recv_iov);
 
-       if (req->transport->compound.missing > 0) {
-               req->transport->compound.buffer = req->out;
+               transport->lease.handler(transport, &lb,
+                   transport->lease.private_data);
        } else {
-               status = smb2_transport_raw_send(req->transport,
-                                                &req->out);
-               if (!NT_STATUS_IS_OK(status)) {
-                       req->state = SMB2_REQUEST_ERROR;
-                       req->status = status;
-                       return;
-               }
-       }
-       ZERO_STRUCT(req->out);
-
-       req->state = SMB2_REQUEST_RECV;
-       DLIST_ADD(req->transport->pending_recv, req);
-
-       /* add a timeout */
-       if (req->transport->options.request_timeout) {
-               tevent_add_timer(req->transport->socket->event.ctx, req,
-                               timeval_current_ofs(req->transport->options.request_timeout, 0), 
-                               smb2_timeout_handler, req);
+               DEBUG(5,("Got SMB2 %s break with no handler\n",
+                       lease ? "lease" : "oplock"));
        }
-
-       talloc_set_destructor(req, smb2_request_destructor);
+       TALLOC_FREE(recv_iov);
 }
 
 NTSTATUS smb2_transport_compound_start(struct smb2_transport *transport,
                                       uint32_t num)
 {
+       TALLOC_FREE(transport->compound.reqs);
        ZERO_STRUCT(transport->compound);
-       transport->compound.missing = num;
+
+       transport->compound.reqs = talloc_zero_array(transport,
+                                                    struct tevent_req *,
+                                                    num);
+       if (transport->compound.reqs == NULL) {
+               return NT_STATUS_NO_MEMORY;
+       }
+
        return NT_STATUS_OK;
 }
 
@@ -561,13 +430,7 @@ void smb2_transport_compound_set_related(struct smb2_transport *transport,
 void smb2_transport_credits_ask_num(struct smb2_transport *transport,
                                    uint16_t ask_num)
 {
-       transport->credits.ask_num = ask_num;
-}
-
-void smb2_transport_credits_set_charge(struct smb2_transport *transport,
-                                      uint16_t charge)
-{
-       transport->credits.charge = charge;
+       smb2cli_conn_set_max_credits(transport->conn, ask_num);
 }
 
 static void idle_handler(struct tevent_context *ev, 
@@ -576,10 +439,10 @@ static void idle_handler(struct tevent_context *ev,
        struct smb2_transport *transport = talloc_get_type(private_data,
                                                           struct smb2_transport);
        struct timeval next = timeval_add(&t, 0, transport->idle.period);
-       transport->socket->event.te = tevent_add_timer(transport->socket->event.ctx,
-                                                     transport,
-                                                     next,
-                                                     idle_handler, transport);
+       tevent_add_timer(transport->ev,
+                        transport,
+                        next,
+                        idle_handler, transport);
        transport->idle.func(transport, transport->idle.private_data);
 }
 
@@ -596,12 +459,8 @@ void smb2_transport_idle_handler(struct smb2_transport *transport,
        transport->idle.private_data = private_data;
        transport->idle.period = period;
 
-       if (transport->socket->event.te != NULL) {
-               talloc_free(transport->socket->event.te);
-       }
-
-       transport->socket->event.te = tevent_add_timer(transport->socket->event.ctx,
-                                                     transport,
-                                                     timeval_current_ofs(0, period),
-                                                     idle_handler, transport);
+       tevent_add_timer(transport->ev,
+                        transport,
+                        timeval_current_ofs(0, period),
+                        idle_handler, transport);
 }
index 8aac8272e395285c7952e62c06402f6f91a9b710..d2478a4497f334c53bee850170cfb1ec4bf9b322 100644 (file)
@@ -1,9 +1,9 @@
 #!/usr/bin/env python
 
 bld.SAMBA_SUBSYSTEM('LIBCLI_SMB2',
-       source='transport.c request.c negprot.c session.c tcon.c create.c close.c connect.c getinfo.c write.c read.c setinfo.c find.c ioctl.c logoff.c tdis.c flush.c lock.c notify.c cancel.c keepalive.c break.c util.c signing.c lease_break.c',
+       source='transport.c request.c session.c tcon.c create.c close.c connect.c getinfo.c write.c read.c setinfo.c find.c ioctl.c logoff.c tdis.c flush.c lock.c notify.c cancel.c keepalive.c break.c util.c signing.c lease_break.c',
        autoproto='smb2_proto.h',
-       deps='tevent-util',
+       deps='tevent-util libsmb',
        public_deps='smbclient-raw LIBPACKET gensec tevent'
        )
 
index 5c93869b5c82dc06c31590087fe44e5ed216b1ea..0fa51b2857965d3304ba1f93ce322f956ce9e268 100644 (file)
@@ -82,7 +82,7 @@ struct composite_context *smb2_composite_unlink_send(struct smb2_tree *tree,
        struct smb2_create create_parm;
        struct smb2_request *req;
 
-       ctx = composite_create(tree, tree->session->transport->socket->event.ctx);
+       ctx = composite_create(tree, tree->session->transport->ev);
        if (ctx == NULL) return NULL;
 
        /* check for wildcards - we could support these with a
@@ -161,7 +161,7 @@ struct composite_context *smb2_composite_mkdir_send(struct smb2_tree *tree,
        struct smb2_create create_parm;
        struct smb2_request *req;
 
-       ctx = composite_create(tree, tree->session->transport->socket->event.ctx);
+       ctx = composite_create(tree, tree->session->transport->ev);
        if (ctx == NULL) return NULL;
 
        ZERO_STRUCT(create_parm);
@@ -232,7 +232,7 @@ struct composite_context *smb2_composite_rmdir_send(struct smb2_tree *tree,
        struct smb2_create create_parm;
        struct smb2_request *req;
 
-       ctx = composite_create(tree, tree->session->transport->socket->event.ctx);
+       ctx = composite_create(tree, tree->session->transport->ev);
        if (ctx == NULL) return NULL;
 
        ZERO_STRUCT(create_parm);
@@ -416,7 +416,7 @@ NTSTATUS smb2_composite_setpathinfo(struct smb2_tree *tree, union smb_setfileinf
        NTSTATUS status;
        bool ok;
        TALLOC_CTX *frame = talloc_stackframe();
-       struct tevent_context *ev = tree->session->transport->socket->event.ctx;
+       struct tevent_context *ev = tree->session->transport->ev;
 
        if (frame == NULL) {
                return NT_STATUS_NO_MEMORY;
index 0de89357978cd2e6ee5eb75b6a996a7f6edddeb4..ecc250412ae3c8332133f566b7a65988c60efae8 100644 (file)
@@ -28,6 +28,7 @@
 #include "librpc/rpc/dcerpc.h"
 #include "librpc/rpc/dcerpc_proto.h"
 #include "librpc/rpc/rpc_common.h"
+#include "../libcli/smb/smbXcli_base.h"
 
 /* transport private information used by SMB2 pipe transport */
 struct smb2_private {
@@ -377,7 +378,7 @@ static const char *smb2_target_hostname(struct dcecli_connection *c)
 {
        struct smb2_private *smb = talloc_get_type(c->transport.private_data, 
                                                   struct smb2_private);
-       return smb->tree->session->transport->socket->hostname;
+       return smbXcli_conn_remote_name(smb->tree->session->transport->conn);
 }
 
 /*
@@ -488,7 +489,7 @@ static void pipe_open_recv(struct smb2_request *req)
        smb->handle     = io.out.file.handle;
        smb->tree       = talloc_reference(smb, tree);
        smb->server_name= strupper_talloc(smb, 
-                                         tree->session->transport->socket->hostname);
+                                         smbXcli_conn_remote_name(tree->session->transport->conn));
        if (composite_nomem(smb->server_name, ctx)) return;
        smb->dead       = false;
 
index 9b6e7fc0fd51bfeeafc3716eb8558f723bc455fa..c7e32de359b81531c09b4b7590f1ece29724960b 100644 (file)
@@ -38,6 +38,7 @@
 #include "dynconfig/dynconfig.h"
 #include "libcli/security/security.h"
 #include "libcli/raw/raw_proto.h"
+#include "../libcli/smb/smbXcli_base.h"
 
 #define NSERVERS 2
 #define NINSTANCES 2
@@ -279,13 +280,21 @@ static bool connect_servers(struct tevent_context *ev,
 static unsigned int time_skew(void)
 {
        unsigned int ret;
+       NTTIME nt0, nt1;
+
        if (options.smb2) {
-               ret = labs(servers[0].smb2_tree[0]->session->transport->negotiate.system_time -
-                          servers[1].smb2_tree[0]->session->transport->negotiate.system_time);
+               struct smbXcli_conn *c0, *c1;
+
+               c0 = servers[0].smb2_tree[0]->session->transport->conn;
+               c1 = servers[1].smb2_tree[0]->session->transport->conn;
+
+               nt0 = smbXcli_conn_server_system_time(c0);
+               nt1 = smbXcli_conn_server_system_time(c1);
        } else {
-               ret = labs(servers[0].smb_tree[0]->session->transport->negotiate.server_time -
-                          servers[1].smb_tree[0]->session->transport->negotiate.server_time);
+               nt0 = servers[0].smb_tree[0]->session->transport->negotiate.server_time;
+               nt1 = servers[1].smb_tree[0]->session->transport->negotiate.server_time;
        }
+       ret = labs(nt0 - nt1);
        return ret + 300;
 }
 
index 1caa688a3558b275734b21ea364b032e1e0bd190..cb5b744c5dff64c2dcb45ded13ba04715ce4384f 100644 (file)
@@ -24,6 +24,7 @@
 #include "libcli/smb2/smb2_calls.h"
 #include "torture/torture.h"
 #include "torture/smb2/proto.h"
+#include "../libcli/smb/smbXcli_base.h"
 
 #define CHECK_STATUS(status, correct) do { \
        if (!NT_STATUS_EQUAL(status, correct)) { \
@@ -47,7 +48,7 @@ static bool test_compound_related1(struct torture_context *tctx,
        bool ret = true;
        struct smb2_request *req[2];
        uint32_t saved_tid = tree->tid;
-       uint64_t saved_uid = tree->session->uid;
+       uint64_t saved_uid = smb2cli_session_current_id(tree->session->smbXcli);
 
        smb2_transport_credits_ask_num(tree->session->transport, 2);
 
@@ -86,7 +87,7 @@ static bool test_compound_related1(struct torture_context *tctx,
        cl.in.file.handle = hd;
 
        tree->tid = 0xFFFFFFFF;
-       tree->session->uid = UINT64_MAX;
+       smb2cli_session_set_id_and_flags(tree->session->smbXcli, UINT64_MAX, 0);
 
        req[1] = smb2_close_send(tree, &cl);
 
@@ -96,7 +97,7 @@ static bool test_compound_related1(struct torture_context *tctx,
        CHECK_STATUS(status, NT_STATUS_OK);
 
        tree->tid = saved_tid;
-       tree->session->uid = saved_uid;
+       smb2cli_session_set_id_and_flags(tree->session->smbXcli, saved_uid, 0);
 
        smb2_util_unlink(tree, fname);
 done:
@@ -114,7 +115,7 @@ static bool test_compound_related2(struct torture_context *tctx,
        bool ret = true;
        struct smb2_request *req[5];
        uint32_t saved_tid = tree->tid;
-       uint64_t saved_uid = tree->session->uid;
+       uint64_t saved_uid = smb2cli_session_current_id(tree->session->smbXcli);
 
        smb2_transport_credits_ask_num(tree->session->transport, 5);
 
@@ -152,7 +153,7 @@ static bool test_compound_related2(struct torture_context *tctx,
        ZERO_STRUCT(cl);
        cl.in.file.handle = hd;
        tree->tid = 0xFFFFFFFF;
-       tree->session->uid = UINT64_MAX;
+       smb2cli_session_set_id_and_flags(tree->session->smbXcli, UINT64_MAX, 0);
 
        req[1] = smb2_close_send(tree, &cl);
        req[2] = smb2_close_send(tree, &cl);
@@ -171,7 +172,7 @@ static bool test_compound_related2(struct torture_context *tctx,
        CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER);
 
        tree->tid = saved_tid;
-       tree->session->uid = saved_uid;
+       smb2cli_session_set_id_and_flags(tree->session->smbXcli, saved_uid, 0);
 
        smb2_util_unlink(tree, fname);
 done:
@@ -314,7 +315,7 @@ static bool test_compound_invalid2(struct torture_context *tctx,
        bool ret = true;
        struct smb2_request *req[5];
        uint32_t saved_tid = tree->tid;
-       uint64_t saved_uid = tree->session->uid;
+       uint64_t saved_uid = smb2cli_session_current_id(tree->session->smbXcli);
 
        smb2_transport_credits_ask_num(tree->session->transport, 5);
 
@@ -352,7 +353,7 @@ static bool test_compound_invalid2(struct torture_context *tctx,
        ZERO_STRUCT(cl);
        cl.in.file.handle = hd;
        tree->tid = 0xFFFFFFFF;
-       tree->session->uid = UINT64_MAX;
+       smb2cli_session_set_id_and_flags(tree->session->smbXcli, UINT64_MAX, 0);
 
        req[1] = smb2_close_send(tree, &cl);
        /* strange that this is not generating invalid parameter */
@@ -374,7 +375,7 @@ static bool test_compound_invalid2(struct torture_context *tctx,
        CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER);
 
        tree->tid = saved_tid;
-       tree->session->uid = saved_uid;
+       smb2cli_session_set_id_and_flags(tree->session->smbXcli, saved_uid, 0);
 
        smb2_util_unlink(tree, fname);
 done: