Fix bug #6551 - win98 clients cannot connect after server upgrade to samba-3.4.0.
[ira/wip.git] / source3 / smbd / sesssetup.c
index 73948eca32be04cd84e5cb1b2be7a26b6e869792..2d2e5141eeb3194db2c02a53d85ecd8f5e5659f4 100644 (file)
 */
 
 #include "includes.h"
+#include "smbd/globals.h"
 
-extern struct auth_context *negprot_global_auth_context;
-extern bool global_encrypted_passwords_negotiated;
-extern bool global_spnego_negotiated;
 extern enum protocol_types Protocol;
-extern int max_send;
 
-uint32 global_client_caps = 0;
+/* For split krb5 SPNEGO blobs. */
+struct pending_auth_data {
+       struct pending_auth_data *prev, *next;
+       uint16 vuid; /* Tag for this entry. */
+       uint16 smbpid; /* Alternate tag for this entry. */
+       size_t needed_len;
+       DATA_BLOB partial_data;
+};
 
 /*
   on a logon error possibly map the error to success if "map to guest"
@@ -76,7 +80,7 @@ static int push_signature(uint8 **outbuf)
        if (tmp == -1) return -1;
        result += tmp;
 
-       if (asprintf(&lanman, "Samba %s", SAMBA_VERSION_STRING) != -1) {
+       if (asprintf(&lanman, "Samba %s", samba_version_string()) != -1) {
                tmp = message_push_string(outbuf, lanman, STR_TERMINATE);
                SAFE_FREE(lanman);
        }
@@ -95,25 +99,6 @@ static int push_signature(uint8 **outbuf)
        return result;
 }
 
-/****************************************************************************
- Start the signing engine if needed. Don't fail signing here.
-****************************************************************************/
-
-static void sessionsetup_start_signing_engine(
-                       const auth_serversupplied_info *server_info,
-                       const uint8 *inbuf)
-{
-       if (!server_info->guest && !srv_signing_started()) {
-               /* We need to start the signing engine
-                * here but a W2K client sends the old
-                * "BSRSPYL " signature instead of the
-                * correct one. Subsequent packets will
-                * be correct.
-                */
-               srv_check_sign_mac((char *)inbuf, False);
-       }
-}
-
 /****************************************************************************
  Send a security blob via a session setup reply.
 ****************************************************************************/
@@ -267,6 +252,7 @@ static void reply_spnego_kerberos(struct smb_request *req,
        bool map_domainuser_to_guest = False;
        bool username_was_mapped;
        struct PAC_LOGON_INFO *logon_info = NULL;
+       struct smbd_server_connection *sconn = smbd_server_conn;
 
        ZERO_STRUCT(ticket);
        ZERO_STRUCT(ap_rep);
@@ -357,7 +343,6 @@ static void reply_spnego_kerberos(struct smb_request *req,
                DEBUG(3,("Doesn't look like a valid principal\n"));
                data_blob_free(&ap_rep);
                data_blob_free(&session_key);
-               SAFE_FREE(client);
                talloc_destroy(mem_ctx);
                reply_nterror(req,nt_status_squash(NT_STATUS_LOGON_FAILURE));
                return;
@@ -379,7 +364,6 @@ static void reply_spnego_kerberos(struct smb_request *req,
                if (!lp_allow_trusted_domains()) {
                        data_blob_free(&ap_rep);
                        data_blob_free(&session_key);
-                       SAFE_FREE(client);
                        talloc_destroy(mem_ctx);
                        reply_nterror(req, nt_status_squash(
                                              NT_STATUS_LOGON_FAILURE));
@@ -432,7 +416,7 @@ static void reply_spnego_kerberos(struct smb_request *req,
 
        /* lookup the passwd struct, create a new user if necessary */
 
-       username_was_mapped = map_username( user );
+       username_was_mapped = map_username(sconn, user);
 
        pw = smb_getpwnam( mem_ctx, user, real_username, True );
 
@@ -469,7 +453,6 @@ static void reply_spnego_kerberos(struct smb_request *req,
                if ( !pw ) {
                        DEBUG(1,("Username %s is invalid on this system\n",
                                user));
-                       SAFE_FREE(client);
                        data_blob_free(&ap_rep);
                        data_blob_free(&session_key);
                        TALLOC_FREE(mem_ctx);
@@ -495,7 +478,6 @@ static void reply_spnego_kerberos(struct smb_request *req,
                if ( !NT_STATUS_IS_OK(ret) ) {
                        DEBUG(1,("make_server_info_info3 failed: %s!\n",
                                 nt_errstr(ret)));
-                       SAFE_FREE(client);
                        data_blob_free(&ap_rep);
                        data_blob_free(&session_key);
                        TALLOC_FREE(mem_ctx);
@@ -509,7 +491,6 @@ static void reply_spnego_kerberos(struct smb_request *req,
                if ( !NT_STATUS_IS_OK(ret) ) {
                        DEBUG(1,("make_server_info_pw failed: %s!\n",
                                 nt_errstr(ret)));
-                       SAFE_FREE(client);
                        data_blob_free(&ap_rep);
                        data_blob_free(&session_key);
                        TALLOC_FREE(mem_ctx);
@@ -537,7 +518,6 @@ static void reply_spnego_kerberos(struct smb_request *req,
                if ( !NT_STATUS_IS_OK(ret) ) {
                        DEBUG(10,("failed to create local token: %s\n",
                                nt_errstr(ret)));
-                       SAFE_FREE(client);
                        data_blob_free(&ap_rep);
                        data_blob_free(&session_key);
                        TALLOC_FREE( mem_ctx );
@@ -547,8 +527,8 @@ static void reply_spnego_kerberos(struct smb_request *req,
                }
        }
 
-       if (!is_partial_auth_vuid(sess_vuid)) {
-               sess_vuid = register_initial_vuid();
+       if (!is_partial_auth_vuid(sconn, sess_vuid)) {
+               sess_vuid = register_initial_vuid(sconn);
        }
 
        data_blob_free(&server_info->user_session_key);
@@ -560,13 +540,12 @@ static void reply_spnego_kerberos(struct smb_request *req,
         * no need to free after this on success. A better interface would copy
         * it.... */
 
-       sess_vuid = register_existing_vuid(sess_vuid,
+       sess_vuid = register_existing_vuid(sconn,
+                                       sess_vuid,
                                        server_info,
                                        nullblob,
                                        client);
 
-       SAFE_FREE(client);
-
        reply_outbuf(req, 4, 0);
        SSVAL(req->outbuf,smb_uid,sess_vuid);
 
@@ -584,7 +563,6 @@ static void reply_spnego_kerberos(struct smb_request *req,
 
                SSVAL(req->outbuf, smb_uid, sess_vuid);
 
-               sessionsetup_start_signing_engine(server_info, req->inbuf);
                /* Successful logon. Keep this vuid. */
                *p_invalidate_vuid = False;
        }
@@ -625,6 +603,7 @@ static void reply_spnego_ntlmssp(struct smb_request *req,
 {
        DATA_BLOB response;
        struct auth_serversupplied_info *server_info = NULL;
+       struct smbd_server_connection *sconn = smbd_server_conn;
 
        if (NT_STATUS_IS_OK(nt_status)) {
                server_info = (*auth_ntlmssp_state)->server_info;
@@ -642,7 +621,7 @@ static void reply_spnego_ntlmssp(struct smb_request *req,
        if (NT_STATUS_IS_OK(nt_status)) {
                DATA_BLOB nullblob = data_blob_null;
 
-               if (!is_partial_auth_vuid(vuid)) {
+               if (!is_partial_auth_vuid(sconn, vuid)) {
                        nt_status = NT_STATUS_LOGON_FAILURE;
                        goto out;
                }
@@ -655,7 +634,7 @@ static void reply_spnego_ntlmssp(struct smb_request *req,
                        (*auth_ntlmssp_state)->ntlmssp_state->session_key.length);
 
                /* register_existing_vuid keeps the server info */
-               if (register_existing_vuid(vuid,
+               if (register_existing_vuid(sconn, vuid,
                                server_info, nullblob,
                                (*auth_ntlmssp_state)->ntlmssp_state->user) !=
                                        vuid) {
@@ -673,9 +652,6 @@ static void reply_spnego_ntlmssp(struct smb_request *req,
                if (server_info->guest) {
                        SSVAL(req->outbuf,smb_vwv2,1);
                }
-
-               sessionsetup_start_signing_engine(server_info,
-                                                 (uint8 *)req->inbuf);
        }
 
   out:
@@ -700,7 +676,7 @@ static void reply_spnego_ntlmssp(struct smb_request *req,
                auth_ntlmssp_end(auth_ntlmssp_state);
                if (!NT_STATUS_IS_OK(nt_status)) {
                        /* Kill the intermediate vuid */
-                       invalidate_vuid(vuid);
+                       invalidate_vuid(sconn, vuid);
                }
        }
 }
@@ -786,11 +762,12 @@ static void reply_spnego_negotiate(struct smb_request *req,
        DATA_BLOB chal;
        char *kerb_mech = NULL;
        NTSTATUS status;
+       struct smbd_server_connection *sconn = smbd_server_conn;
 
        status = parse_spnego_mechanisms(blob1, &secblob, &kerb_mech);
        if (!NT_STATUS_IS_OK(status)) {
                /* Kill the intermediate vuid */
-               invalidate_vuid(vuid);
+               invalidate_vuid(sconn, vuid);
                reply_nterror(req, nt_status_squash(status));
                return;
        }
@@ -800,14 +777,14 @@ static void reply_spnego_negotiate(struct smb_request *req,
 
 #ifdef HAVE_KRB5
        if (kerb_mech && ((lp_security()==SEC_ADS) ||
-                               lp_use_kerberos_keytab()) ) {
+                               USE_KERBEROS_KEYTAB) ) {
                bool destroy_vuid = True;
                reply_spnego_kerberos(req, &secblob, kerb_mech,
                                      vuid, &destroy_vuid);
                data_blob_free(&secblob);
                if (destroy_vuid) {
                        /* Kill the intermediate vuid */
-                       invalidate_vuid(vuid);
+                       invalidate_vuid(sconn, vuid);
                }
                SAFE_FREE(kerb_mech);
                return;
@@ -830,7 +807,7 @@ static void reply_spnego_negotiate(struct smb_request *req,
        status = auth_ntlmssp_start(auth_ntlmssp_state);
        if (!NT_STATUS_IS_OK(status)) {
                /* Kill the intermediate vuid */
-               invalidate_vuid(vuid);
+               invalidate_vuid(sconn, vuid);
                reply_nterror(req, nt_status_squash(status));
                return;
        }
@@ -862,13 +839,14 @@ static void reply_spnego_auth(struct smb_request *req,
        DATA_BLOB auth_reply = data_blob_null;
        DATA_BLOB secblob = data_blob_null;
        NTSTATUS status = NT_STATUS_LOGON_FAILURE;
+       struct smbd_server_connection *sconn = smbd_server_conn;
 
        if (!spnego_parse_auth(blob1, &auth)) {
 #if 0
                file_save("auth.dat", blob1.data, blob1.length);
 #endif
                /* Kill the intermediate vuid */
-               invalidate_vuid(vuid);
+               invalidate_vuid(sconn, vuid);
 
                reply_nterror(req, nt_status_squash(
                                      NT_STATUS_LOGON_FAILURE));
@@ -883,7 +861,7 @@ static void reply_spnego_auth(struct smb_request *req,
 
                if (!NT_STATUS_IS_OK(status)) {
                        /* Kill the intermediate vuid */
-                       invalidate_vuid(vuid);
+                       invalidate_vuid(sconn, vuid);
                        reply_nterror(req, nt_status_squash(status));
                        return;
                }
@@ -892,7 +870,7 @@ static void reply_spnego_auth(struct smb_request *req,
                                (unsigned long)secblob.length));
 #ifdef HAVE_KRB5
                if (kerb_mech && ((lp_security()==SEC_ADS) ||
-                                       lp_use_kerberos_keytab()) ) {
+                                       USE_KERBEROS_KEYTAB)) {
                        bool destroy_vuid = True;
                        reply_spnego_kerberos(req, &secblob, kerb_mech,
                                              vuid, &destroy_vuid);
@@ -900,7 +878,7 @@ static void reply_spnego_auth(struct smb_request *req,
                        data_blob_free(&auth);
                        if (destroy_vuid) {
                                /* Kill the intermediate vuid */
-                               invalidate_vuid(vuid);
+                               invalidate_vuid(sconn, vuid);
                        }
                        SAFE_FREE(kerb_mech);
                        return;
@@ -911,7 +889,7 @@ static void reply_spnego_auth(struct smb_request *req,
 
                if (kerb_mech) {
                        /* Kill the intermediate vuid */
-                       invalidate_vuid(vuid);
+                       invalidate_vuid(sconn, vuid);
                        DEBUG(3,("reply_spnego_auth: network "
                                "misconfiguration, client sent us a "
                                "krb5 ticket and kerberos security "
@@ -929,7 +907,7 @@ static void reply_spnego_auth(struct smb_request *req,
                status = auth_ntlmssp_start(auth_ntlmssp_state);
                if (!NT_STATUS_IS_OK(status)) {
                        /* Kill the intermediate vuid */
-                       invalidate_vuid(vuid);
+                       invalidate_vuid(sconn, vuid);
                        reply_nterror(req, nt_status_squash(status));
                        return;
                }
@@ -952,22 +930,17 @@ static void reply_spnego_auth(struct smb_request *req,
        return;
 }
 
-/****************************************************************************
- List to store partial SPNEGO auth fragments.
-****************************************************************************/
-
-static struct pending_auth_data *pd_list;
-
 /****************************************************************************
  Delete an entry on the list.
 ****************************************************************************/
 
-static void delete_partial_auth(struct pending_auth_data *pad)
+static void delete_partial_auth(struct smbd_server_connection *sconn,
+                               struct pending_auth_data *pad)
 {
        if (!pad) {
                return;
        }
-       DLIST_REMOVE(pd_list, pad);
+       DLIST_REMOVE(sconn->smb1.pd_list, pad);
        data_blob_free(&pad->partial_data);
        SAFE_FREE(pad);
 }
@@ -976,11 +949,17 @@ static void delete_partial_auth(struct pending_auth_data *pad)
  Search for a partial SPNEGO auth fragment matching an smbpid.
 ****************************************************************************/
 
-static struct pending_auth_data *get_pending_auth_data(uint16 smbpid)
+static struct pending_auth_data *get_pending_auth_data(
+               struct smbd_server_connection *sconn,
+               uint16_t smbpid)
 {
        struct pending_auth_data *pad;
-
-       for (pad = pd_list; pad; pad = pad->next) {
+/*
+ * NOTE: using the smbpid here is completely wrong...
+ *       see [MS-SMB]
+ *       3.3.5.3 Receiving an SMB_COM_SESSION_SETUP_ANDX Request
+ */
+       for (pad = sconn->smb1.pd_list; pad; pad = pad->next) {
                if (pad->smbpid == smbpid) {
                        break;
                }
@@ -994,20 +973,21 @@ static struct pending_auth_data *get_pending_auth_data(uint16 smbpid)
  the blob to be more than 64k.
 ****************************************************************************/
 
-static NTSTATUS check_spnego_blob_complete(uint16 smbpid, uint16 vuid,
-               DATA_BLOB *pblob)
+static NTSTATUS check_spnego_blob_complete(struct smbd_server_connection *sconn,
+                                          uint16 smbpid, uint16 vuid,
+                                          DATA_BLOB *pblob)
 {
        struct pending_auth_data *pad = NULL;
        ASN1_DATA *data;
        size_t needed_len = 0;
 
-       pad = get_pending_auth_data(smbpid);
+       pad = get_pending_auth_data(sconn, smbpid);
 
        /* Ensure we have some data. */
        if (pblob->length == 0) {
                /* Caller can cope. */
                DEBUG(2,("check_spnego_blob_complete: zero blob length !\n"));
-               delete_partial_auth(pad);
+               delete_partial_auth(sconn, pad);
                return NT_STATUS_OK;
        }
 
@@ -1028,7 +1008,7 @@ static NTSTATUS check_spnego_blob_complete(uint16 smbpid, uint16 vuid,
                                (unsigned int)pad->partial_data.length,
                                (unsigned int)copy_len ));
 
-                       delete_partial_auth(pad);
+                       delete_partial_auth(sconn, pad);
                        return NT_STATUS_INVALID_PARAMETER;
                }
 
@@ -1064,7 +1044,7 @@ static NTSTATUS check_spnego_blob_complete(uint16 smbpid, uint16 vuid,
                        data_blob_free(pblob);
                        *pblob = pad->partial_data;
                        ZERO_STRUCT(pad->partial_data);
-                       delete_partial_auth(pad);
+                       delete_partial_auth(sconn, pad);
                        return NT_STATUS_OK;
                }
 
@@ -1149,7 +1129,7 @@ static NTSTATUS check_spnego_blob_complete(uint16 smbpid, uint16 vuid,
        }
        pad->smbpid = smbpid;
        pad->vuid = vuid;
-       DLIST_ADD(pd_list, pad);
+       DLIST_ADD(sconn->smb1.pd_list, pad);
 
        return NT_STATUS_MORE_PROCESSING_REQUIRED;
 }
@@ -1175,6 +1155,7 @@ static void reply_sesssetup_and_X_spnego(struct smb_request *req)
        user_struct *vuser = NULL;
        NTSTATUS status = NT_STATUS_OK;
        uint16 smbpid = req->smbpid;
+       struct smbd_server_connection *sconn = smbd_server_conn;
 
        DEBUG(3,("Doing spnego session setup\n"));
 
@@ -1237,10 +1218,11 @@ static void reply_sesssetup_and_X_spnego(struct smb_request *req)
        }
 
        /* Did we get a valid vuid ? */
-       if (!is_partial_auth_vuid(vuid)) {
+       if (!is_partial_auth_vuid(sconn, vuid)) {
                /* No, then try and see if this is an intermediate sessionsetup
                 * for a large SPNEGO packet. */
-               struct pending_auth_data *pad = get_pending_auth_data(smbpid);
+               struct pending_auth_data *pad;
+               pad = get_pending_auth_data(sconn, smbpid);
                if (pad) {
                        DEBUG(10,("reply_sesssetup_and_X_spnego: found "
                                "pending vuid %u\n",
@@ -1250,9 +1232,9 @@ static void reply_sesssetup_and_X_spnego(struct smb_request *req)
        }
 
        /* Do we have a valid vuid now ? */
-       if (!is_partial_auth_vuid(vuid)) {
+       if (!is_partial_auth_vuid(sconn, vuid)) {
                /* No, start a new authentication setup. */
-               vuid = register_initial_vuid();
+               vuid = register_initial_vuid(sconn);
                if (vuid == UID_FIELD_INVALID) {
                        data_blob_free(&blob1);
                        reply_nterror(req, nt_status_squash(
@@ -1261,7 +1243,7 @@ static void reply_sesssetup_and_X_spnego(struct smb_request *req)
                }
        }
 
-       vuser = get_partial_auth_user_struct(vuid);
+       vuser = get_partial_auth_user_struct(sconn, vuid);
        /* This MUST be valid. */
        if (!vuser) {
                smb_panic("reply_sesssetup_and_X_spnego: invalid vuid.");
@@ -1272,12 +1254,12 @@ static void reply_sesssetup_and_X_spnego(struct smb_request *req)
         * field is 4k. Bug #4400. JRA.
         */
 
-       status = check_spnego_blob_complete(smbpid, vuid, &blob1);
+       status = check_spnego_blob_complete(sconn, smbpid, vuid, &blob1);
        if (!NT_STATUS_IS_OK(status)) {
                if (!NT_STATUS_EQUAL(status,
                                NT_STATUS_MORE_PROCESSING_REQUIRED)) {
                        /* Real error - kill the intermediate vuid */
-                       invalidate_vuid(vuid);
+                       invalidate_vuid(sconn, vuid);
                }
                data_blob_free(&blob1);
                reply_nterror(req, nt_status_squash(status));
@@ -1311,7 +1293,7 @@ static void reply_sesssetup_and_X_spnego(struct smb_request *req)
                        status = auth_ntlmssp_start(&vuser->auth_ntlmssp_state);
                        if (!NT_STATUS_IS_OK(status)) {
                                /* Kill the intermediate vuid */
-                               invalidate_vuid(vuid);
+                               invalidate_vuid(sconn, vuid);
                                data_blob_free(&blob1);
                                reply_nterror(req, nt_status_squash(status));
                                return;
@@ -1363,8 +1345,8 @@ static int shutdown_other_smbds(struct db_record *rec,
                return 0;
        }
 
-       DEBUG(0,("shutdown_other_smbds: shutting down pid %d "
-                "(IP %s)\n", procid_to_pid(&crec->pid), ip));
+       DEBUG(0,("shutdown_other_smbds: shutting down pid %u "
+                "(IP %s)\n", (unsigned int)procid_to_pid(&crec->pid), ip));
 
        messaging_send(smbd_messaging_context(), crec->pid, MSG_SHUTDOWN,
                       &data_blob_null);
@@ -1406,14 +1388,14 @@ void reply_sesssetup_and_X(struct smb_request *req)
        const char *native_os;
        const char *native_lanman;
        const char *primary_domain;
-       static bool done_sesssetup = False;
        auth_usersupplied_info *user_info = NULL;
        auth_serversupplied_info *server_info = NULL;
        uint16 smb_flag2 = req->flags2;
 
        NTSTATUS nt_status;
+       struct smbd_server_connection *sconn = smbd_server_conn;
 
-       bool doencrypt = global_encrypted_passwords_negotiated;
+       bool doencrypt = sconn->smb1.negprot.encrypted_passwords;
 
        START_PROFILE(SMBsesssetupX);
 
@@ -1428,7 +1410,7 @@ void reply_sesssetup_and_X(struct smb_request *req)
        if (req->wct == 12 &&
            (req->flags2 & FLAGS2_EXTENDED_SECURITY)) {
 
-               if (!global_spnego_negotiated) {
+               if (!sconn->smb1.negprot.spnego) {
                        DEBUG(0,("reply_sesssetup_and_X:  Rejecting attempt "
                                 "at SPNEGO session setup when it was not "
                                 "negotiated.\n"));
@@ -1643,7 +1625,7 @@ void reply_sesssetup_and_X(struct smb_request *req)
                                domain, user, get_remote_machine_name()));
 
        if (*user) {
-               if (global_spnego_negotiated) {
+               if (sconn->smb1.negprot.spnego) {
 
                        /* This has to be here, because this is a perfectly
                         * valid behaviour for guest logons :-( */
@@ -1672,9 +1654,9 @@ void reply_sesssetup_and_X(struct smb_request *req)
                data_blob_free(&nt_resp);
                data_blob_clear_free(&plaintext_password);
 
-               map_username(sub_user);
-               add_session_user(sub_user);
-               add_session_workgroup(domain);
+               map_username(sconn, sub_user);
+               add_session_user(sconn, sub_user);
+               add_session_workgroup(sconn, domain);
                /* Then force it to null for the benfit of the code below */
                user = "";
        }
@@ -1684,7 +1666,9 @@ void reply_sesssetup_and_X(struct smb_request *req)
                nt_status = check_guest_password(&server_info);
 
        } else if (doencrypt) {
-               if (!negprot_global_auth_context) {
+               struct auth_context *negprot_auth_context = NULL;
+               negprot_auth_context = sconn->smb1.negprot.auth_context;
+               if (!negprot_auth_context) {
                        DEBUG(0, ("reply_sesssetup_and_X:  Attempted encrypted "
                                "session setup without negprot denied!\n"));
                        reply_nterror(req, nt_status_squash(
@@ -1696,21 +1680,22 @@ void reply_sesssetup_and_X(struct smb_request *req)
                                                domain,
                                                lm_resp, nt_resp);
                if (NT_STATUS_IS_OK(nt_status)) {
-                       nt_status = negprot_global_auth_context->check_ntlm_password(
-                                       negprot_global_auth_context,
+                       nt_status = negprot_auth_context->check_ntlm_password(
+                                       negprot_auth_context,
                                        user_info,
                                        &server_info);
                }
        } else {
                struct auth_context *plaintext_auth_context = NULL;
-               const uint8 *chal;
 
                nt_status = make_auth_context_subsystem(
                                &plaintext_auth_context);
 
                if (NT_STATUS_IS_OK(nt_status)) {
-                       chal = plaintext_auth_context->get_ntlm_challenge(
-                                       plaintext_auth_context);
+                       uint8_t chal[8];
+
+                       plaintext_auth_context->get_ntlm_challenge(
+                                       plaintext_auth_context, chal);
 
                        if (!make_user_info_for_reply(&user_info,
                                                      user, domain, chal,
@@ -1790,7 +1775,7 @@ void reply_sesssetup_and_X(struct smb_request *req)
                TALLOC_FREE(server_info);
        } else {
                /* Ignore the initial vuid. */
-               sess_vuid = register_initial_vuid();
+               sess_vuid = register_initial_vuid(sconn);
                if (sess_vuid == UID_FIELD_INVALID) {
                        data_blob_free(&nt_resp);
                        data_blob_free(&lm_resp);
@@ -1800,7 +1785,7 @@ void reply_sesssetup_and_X(struct smb_request *req)
                        return;
                }
                /* register_existing_vuid keeps the server info */
-               sess_vuid = register_existing_vuid(sess_vuid,
+               sess_vuid = register_existing_vuid(sconn, sess_vuid,
                                        server_info,
                                        nt_resp.data ? nt_resp : lm_resp,
                                        sub_user);
@@ -1815,8 +1800,6 @@ void reply_sesssetup_and_X(struct smb_request *req)
 
                /* current_user_info is changed on new vuid */
                reload_services( True );
-
-               sessionsetup_start_signing_engine(server_info, req->inbuf);
        }
 
        data_blob_free(&nt_resp);
@@ -1824,11 +1807,13 @@ void reply_sesssetup_and_X(struct smb_request *req)
 
        SSVAL(req->outbuf,smb_uid,sess_vuid);
        SSVAL(req->inbuf,smb_uid,sess_vuid);
+       req->vuid = sess_vuid;
 
-       if (!done_sesssetup)
-               max_send = MIN(max_send,smb_bufsize);
-
-       done_sesssetup = True;
+       if (!sconn->smb1.sessions.done_sesssetup) {
+               sconn->smb1.sessions.max_send =
+                       MIN(sconn->smb1.sessions.max_send,smb_bufsize);
+       }
+       sconn->smb1.sessions.done_sesssetup = true;
 
        END_PROFILE(SMBsesssetupX);
        chain_reply(req);