libcli/smb: split out smb2cli_raw_tcon* from smb2cli_tcon*
authorStefan Metzmacher <metze@samba.org>
Thu, 16 Sep 2021 08:51:43 +0000 (10:51 +0200)
committerJule Anger <janger@samba.org>
Mon, 6 Dec 2021 10:42:09 +0000 (10:42 +0000)
This will be used in tests in order to separate the tcon from
validate_negotiate_info.

BUG: https://bugzilla.samba.org/show_bug.cgi?id=14788

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Ralph Boehme <slow@samba.org>
(cherry picked from commit 04a79139a42cfd1b607317dec041618cbf629584)

libcli/smb/smb2cli_tcon.c
libcli/smb/smbXcli_base.h

index 03fb604db5f378ceca411d7c1fc76a6c24bd4d04..d5e4fc30fba80d9227a62dda6d48e4004d905c8b 100644 (file)
 #include "../libcli/smb/smb_common.h"
 #include "../libcli/smb/smbXcli_base.h"
 
-struct smb2cli_tcon_state {
-       struct tevent_context *ev;
-       struct smbXcli_conn *conn;
-       uint32_t timeout_msec;
+struct smb2cli_raw_tcon_state {
        struct smbXcli_session *session;
        struct smbXcli_tcon *tcon;
        uint8_t fixed[8];
        uint8_t dyn_pad[1];
 };
 
-static void smb2cli_tcon_done(struct tevent_req *subreq);
-
-struct tevent_req *smb2cli_tcon_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,
-                                    uint16_t flags,
-                                    const char *unc)
+static void smb2cli_raw_tcon_done(struct tevent_req *subreq);
+
+struct tevent_req *smb2cli_raw_tcon_send(TALLOC_CTX *mem_ctx,
+                                        struct tevent_context *ev,
+                                        struct smbXcli_conn *conn,
+                                        uint32_t additional_flags,
+                                        uint32_t clear_flags,
+                                        uint32_t timeout_msec,
+                                        struct smbXcli_session *session,
+                                        struct smbXcli_tcon *tcon,
+                                        uint16_t tcon_flags,
+                                        const char *unc)
 {
-       struct tevent_req *req, *subreq;
-       struct smb2cli_tcon_state *state;
-       uint8_t *fixed;
-       uint8_t *dyn;
+       struct tevent_req *req = NULL;
+       struct smb2cli_raw_tcon_state *state = NULL;
+       struct tevent_req *subreq = NULL;
+       uint8_t *fixed = NULL;
+       uint8_t *dyn = NULL;
        size_t dyn_len;
-       uint32_t additional_flags = 0;
-       uint32_t clear_flags = 0;
 
-       req = tevent_req_create(mem_ctx, &state, struct smb2cli_tcon_state);
+       req = tevent_req_create(mem_ctx, &state,
+                               struct smb2cli_raw_tcon_state);
        if (req == NULL) {
                return NULL;
        }
-       state->ev = ev;
-       state->conn = conn;
-       state->timeout_msec = timeout_msec;
        state->session = session;
        state->tcon = tcon;
 
@@ -77,7 +73,7 @@ struct tevent_req *smb2cli_tcon_send(TALLOC_CTX *mem_ctx,
        fixed = state->fixed;
        SSVAL(fixed, 0, 9);
        if (smbXcli_conn_protocol(conn) >= PROTOCOL_SMB3_11) {
-               SSVAL(fixed, 2, flags);
+               SSVAL(fixed, 2, tcon_flags);
        } else {
                SSVAL(fixed, 2, 0); /* Reserved */
        }
@@ -89,10 +85,6 @@ struct tevent_req *smb2cli_tcon_send(TALLOC_CTX *mem_ctx,
                dyn_len = sizeof(state->dyn_pad);
        }
 
-       if (smbXcli_session_is_authenticated(state->session)) {
-               additional_flags |= SMB2_HDR_FLAG_SIGNED;
-       }
-
        subreq = smb2cli_req_send(state, ev, conn, SMB2_OP_TCON,
                                  additional_flags, clear_flags,
                                  timeout_msec,
@@ -104,19 +96,17 @@ struct tevent_req *smb2cli_tcon_send(TALLOC_CTX *mem_ctx,
        if (tevent_req_nomem(subreq, req)) {
                return tevent_req_post(req, ev);
        }
-       tevent_req_set_callback(subreq, smb2cli_tcon_done, req);
+       tevent_req_set_callback(subreq, smb2cli_raw_tcon_done, req);
 
        return req;
 }
 
-static void smb2cli_tcon_validate(struct tevent_req *subreq);
-
-static void smb2cli_tcon_done(struct tevent_req *subreq)
+static void smb2cli_raw_tcon_done(struct tevent_req *subreq)
 {
        struct tevent_req *req = tevent_req_callback_data(
                subreq, struct tevent_req);
-       struct smb2cli_tcon_state *state = tevent_req_data(
-               req, struct smb2cli_tcon_state);
+       struct smb2cli_raw_tcon_state *state = tevent_req_data(
+               req, struct smb2cli_raw_tcon_state);
        NTSTATUS status;
        struct iovec *iov;
        uint8_t *body;
@@ -156,6 +146,129 @@ static void smb2cli_tcon_done(struct tevent_req *subreq)
                                share_capabilities,
                                maximal_access);
 
+       tevent_req_done(req);
+}
+
+NTSTATUS smb2cli_raw_tcon_recv(struct tevent_req *req)
+{
+       return tevent_req_simple_recv_ntstatus(req);
+}
+
+NTSTATUS smb2cli_raw_tcon(struct smbXcli_conn *conn,
+                         uint32_t additional_flags,
+                         uint32_t clear_flags,
+                         uint32_t timeout_msec,
+                         struct smbXcli_session *session,
+                         struct smbXcli_tcon *tcon,
+                         uint16_t tcon_flags,
+                         const char *unc)
+{
+       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(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 = smb2cli_raw_tcon_send(frame, ev, conn,
+                                   additional_flags, clear_flags,
+                                   timeout_msec, session, tcon,
+                                   tcon_flags, unc);
+       if (req == NULL) {
+               goto fail;
+       }
+       if (!tevent_req_poll_ntstatus(req, ev, &status)) {
+               goto fail;
+       }
+       status = smb2cli_raw_tcon_recv(req);
+ fail:
+       TALLOC_FREE(frame);
+       return status;
+}
+
+struct smb2cli_tcon_state {
+       struct tevent_context *ev;
+       struct smbXcli_conn *conn;
+       uint32_t timeout_msec;
+       struct smbXcli_session *session;
+       struct smbXcli_tcon *tcon;
+       uint8_t fixed[8];
+       uint8_t dyn_pad[1];
+};
+
+static void smb2cli_tcon_done(struct tevent_req *subreq);
+
+struct tevent_req *smb2cli_tcon_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,
+                                    uint16_t flags,
+                                    const char *unc)
+{
+       struct tevent_req *req, *subreq;
+       struct smb2cli_tcon_state *state;
+       uint32_t additional_flags = 0;
+       uint32_t clear_flags = 0;
+
+       req = tevent_req_create(mem_ctx, &state, struct smb2cli_tcon_state);
+       if (req == NULL) {
+               return NULL;
+       }
+       state->ev = ev;
+       state->conn = conn;
+       state->timeout_msec = timeout_msec;
+       state->session = session;
+       state->tcon = tcon;
+
+       if (smbXcli_session_is_authenticated(state->session)) {
+               additional_flags |= SMB2_HDR_FLAG_SIGNED;
+       }
+
+       subreq = smb2cli_raw_tcon_send(state,
+                                      state->ev,
+                                      state->conn,
+                                      additional_flags,
+                                      clear_flags,
+                                      state->timeout_msec,
+                                      state->session,
+                                      state->tcon,
+                                      flags,
+                                      unc);
+       if (tevent_req_nomem(subreq, req)) {
+               return tevent_req_post(req, ev);
+       }
+       tevent_req_set_callback(subreq, smb2cli_tcon_done, req);
+
+       return req;
+}
+
+static void smb2cli_tcon_validate(struct tevent_req *subreq);
+
+static void smb2cli_tcon_done(struct tevent_req *subreq)
+{
+       struct tevent_req *req = tevent_req_callback_data(
+               subreq, struct tevent_req);
+       struct smb2cli_tcon_state *state = tevent_req_data(
+               req, struct smb2cli_tcon_state);
+       NTSTATUS status;
+
+       status = smb2cli_raw_tcon_recv(subreq);
+       TALLOC_FREE(subreq);
+       if (tevent_req_nterror(req, status)) {
+               return;
+       }
+
        if (!smbXcli_session_is_authenticated(state->session)) {
                tevent_req_done(req);
                return;
index 136e0e0111aa34c5d254d6193cbdd3dd00e33ec7..805a62ce34226a12f62e80f902973266755d1770 100644 (file)
@@ -593,6 +593,26 @@ NTSTATUS smb2cli_logoff(struct smbXcli_conn *conn,
                        uint32_t timeout_msec,
                        struct smbXcli_session *session);
 
+/* smb2cli_raw_tcon* should only be used in tests! */
+struct tevent_req *smb2cli_raw_tcon_send(TALLOC_CTX *mem_ctx,
+                                        struct tevent_context *ev,
+                                        struct smbXcli_conn *conn,
+                                        uint32_t additional_flags,
+                                        uint32_t clear_flags,
+                                        uint32_t timeout_msec,
+                                        struct smbXcli_session *session,
+                                        struct smbXcli_tcon *tcon,
+                                        uint16_t tcon_flags,
+                                        const char *unc);
+NTSTATUS smb2cli_raw_tcon_recv(struct tevent_req *req);
+NTSTATUS smb2cli_raw_tcon(struct smbXcli_conn *conn,
+                         uint32_t additional_flags,
+                         uint32_t clear_flags,
+                         uint32_t timeout_msec,
+                         struct smbXcli_session *session,
+                         struct smbXcli_tcon *tcon,
+                         uint16_t tcon_flags,
+                         const char *unc);
 struct tevent_req *smb2cli_tcon_send(TALLOC_CTX *mem_ctx,
                                     struct tevent_context *ev,
                                     struct smbXcli_conn *conn,