smbd: Move check for SMB2 compound request to new function
[samba.git] / source3 / smbd / globals.h
index d6ca15286dbc85ac53f7eee5a7e876f0c9242ad9..78f1260909d4ab7c4db0b4682b502c962796e04d 100644 (file)
 
 #include "system/select.h"
 #include "librpc/gen_ndr/smbXsrv.h"
-
-extern int aio_pending_size;
-extern int outstanding_aio_calls;
+#include "smbprofile.h"
 
 #ifdef USE_DMAPI
 struct smbd_dmapi_context;
 extern struct smbd_dmapi_context *dmapi_ctx;
 #endif
 
-extern bool dfree_broken;
-
 /* how many write cache buffers have been allocated */
 extern unsigned int allocated_write_caches;
 
@@ -111,20 +107,22 @@ extern bool exit_firsttime;
 struct tstream_context;
 struct smbd_smb2_request;
 
-DATA_BLOB negprot_spnego(TALLOC_CTX *ctx, struct smbd_server_connection *sconn);
+DATA_BLOB negprot_spnego(TALLOC_CTX *ctx, struct smbXsrv_connection *xconn);
 
-void smbd_lock_socket(struct smbd_server_connection *sconn);
-void smbd_unlock_socket(struct smbd_server_connection *sconn);
+void smbd_lock_socket(struct smbXsrv_connection *xconn);
+void smbd_unlock_socket(struct smbXsrv_connection *xconn);
 
 NTSTATUS smbd_do_locking(struct smb_request *req,
                         files_struct *fsp,
                         uint8_t type,
                         int32_t timeout,
-                        uint16_t num_ulocks,
-                        struct smbd_lock_element *ulocks,
                         uint16_t num_locks,
                         struct smbd_lock_element *locks,
                         bool *async);
+NTSTATUS smbd_do_unlocking(struct smb_request *req,
+                          files_struct *fsp,
+                          uint16_t num_ulocks,
+                          struct smbd_lock_element *ulocks);
 
 NTSTATUS smbd_do_qfilepathinfo(connection_struct *conn,
                               TALLOC_CTX *mem_ctx,
@@ -138,9 +136,17 @@ NTSTATUS smbd_do_qfilepathinfo(connection_struct *conn,
                               char *lock_data,
                               uint16_t flags2,
                               unsigned int max_data_bytes,
+                              size_t *fixed_portion,
                               char **ppdata,
                               unsigned int *pdata_size);
 
+NTSTATUS smbd_do_setfsinfo(connection_struct *conn,
+                               struct smb_request *req,
+                               TALLOC_CTX *mem_ctx,
+                               uint16_t info_level,
+                               files_struct *fsp,
+                               const DATA_BLOB *pdata);
+
 NTSTATUS smbd_do_setfilepathinfo(connection_struct *conn,
                                struct smb_request *req,
                                TALLOC_CTX *mem_ctx,
@@ -150,11 +156,13 @@ NTSTATUS smbd_do_setfilepathinfo(connection_struct *conn,
                                char **ppdata, int total_data,
                                int *ret_data_size);
 
-NTSTATUS smbd_do_qfsinfo(connection_struct *conn,
+NTSTATUS smbd_do_qfsinfo(struct smbXsrv_connection *xconn,
+                        connection_struct *conn,
                         TALLOC_CTX *mem_ctx,
                         uint16_t info_level,
                         uint16_t flags2,
                         unsigned int max_data_bytes,
+                        size_t *fixed_portion,
                         struct smb_filename *smb_fname,
                         char **ppdata,
                         int *ret_data_len);
@@ -180,12 +188,12 @@ bool smbd_dirptr_get_entry(TALLOC_CTX *ctx,
                           uint32_t *_mode,
                           long *_prev_offset);
 
-bool smbd_dirptr_lanman2_entry(TALLOC_CTX *ctx,
+NTSTATUS smbd_dirptr_lanman2_entry(TALLOC_CTX *ctx,
                               connection_struct *conn,
                               struct dptr_struct *dirptr,
-                              uint16 flags2,
+                              uint16_t flags2,
                               const char *path_mask,
-                              uint32 dirtype,
+                              uint32_t dirtype,
                               int info_level,
                               int requires_resume_key,
                               bool dont_descend,
@@ -196,10 +204,10 @@ bool smbd_dirptr_lanman2_entry(TALLOC_CTX *ctx,
                               char *base_data,
                               char *end_data,
                               int space_remaining,
-                              bool *out_of_space,
                               bool *got_exact_match,
                               int *_last_entry_off,
-                              struct ea_list *name_list);
+                              struct ea_list *name_list,
+                              struct file_id *file_id);
 
 NTSTATUS smbd_calculate_access_mask(connection_struct *conn,
                                    const struct smb_filename *smb_fname,
@@ -209,19 +217,26 @@ NTSTATUS smbd_calculate_access_mask(connection_struct *conn,
 
 void smbd_notify_cancel_by_smbreq(const struct smb_request *smbreq);
 
-void smbd_server_connection_terminate_ex(struct smbd_server_connection *sconn,
+void smbd_server_connection_terminate_ex(struct smbXsrv_connection *xconn,
                                         const char *reason,
                                         const char *location);
-#define smbd_server_connection_terminate(sconn, reason) \
-       smbd_server_connection_terminate_ex(sconn, reason, __location__)
+#define smbd_server_connection_terminate(xconn, reason) \
+       smbd_server_connection_terminate_ex(xconn, reason, __location__)
 
 const char *smb2_opcode_name(uint16_t opcode);
 bool smbd_is_smb2_header(const uint8_t *inbuf, size_t size);
+bool smbd_smb2_is_compound(const struct smbd_smb2_request *req);
+
+NTSTATUS smbd_add_connection(struct smbXsrv_client *client, int sock_fd,
+                            struct smbXsrv_connection **_xconn);
 
 void reply_smb2002(struct smb_request *req, uint16_t choice);
 void reply_smb20ff(struct smb_request *req, uint16_t choice);
-void smbd_smb2_first_negprot(struct smbd_server_connection *sconn,
-                            uint8_t *inbuf, size_t size);
+void smbd_smb2_process_negprot(struct smbXsrv_connection *xconn,
+                              uint64_t expected_seq_low,
+                              const uint8_t *inpdu, size_t size);
+
+DATA_BLOB smbd_smb2_generate_outbody(struct smbd_smb2_request *req, size_t size);
 
 NTSTATUS smbd_smb2_request_error_ex(struct smbd_smb2_request *req,
                                    NTSTATUS status,
@@ -236,11 +251,17 @@ NTSTATUS smbd_smb2_request_done_ex(struct smbd_smb2_request *req,
 #define smbd_smb2_request_done(req, body, dyn) \
        smbd_smb2_request_done_ex(req, NT_STATUS_OK, body, dyn, __location__)
 
-NTSTATUS smbd_smb2_send_oplock_break(struct smbd_server_connection *sconn,
+NTSTATUS smbd_smb2_send_oplock_break(struct smbXsrv_connection *xconn,
                                     struct smbXsrv_session *session,
                                     struct smbXsrv_tcon *tcon,
                                     struct smbXsrv_open *op,
                                     uint8_t oplock_level);
+NTSTATUS smbd_smb2_send_lease_break(struct smbXsrv_connection *xconn,
+                                   uint16_t new_epoch,
+                                   uint32_t lease_flags,
+                                   struct smb2_lease_key *lease_key,
+                                   uint32_t current_lease_state,
+                                   uint32_t new_lease_state);
 
 NTSTATUS smbd_smb2_request_pending_queue(struct smbd_smb2_request *req,
                                         struct tevent_req *subreq,
@@ -256,6 +277,12 @@ NTSTATUS smbd_smb2_request_verify_creditcharge(struct smbd_smb2_request *req,
 NTSTATUS smbd_smb2_request_verify_sizes(struct smbd_smb2_request *req,
                                        size_t expected_body_size);
 
+void smb2_request_set_async_internal(struct smbd_smb2_request *req,
+                                    bool async_internal);
+
+enum protocol_types smbd_smb2_protocol_dialect_match(const uint8_t *indyn,
+                                                    const int dialect_count,
+                                                    uint16_t *dialect);
 NTSTATUS smbd_smb2_request_process_negprot(struct smbd_smb2_request *req);
 NTSTATUS smbd_smb2_request_process_sesssetup(struct smbd_smb2_request *req);
 NTSTATUS smbd_smb2_request_process_logoff(struct smbd_smb2_request *req);
@@ -273,7 +300,7 @@ NTSTATUS smb2_write_complete_nosync(struct tevent_req *req, ssize_t nwritten,
 NTSTATUS smbd_smb2_request_process_lock(struct smbd_smb2_request *req);
 NTSTATUS smbd_smb2_request_process_ioctl(struct smbd_smb2_request *req);
 NTSTATUS smbd_smb2_request_process_keepalive(struct smbd_smb2_request *req);
-NTSTATUS smbd_smb2_request_process_find(struct smbd_smb2_request *req);
+NTSTATUS smbd_smb2_request_process_query_directory(struct smbd_smb2_request *req);
 NTSTATUS smbd_smb2_request_process_notify(struct smbd_smb2_request *req);
 NTSTATUS smbd_smb2_request_process_getinfo(struct smbd_smb2_request *req);
 NTSTATUS smbd_smb2_request_process_setinfo(struct smbd_smb2_request *req);
@@ -283,8 +310,12 @@ void smbd_smb2_request_dispatch_immediate(struct tevent_context *ctx,
                                struct tevent_immediate *im,
                                void *private_data);
 
+struct deferred_open_record;
+
 /* SMB1 -> SMB2 glue. */
-void send_break_message_smb2(files_struct *fsp, int level);
+void send_break_message_smb2(files_struct *fsp,
+                            uint32_t break_from,
+                            uint32_t break_to);
 struct blocking_lock_record *get_pending_smb2req_blr(struct smbd_smb2_request *smb2req);
 bool push_blocking_lock_request_smb2( struct byte_range_lock *br_lck,
                                struct smb_request *req,
@@ -306,22 +337,30 @@ void cancel_pending_lock_requests_by_fid_smb2(files_struct *fsp,
 int map_smb2_oplock_levels_to_samba(uint8_t in_oplock_level);
 bool get_deferred_open_message_state_smb2(struct smbd_smb2_request *smb2req,
                        struct timeval *p_request_time,
-                       void **pp_state);
-bool open_was_deferred_smb2(struct smbd_server_connection *sconn,
-                           uint64_t mid);
+                       struct deferred_open_record **open_rec);
+bool open_was_deferred_smb2(
+       struct smbXsrv_connection *xconn, uint64_t mid);
 void remove_deferred_open_message_smb2(
-       struct smbd_server_connection *sconn, uint64_t mid);
+       struct smbXsrv_connection *xconn, uint64_t mid);
 bool schedule_deferred_open_message_smb2(
-       struct smbd_server_connection *sconn, uint64_t mid);
+       struct smbXsrv_connection *xconn, uint64_t mid);
 bool push_deferred_open_message_smb2(struct smbd_smb2_request *smb2req,
-                       struct timeval request_time,
-                       struct timeval timeout,
-                       struct file_id id,
-                       char *private_data,
-                       size_t priv_len);
+                                struct timeval request_time,
+                                struct timeval timeout,
+                               struct file_id id,
+                               struct deferred_open_record *open_rec);
+
+struct smbXsrv_client;
+
+struct smbXsrv_preauth {
+       uint8_t sha512_value[64];
+};
 
 struct smbXsrv_connection {
-       struct smbd_server_connection *sconn;
+       struct smbXsrv_connection *prev, *next;
+
+       struct smbXsrv_client *client;
+
 
        const struct tsocket_address *local_address;
        const struct tsocket_address *remote_address;
@@ -333,9 +372,148 @@ struct smbXsrv_connection {
        enum protocol_types protocol;
 
        struct {
+               NTSTATUS status;
+               int sock;
+               struct tevent_fd *fde;
+
+               struct {
+                       bool got_session;
+               } nbt;
+       } transport;
+
+       struct {
+               struct {
+                       /*
+                        * fd for the fcntl lock and process shared
+                        * robust mutex to coordinate access to the
+                        * client socket. When the system supports
+                        * process shared robust mutexes, those are
+                        * used. If not, then the fcntl lock will be
+                        * used.
+                        */
+                       int socket_lock_fd;
+#ifdef HAVE_ROBUST_MUTEXES
+                       pthread_mutex_t *socket_mutex;
+#endif
+
+                       /*
+                        * fd for the trusted pipe from
+                        * echo handler child
+                        */
+                       int trusted_fd;
+
+                       /*
+                        * fde for the trusted_fd
+                        */
+                       struct tevent_fd *trusted_fde;
+
+                       /*
+                        * Reference count for the fcntl lock to
+                        * allow recursive locks.
+                        */
+                       int ref_count;
+               } echo_handler;
+
+               struct {
+                       bool encrypted_passwords;
+                       bool spnego;
+                       struct auth4_context *auth_context;
+                       bool done;
+                       /*
+                        * Size of the data we can receive. Set by us.
+                        * Can be modified by the max xmit parameter.
+                        */
+                       int max_recv;
+               } negprot;
+
+               struct {
+                       bool done_sesssetup;
+                       /*
+                        * Size of data we can send to client. Set
+                        *  by the client for all protocols above CORE.
+                        *  Set by us for CORE protocol.
+                        */
+                       int max_send;
+               } sessions;
+               struct smb_signing_state *signing_state;
+
+               struct {
+                       uint16_t client_major;
+                       uint16_t client_minor;
+                       uint32_t client_cap_low;
+                       uint32_t client_cap_high;
+               } unix_info;
+
+               struct msg_state *msg_state;
+       } smb1;
+       struct {
+               struct smbd_smb2_request_read_state {
+                       struct smbd_smb2_request *req;
+                       struct {
+                               uint8_t nbt[NBT_HDR_SIZE];
+                               bool done;
+                       } hdr;
+                       struct iovec vector;
+                       bool doing_receivefile;
+                       size_t min_recv_size;
+                       size_t pktfull;
+                       size_t pktlen;
+                       uint8_t *pktbuf;
+               } request_read_state;
+               struct smbd_smb2_send_queue *send_queue;
+               size_t send_queue_len;
+
+               struct {
+                       /*
+                        * seq_low is the lowest sequence number
+                        * we will accept.
+                        */
+                       uint64_t seq_low;
+                       /*
+                        * seq_range is the range of credits we have
+                        * granted from the sequence windows starting
+                        * at seq_low.
+                        *
+                        * This gets incremented when new credits are
+                        * granted and gets decremented when the
+                        * lowest sequence number is consumed
+                        * (when seq_low gets incremented).
+                        */
+                       uint16_t seq_range;
+                       /*
+                        * The number of credits we have currently granted
+                        * to the client.
+                        *
+                        * This gets incremented when new credits are
+                        * granted and gets decremented when any credit
+                        * is comsumed.
+                        *
+                        * Note: the decrementing is different compared
+                        *       to seq_range.
+                        */
+                       uint16_t granted;
+                       /*
+                        * The maximum number of credits we will ever
+                        * grant to the client.
+                        *
+                        * Typically we will only grant 1/16th of
+                        * max_credits.
+                        *
+                        * This is the "server max credits" parameter.
+                        */
+                       uint16_t max;
+                       /*
+                        * a bitmap of size max_credits
+                        */
+                       struct bitmap *bitmap;
+                       bool multicredit;
+               } credits;
+
+               bool allow_2ff;
                struct {
                        uint32_t capabilities;
                        struct GUID guid;
+                       bool guid_verified;
                        uint16_t security_mode;
                        uint16_t num_dialects;
                        uint16_t *dialects;
@@ -348,46 +526,66 @@ struct smbXsrv_connection {
                        uint32_t max_trans;
                        uint32_t max_read;
                        uint32_t max_write;
+                       uint16_t cipher;
                } server;
-       } smb2;
 
-       struct msg_state *msg_state;
-
-       /*
-        * Link into libasys for asynchronous operations
-        */
-       struct asys_context *asys_ctx;
-       struct tevent_fd *asys_fde;
+               struct smbXsrv_preauth preauth;
 
-       uint64_t smbd_idle_profstamp;
-
-       /*
-        * this session_table is used for SMB1 and SMB2,
-        */
-       struct smbXsrv_session_table *session_table;
-       /*
-        * this tcon_table is only used for SMB1.
-        */
-       struct smbXsrv_tcon_table *tcon_table;
-       /*
-        * this open_table is used for SMB1 and SMB2,
-        * because we have a global sconn->real_max_open_files
-        * limit.
-        */
-       struct smbXsrv_open_table *open_table;
+               struct smbd_smb2_request *requests;
+       } smb2;
 };
 
+const char *smbXsrv_connection_dbg(const struct smbXsrv_connection *xconn);
+
 NTSTATUS smbXsrv_version_global_init(const struct server_id *server_id);
 uint32_t smbXsrv_version_global_current(void);
 
+struct smbXsrv_client_table;
+NTSTATUS smbXsrv_client_global_init(void);
+NTSTATUS smbXsrv_client_create(TALLOC_CTX *mem_ctx,
+                              struct tevent_context *ev_ctx,
+                              struct messaging_context *msg_ctx,
+                              NTTIME now,
+                              struct smbXsrv_client **_client);
+NTSTATUS smbXsrv_client_update(struct smbXsrv_client *client);
+NTSTATUS smbXsrv_client_remove(struct smbXsrv_client *client);
+NTSTATUS smb2srv_client_lookup_global(struct smbXsrv_client *client,
+                                     struct GUID client_guid,
+                                     TALLOC_CTX *mem_ctx,
+                                     struct smbXsrv_client_global0 **_pass);
+NTSTATUS smb2srv_client_connection_pass(struct smbd_smb2_request *smb2req,
+                                       struct smbXsrv_client_global0 *global);
+
 NTSTATUS smbXsrv_connection_init_tables(struct smbXsrv_connection *conn,
                                        enum protocol_types protocol);
 
-NTSTATUS smbXsrv_session_global_init(void);
+NTSTATUS smbXsrv_session_global_init(struct messaging_context *msg_ctx);
 NTSTATUS smbXsrv_session_create(struct smbXsrv_connection *conn,
                                NTTIME now,
                                struct smbXsrv_session **_session);
+NTSTATUS smbXsrv_session_add_channel(struct smbXsrv_session *session,
+                                    struct smbXsrv_connection *conn,
+                                    struct smbXsrv_channel_global0 **_c);
 NTSTATUS smbXsrv_session_update(struct smbXsrv_session *session);
+struct smbXsrv_channel_global0;
+NTSTATUS smbXsrv_session_find_channel(const struct smbXsrv_session *session,
+                                     const struct smbXsrv_connection *conn,
+                                     struct smbXsrv_channel_global0 **_c);
+NTSTATUS smbXsrv_session_find_auth(const struct smbXsrv_session *session,
+                                  const struct smbXsrv_connection *conn,
+                                  NTTIME now,
+                                  struct smbXsrv_session_auth0 **_a);
+NTSTATUS smbXsrv_session_create_auth(struct smbXsrv_session *session,
+                                    struct smbXsrv_connection *conn,
+                                    NTTIME now,
+                                    uint8_t in_flags,
+                                    uint8_t in_security_mode,
+                                    struct smbXsrv_session_auth0 **_a);
+struct tevent_req *smb2srv_session_shutdown_send(TALLOC_CTX *mem_ctx,
+                                       struct tevent_context *ev,
+                                       struct smbXsrv_session *session,
+                                       struct smbd_smb2_request *current_req);
+NTSTATUS smb2srv_session_shutdown_recv(struct tevent_req *req);
 NTSTATUS smbXsrv_session_logoff(struct smbXsrv_session *session);
 NTSTATUS smbXsrv_session_logoff_all(struct smbXsrv_connection *conn);
 NTSTATUS smb1srv_session_table_init(struct smbXsrv_connection *conn);
@@ -395,9 +593,12 @@ NTSTATUS smb1srv_session_lookup(struct smbXsrv_connection *conn,
                                uint16_t vuid, NTTIME now,
                                struct smbXsrv_session **session);
 NTSTATUS smb2srv_session_table_init(struct smbXsrv_connection *conn);
-NTSTATUS smb2srv_session_lookup(struct smbXsrv_connection *conn,
-                               uint64_t session_id, NTTIME now,
-                               struct smbXsrv_session **session);
+NTSTATUS smb2srv_session_lookup_conn(struct smbXsrv_connection *conn,
+                                    uint64_t session_id, NTTIME now,
+                                    struct smbXsrv_session **session);
+NTSTATUS smb2srv_session_lookup_client(struct smbXsrv_client *client,
+                                      uint64_t session_id, NTTIME now,
+                                      struct smbXsrv_session **session);
 struct smbXsrv_session_global0;
 NTSTATUS smbXsrv_session_global_traverse(
                        int (*fn)(struct smbXsrv_session_global0 *, void *),
@@ -452,10 +653,14 @@ NTSTATUS smb2srv_open_lookup(struct smbXsrv_connection *conn,
                             uint64_t volatile_id,
                             NTTIME now,
                             struct smbXsrv_open **_open);
+NTSTATUS smb2srv_open_lookup_replay_cache(struct smbXsrv_connection *conn,
+                                         const struct GUID *create_guid,
+                                         NTTIME now,
+                                         struct smbXsrv_open **_open);
 NTSTATUS smb2srv_open_recreate(struct smbXsrv_connection *conn,
                               struct auth_session_info *session_info,
                               uint64_t persistent_id,
-                              struct GUID create_guid,
+                              const struct GUID *create_guid,
                               NTTIME now,
                               struct smbXsrv_open **_open);
 struct smbXsrv_open_global0;
@@ -464,12 +669,30 @@ NTSTATUS smbXsrv_open_global_traverse(
        void *private_data);
 
 NTSTATUS smbXsrv_open_cleanup(uint64_t persistent_id);
+bool smbXsrv_is_encrypted(uint8_t encryption_flags);
+bool smbXsrv_is_partially_encrypted(uint8_t encryption_flags);
+bool smbXsrv_set_crypto_flag(uint8_t *flags, uint8_t flag);
+bool smbXsrv_is_signed(uint8_t signing_flags);
+bool smbXsrv_is_partially_signed(uint8_t signing_flags);
+
+struct smbd_smb2_send_queue {
+       struct smbd_smb2_send_queue *prev, *next;
 
+       DATA_BLOB *sendfile_header;
+       NTSTATUS *sendfile_status;
+       struct iovec *vector;
+       int count;
+
+       TALLOC_CTX *mem_ctx;
+};
 
 struct smbd_smb2_request {
        struct smbd_smb2_request *prev, *next;
 
        struct smbd_server_connection *sconn;
+       struct smbXsrv_connection *xconn;
+
+       struct smbd_smb2_send_queue queue_entry;
 
        /* the session the request operates on, maybe NULL */
        struct smbXsrv_session *session;
@@ -481,10 +704,20 @@ struct smbd_smb2_request {
 
        int current_idx;
        bool do_signing;
+       /* Was the request encrypted? */
+       bool was_encrypted;
+       /* Should we encrypt? */
        bool do_encryption;
        struct tevent_timer *async_te;
        bool compound_related;
 
+       /*
+        * Give the implementation of an SMB2 req a way to tell the SMB2 request
+        * processing engine that the internal request is going async, while
+        * preserving synchronous SMB2 behaviour.
+        */
+       bool async_internal;
+
        /*
         * the encryption key for the whole
         * compound chain
@@ -495,13 +728,23 @@ struct smbd_smb2_request {
         * request/response of a compound chain
         */
        DATA_BLOB last_key;
+       struct smbXsrv_preauth *preauth;
 
        struct timeval request_time;
 
+       SMBPROFILE_IOBYTES_ASYNC_STATE(profile);
+
        /* fake smb1 request. */
        struct smb_request *smb1req;
        struct files_struct *compat_chain_fsp;
 
+       /*
+        * Keep track of whether the outstanding request counters
+        * had been updated in dispatch, so that they need to be
+        * adapted again in reply.
+        */
+       bool request_counters_updated;
+
        /*
         * The sub request for async backend calls.
         * This is used for SMB2 Cancel.
@@ -549,6 +792,8 @@ struct smbd_smb2_request {
 #define SMBD_SMB2_OUT_DYN_PTR(req)   (uint8_t *)(SMBD_SMB2_OUT_DYN_IOV(req)->iov_base)
 #define SMBD_SMB2_OUT_DYN_LEN(req)   (SMBD_SMB2_OUT_DYN_IOV(req)->iov_len)
 
+#define SMBD_SMB2_SHORT_RECEIVEFILE_WRITE_LEN (SMB2_HDR_BODY + 0x30)
+
        struct {
                /*
                 * vector[0] TRANSPORT HEADER (empty)
@@ -570,6 +815,7 @@ struct smbd_smb2_request {
                 */
                struct iovec *vector;
                int vector_count;
+               struct iovec _vector[1 + SMBD_SMB2_NUM_IOV_PER_REQ];
        } in;
        struct {
                /* the NBT header is not allocated */
@@ -594,6 +840,10 @@ struct smbd_smb2_request {
                 */
                struct iovec *vector;
                int vector_count;
+               struct iovec _vector[1 + SMBD_SMB2_NUM_IOV_PER_REQ];
+#define OUTVEC_ALLOC_SIZE (SMB2_HDR_BODY + 9)
+               uint8_t _hdr[OUTVEC_ALLOC_SIZE];
+               uint8_t _body[0x58];
        } out;
 };
 
@@ -616,19 +866,17 @@ struct user_struct {
        struct smbXsrv_session *session;
 };
 
+struct pthreadpool_tevent;
+
 struct smbd_server_connection {
-       int sock;
        const struct tsocket_address *local_address;
        const struct tsocket_address *remote_address;
        const char *remote_hostname;
        struct tevent_context *ev_ctx;
        struct messaging_context *msg_ctx;
-       struct sys_notify_context *sys_notify_ctx;
        struct notify_context *notify_ctx;
-       struct {
-               bool got_session;
-       } nbt;
        bool using_smb2;
+       bool aapl_zero_file_id; /* Apple-specific */
        int trans_num;
 
        size_t num_users;
@@ -663,63 +911,6 @@ struct smbd_server_connection {
        } oplocks;
 
        struct {
-               struct tevent_fd *fde;
-
-               struct {
-                       /*
-                        * fd for the fcntl lock mutexing access to our sock
-                        */
-                       int socket_lock_fd;
-
-                       /*
-                        * fd for the trusted pipe from
-                        * echo handler child
-                        */
-                       int trusted_fd;
-
-                       /*
-                        * fde for the trusted_fd
-                        */
-                       struct tevent_fd *trusted_fde;
-
-                       /*
-                        * Reference count for the fcntl lock to
-                        * allow recursive locks.
-                        */
-                       int ref_count;
-               } echo_handler;
-
-               struct {
-                       bool encrypted_passwords;
-                       bool spnego;
-                       struct auth4_context *auth_context;
-                       bool done;
-                       /*
-                        * Size of the data we can receive. Set by us.
-                        * Can be modified by the max xmit parameter.
-                        */
-                       int max_recv;
-               } negprot;
-
-               struct {
-                       uint16_t client_major;
-                       uint16_t client_minor;
-                       uint32_t client_cap_low;
-                       uint32_t client_cap_high;
-               } unix_info;
-
-               struct {
-                       bool done_sesssetup;
-                       /*
-                        * Size of data we can send to client. Set
-                        *  by the client for all protocols above CORE.
-                        *  Set by us for CORE protocol.
-                        */
-                       int max_send;
-                       uint64_t last_session_tag;
-               } sessions;
-               struct smb_signing_state *signing_state;
-
                struct notify_mid_map *notify_mid_maps;
 
                struct {
@@ -736,68 +927,18 @@ struct smbd_server_connection {
                } locks;
        } smb1;
        struct {
-               struct tevent_queue *recv_queue;
-               struct tevent_queue *send_queue;
-               struct tstream_context *stream;
-               bool negprot_2ff;
                struct {
                        /* The event that makes us process our blocking lock queue */
                        struct tevent_timer *brl_timeout;
                        bool blocking_lock_unlock_state;
                } locks;
-               struct smbd_smb2_request *requests;
-               /*
-                * seqnum_low is the lowest sequence number
-                * we will accept.
-                */
-               uint64_t seqnum_low;
-               /*
-                * seqnum_range is the range of credits we have
-                * granted from the sequence windows starting
-                * at seqnum_low.
-                *
-                * This gets incremented when new credits are
-                * granted and gets decremented when the
-                * lowest sequence number is consumed
-                * (when seqnum_low gets incremented).
-                */
-               uint16_t seqnum_range;
-               /*
-                * credits_grantedThe number of credits we have currently granted
-                * to the client.
-                *
-                * This gets incremented when new credits are
-                * granted and gets decremented when any credit
-                * is comsumed.
-                *
-                * Note: the decrementing is different compared
-                *       to seqnum_range.
-                */
-               uint16_t credits_granted;
-               /*
-                * The maximum number of credits we will ever
-                * grant to the client.
-                *
-                * Typically we will only grant 1/16th of
-                * max_credits.
-                *
-                * This is the "server max credits" parameter.
-                */
-               uint16_t max_credits;
-               /*
-                * a bitmap of size max_credits
-                */
-               struct bitmap *credits_bitmap;
-               bool supports_multicredit;
-               uint32_t max_trans;
-               uint32_t max_read;
-               uint32_t max_write;
-               bool compound_related_in_progress;
        } smb2;
 
-       struct smbXsrv_connection *conn;
+       struct pthreadpool_tevent *pool;
+
+       struct smbXsrv_client *client;
 };
 
-extern struct smbXsrv_connection *global_smbXsrv_connection;
+extern struct smbXsrv_client *global_smbXsrv_client;
 
 void smbd_init_globals(void);