s3:libsmb: get rid of cli_negprot
[mat/samba.git] / source3 / libsmb / cliconnect.c
index bc220280ebb0fa2e5f8a050a5805df5c90848939..491b7039f954f409b9a6a09c25aadffebd32ae19 100644 (file)
 
 #include "includes.h"
 #include "libsmb/libsmb.h"
-#include "popt_common.h"
+#include "auth_info.h"
 #include "../libcli/auth/libcli_auth.h"
 #include "../libcli/auth/spnego.h"
 #include "smb_krb5.h"
-#include "../libcli/auth/ntlmssp.h"
+#include "../auth/ntlmssp/ntlmssp.h"
 #include "libads/kerberos_proto.h"
 #include "krb5_env.h"
 #include "../lib/util/tevent_ntstatus.h"
 #include "async_smb.h"
 #include "libsmb/nmblib.h"
-#include "read_smb.h"
-
-static const struct {
-       int prot;
-       const char name[24];
-} prots[10] = {
-       {PROTOCOL_CORE,         "PC NETWORK PROGRAM 1.0"},
-       {PROTOCOL_COREPLUS,     "MICROSOFT NETWORKS 1.03"},
-       {PROTOCOL_LANMAN1,      "MICROSOFT NETWORKS 3.0"},
-       {PROTOCOL_LANMAN1,      "LANMAN1.0"},
-       {PROTOCOL_LANMAN2,      "LM1.2X002"},
-       {PROTOCOL_LANMAN2,      "DOS LANMAN2.1"},
-       {PROTOCOL_LANMAN2,      "LANMAN2.1"},
-       {PROTOCOL_LANMAN2,      "Samba"},
-       {PROTOCOL_NT1,          "NT LANMAN 1.0"},
-       {PROTOCOL_NT1,          "NT LM 0.12"},
-};
+#include "librpc/ndr/libndr.h"
+#include "../libcli/smb/smbXcli_base.h"
+#include "smb2cli.h"
 
 #define STAR_SMBSERVER "*SMBSERVER"
 
@@ -59,14 +45,14 @@ static const struct {
  strings.
 *******************************************************/
 
-static NTSTATUS smb_bytes_talloc_string(struct cli_state *cli,
+static NTSTATUS smb_bytes_talloc_string(TALLOC_CTX *mem_ctx,
                                        char *inbuf,
                                        char **dest,
                                        uint8_t *src,
                                        size_t srclen,
                                        ssize_t *destlen)
 {
-       *destlen = clistr_pull_talloc(cli,
+       *destlen = clistr_pull_talloc(mem_ctx,
                                inbuf,
                                SVAL(inbuf, smb_flg2),
                                dest,
@@ -78,7 +64,7 @@ static NTSTATUS smb_bytes_talloc_string(struct cli_state *cli,
        }
 
        if (*dest == NULL) {
-               *dest = talloc_strdup(cli, "");
+               *dest = talloc_strdup(mem_ctx, "");
                if (*dest == NULL) {
                        return NT_STATUS_NO_MEMORY;
                }
@@ -122,6 +108,7 @@ static struct tevent_req *cli_session_setup_lanman2_send(
        uint16_t *vwv;
        uint8_t *bytes;
        char *tmp;
+       uint16_t sec_mode = smb1cli_conn_server_security_mode(cli->conn);
 
        req = tevent_req_create(mem_ctx, &state,
                                struct cli_session_setup_lanman2_state);
@@ -132,25 +119,15 @@ static struct tevent_req *cli_session_setup_lanman2_send(
        state->user = user;
        vwv = state->vwv;
 
-       /*
-        * LANMAN servers predate NT status codes and Unicode and
-        * ignore those smb flags so we must disable the corresponding
-        * default capabilities that would otherwise cause the Unicode
-        * and NT Status flags to be set (and even returned by the
-        * server)
-        */
-
-       cli->capabilities &= ~(CAP_UNICODE | CAP_STATUS32);
-
        /*
         * if in share level security then don't send a password now
         */
-       if (!(cli->sec_mode & NEGOTIATE_SECURITY_USER_LEVEL)) {
+       if (!(sec_mode & NEGOTIATE_SECURITY_USER_LEVEL)) {
                passlen = 0;
        }
 
        if (passlen > 0
-           && (cli->sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE)
+           && (sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE)
            && passlen != 24) {
                /*
                 * Encrypted mode needed, and non encrypted password
@@ -161,7 +138,7 @@ static struct tevent_req *cli_session_setup_lanman2_send(
                        return tevent_req_post(req, ev);
                }
 
-               if (!SMBencrypt(pass, cli->secblob.data,
+               if (!SMBencrypt(pass, smb1cli_conn_server_challenge(cli->conn),
                                (uint8_t *)lm_response.data)) {
                        DEBUG(1, ("Password is > 14 chars in length, and is "
                                  "therefore incompatible with Lanman "
@@ -169,7 +146,7 @@ static struct tevent_req *cli_session_setup_lanman2_send(
                        tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
                        return tevent_req_post(req, ev);
                }
-       } else if ((cli->sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE)
+       } else if ((sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE)
                   && passlen == 24) {
                /*
                 * Encrypted mode needed, and encrypted password
@@ -204,7 +181,7 @@ static struct tevent_req *cli_session_setup_lanman2_send(
        SSVAL(vwv+2, 0, CLI_BUFFER_SIZE);
        SSVAL(vwv+3, 0, 2);
        SSVAL(vwv+4, 0, 1);
-       SIVAL(vwv+5, 0, cli->sesskey);
+       SIVAL(vwv+5, 0, smb1cli_conn_server_session_key(cli->conn));
        SSVAL(vwv+7, 0, lm_response.length);
 
        bytes = talloc_array(state, uint8_t, lm_response.length);
@@ -274,7 +251,7 @@ static void cli_session_setup_lanman2_done(struct tevent_req *subreq)
        inbuf = (char *)in;
        p = bytes;
 
-       cli->vuid = SVAL(inbuf, smb_uid);
+       cli_state_set_uid(state->cli, SVAL(inbuf, smb_uid));
        cli->is_guestlogin = ((SVAL(vwv+2, 0) & 1) != 0);
 
        status = smb_bytes_talloc_string(cli,
@@ -316,9 +293,6 @@ static void cli_session_setup_lanman2_done(struct tevent_req *subreq)
        }
        p += ret;
 
-       if (strstr(cli->server_type, "Samba")) {
-               cli->is_samba = True;
-       }
        status = cli_set_username(cli, state->user);
        if (tevent_req_nterror(req, status)) {
                return;
@@ -369,18 +343,31 @@ static NTSTATUS cli_session_setup_lanman2(struct cli_state *cli, const char *use
  Work out suitable capabilities to offer the server.
 ****************************************************************************/
 
-static uint32 cli_session_setup_capabilities(struct cli_state *cli)
+static uint32_t cli_session_setup_capabilities(struct cli_state *cli,
+                                              uint32_t sesssetup_capabilities)
 {
-       uint32 capabilities = CAP_NT_SMBS;
+       uint32_t client_capabilities = smb1cli_conn_capabilities(cli->conn);
 
-       if (!cli->force_dos_errors)
-               capabilities |= CAP_STATUS32;
+       /*
+        * We only send capabilities based on the mask for:
+        * - client only flags
+        * - flags used in both directions
+        *
+        * We do not echo the server only flags.
+        */
+       client_capabilities &= (SMB_CAP_BOTH_MASK | SMB_CAP_CLIENT_MASK);
 
-       if (cli->use_level_II_oplocks)
-               capabilities |= CAP_LEVEL_II_OPLOCKS;
+       /*
+        * Session Setup specific flags CAP_DYNAMIC_REAUTH
+        * and CAP_EXTENDED_SECURITY are passed by the caller.
+        * We need that in order to do guest logins even if
+        * CAP_EXTENDED_SECURITY is negotiated.
+        */
+       client_capabilities &= ~(CAP_DYNAMIC_REAUTH|CAP_EXTENDED_SECURITY);
+       sesssetup_capabilities &= (CAP_DYNAMIC_REAUTH|CAP_EXTENDED_SECURITY);
+       client_capabilities |= sesssetup_capabilities;
 
-       capabilities |= (cli->capabilities & (CAP_UNICODE|CAP_LARGE_FILES|CAP_LARGE_READX|CAP_LARGE_WRITEX|CAP_DFS));
-       return capabilities;
+       return client_capabilities;
 }
 
 /****************************************************************************
@@ -418,13 +405,13 @@ struct tevent_req *cli_session_setup_guest_create(TALLOC_CTX *mem_ctx,
        SSVAL(vwv+1, 0, 0);
        SSVAL(vwv+2, 0, CLI_BUFFER_SIZE);
        SSVAL(vwv+3, 0, 2);
-       SSVAL(vwv+4, 0, cli->pid);
-       SIVAL(vwv+5, 0, cli->sesskey);
+       SSVAL(vwv+4, 0, cli_state_get_vc_num(cli));
+       SIVAL(vwv+5, 0, smb1cli_conn_server_session_key(cli->conn));
        SSVAL(vwv+7, 0, 0);
        SSVAL(vwv+8, 0, 0);
        SSVAL(vwv+9, 0, 0);
        SSVAL(vwv+10, 0, 0);
-       SIVAL(vwv+11, 0, cli_session_setup_capabilities(cli));
+       SIVAL(vwv+11, 0, cli_session_setup_capabilities(cli, 0));
 
        bytes = talloc_array(state, uint8_t, 0);
 
@@ -502,7 +489,7 @@ static void cli_session_setup_guest_done(struct tevent_req *subreq)
        inbuf = (char *)in;
        p = bytes;
 
-       cli->vuid = SVAL(inbuf, smb_uid);
+       cli_state_set_uid(state->cli, SVAL(inbuf, smb_uid));
        cli->is_guestlogin = ((SVAL(vwv+2, 0) & 1) != 0);
 
        status = smb_bytes_talloc_string(cli,
@@ -544,10 +531,6 @@ static void cli_session_setup_guest_done(struct tevent_req *subreq)
        }
        p += ret;
 
-       if (strstr(cli->server_type, "Samba")) {
-               cli->is_samba = True;
-       }
-
        status = cli_set_username(cli, "");
        if (!NT_STATUS_IS_OK(status)) {
                tevent_req_nterror(req, status);
@@ -637,13 +620,13 @@ static struct tevent_req *cli_session_setup_plain_send(
        SSVAL(vwv+1, 0, 0);
        SSVAL(vwv+2, 0, CLI_BUFFER_SIZE);
        SSVAL(vwv+3, 0, 2);
-       SSVAL(vwv+4, 0, cli->pid);
-       SIVAL(vwv+5, 0, cli->sesskey);
+       SSVAL(vwv+4, 0, cli_state_get_vc_num(cli));
+       SIVAL(vwv+5, 0, smb1cli_conn_server_session_key(cli->conn));
        SSVAL(vwv+7, 0, 0);
        SSVAL(vwv+8, 0, 0);
        SSVAL(vwv+9, 0, 0);
        SSVAL(vwv+10, 0, 0);
-       SIVAL(vwv+11, 0, cli_session_setup_capabilities(cli));
+       SIVAL(vwv+11, 0, cli_session_setup_capabilities(cli, 0));
 
        bytes = talloc_array(state, uint8_t, 0);
        bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), pass, strlen(pass)+1,
@@ -709,7 +692,7 @@ static void cli_session_setup_plain_done(struct tevent_req *subreq)
        inbuf = (char *)in;
        p = bytes;
 
-       cli->vuid = SVAL(inbuf, smb_uid);
+       cli_state_set_uid(state->cli, SVAL(inbuf, smb_uid));
        cli->is_guestlogin = ((SVAL(vwv+2, 0) & 1) != 0);
 
        status = smb_bytes_talloc_string(cli,
@@ -755,9 +738,7 @@ static void cli_session_setup_plain_done(struct tevent_req *subreq)
        if (tevent_req_nterror(req, status)) {
                return;
        }
-       if (strstr(cli->server_type, "Samba")) {
-               cli->is_samba = True;
-       }
+
        tevent_req_done(req);
 }
 
@@ -852,20 +833,18 @@ static struct tevent_req *cli_session_setup_nt1_send(
                        DATA_BLOB server_chal;
                        DATA_BLOB names_blob;
 
-                       server_chal = data_blob(cli->secblob.data,
-                                               MIN(cli->secblob.length, 8));
-                       if (tevent_req_nomem(server_chal.data, req)) {
-                               return tevent_req_post(req, ev);
-                       }
+                       server_chal =
+                               data_blob_const(smb1cli_conn_server_challenge(cli->conn),
+                                               8);
 
                        /*
                         * note that the 'workgroup' here is a best
                         * guess - we don't know the server's domain
-                        * at this point.  The 'server name' is also
-                        * dodgy...
+                        * at this point. Windows clients also don't
+                        * use hostname...
                         */
                        names_blob = NTLMv2_generate_names_blob(
-                               NULL, cli->called.name, workgroup);
+                               NULL, NULL, workgroup);
 
                        if (tevent_req_nomem(names_blob.data, req)) {
                                return tevent_req_post(req, ev);
@@ -876,13 +855,11 @@ static struct tevent_req *cli_session_setup_nt1_send(
                                              &lm_response, &nt_response,
                                              NULL, &session_key)) {
                                data_blob_free(&names_blob);
-                               data_blob_free(&server_chal);
                                tevent_req_nterror(
                                        req, NT_STATUS_ACCESS_DENIED);
                                return tevent_req_post(req, ev);
                        }
                        data_blob_free(&names_blob);
-                       data_blob_free(&server_chal);
 
                } else {
                        uchar nt_hash[16];
@@ -896,7 +873,7 @@ static struct tevent_req *cli_session_setup_nt1_send(
                                return tevent_req_post(req, ev);
                        }
 
-                       SMBNTencrypt(pass, cli->secblob.data,
+                       SMBNTencrypt(pass, smb1cli_conn_server_challenge(cli->conn),
                                     nt_response.data);
 #endif
                        /* non encrypted password supplied. Ignore ntpass. */
@@ -907,7 +884,8 @@ static struct tevent_req *cli_session_setup_nt1_send(
                                        return tevent_req_post(req, ev);
                                }
 
-                               if (!SMBencrypt(pass,cli->secblob.data,
+                               if (!SMBencrypt(pass,
+                                               smb1cli_conn_server_challenge(cli->conn),
                                                lm_response.data)) {
                                        /*
                                         * Oops, the LM response is
@@ -943,7 +921,6 @@ static struct tevent_req *cli_session_setup_nt1_send(
                        SMBsesskeygen_ntv1(nt_hash, session_key.data);
 #endif
                }
-               cli_temp_set_signing(cli);
        } else {
                /* pre-encrypted password supplied.  Only used for 
                   security=server, can't do
@@ -985,13 +962,13 @@ static struct tevent_req *cli_session_setup_nt1_send(
        SSVAL(vwv+1, 0, 0);
        SSVAL(vwv+2, 0, CLI_BUFFER_SIZE);
        SSVAL(vwv+3, 0, 2);
-       SSVAL(vwv+4, 0, cli->pid);
-       SIVAL(vwv+5, 0, cli->sesskey);
+       SSVAL(vwv+4, 0, cli_state_get_vc_num(cli));
+       SIVAL(vwv+5, 0, smb1cli_conn_server_session_key(cli->conn));
        SSVAL(vwv+7, 0, lm_response.length);
        SSVAL(vwv+8, 0, nt_response.length);
        SSVAL(vwv+9, 0, 0);
        SSVAL(vwv+10, 0, 0);
-       SIVAL(vwv+11, 0, cli_session_setup_capabilities(cli));
+       SIVAL(vwv+11, 0, cli_session_setup_capabilities(cli, 0));
 
        bytes = talloc_array(state, uint8_t,
                             lm_response.length + nt_response.length);
@@ -1066,7 +1043,7 @@ static void cli_session_setup_nt1_done(struct tevent_req *subreq)
        inbuf = (char *)in;
        p = bytes;
 
-       cli->vuid = SVAL(inbuf, smb_uid);
+       cli_state_set_uid(state->cli, SVAL(inbuf, smb_uid));
        cli->is_guestlogin = ((SVAL(vwv+2, 0) & 1) != 0);
 
        status = smb_bytes_talloc_string(cli,
@@ -1105,10 +1082,6 @@ static void cli_session_setup_nt1_done(struct tevent_req *subreq)
        }
        p += ret;
 
-       if (strstr(cli->server_type, "Samba")) {
-               cli->is_samba = True;
-       }
-
        status = cli_set_username(cli, state->user);
        if (tevent_req_nterror(req, status)) {
                return;
@@ -1182,6 +1155,9 @@ struct cli_sesssetup_blob_state {
        uint16_t vwv[12];
        uint8_t *buf;
 
+       DATA_BLOB smb2_blob;
+       struct iovec *recv_iov;
+
        NTSTATUS status;
        char *inbuf;
        DATA_BLOB ret_blob;
@@ -1198,6 +1174,7 @@ static struct tevent_req *cli_sesssetup_blob_send(TALLOC_CTX *mem_ctx,
 {
        struct tevent_req *req, *subreq;
        struct cli_sesssetup_blob_state *state;
+       uint32_t usable_space;
 
        req = tevent_req_create(mem_ctx, &state,
                                struct cli_sesssetup_blob_state);
@@ -1208,16 +1185,21 @@ static struct tevent_req *cli_sesssetup_blob_send(TALLOC_CTX *mem_ctx,
        state->blob = blob;
        state->cli = cli;
 
-       if (cli->max_xmit < BASE_SESSSETUP_BLOB_PACKET_SIZE + 1) {
+       if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) {
+               usable_space = UINT16_MAX;
+       } else {
+               usable_space = cli_state_available_size(cli,
+                               BASE_SESSSETUP_BLOB_PACKET_SIZE);
+       }
+
+       if (usable_space == 0) {
                DEBUG(1, ("cli_session_setup_blob: cli->max_xmit too small "
-                         "(was %u, need minimum %u)\n",
-                         (unsigned int)cli->max_xmit,
-                         BASE_SESSSETUP_BLOB_PACKET_SIZE));
+                         "(not possible to send %u bytes)\n",
+                         BASE_SESSSETUP_BLOB_PACKET_SIZE + 1));
                tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
                return tevent_req_post(req, ev);
        }
-       state->max_blob_size =
-               MIN(cli->max_xmit - BASE_SESSSETUP_BLOB_PACKET_SIZE, 0xFFFF);
+       state->max_blob_size = MIN(usable_space, 0xFFFF);
 
        if (!cli_sesssetup_blob_next(state, &subreq)) {
                tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
@@ -1233,6 +1215,32 @@ static bool cli_sesssetup_blob_next(struct cli_sesssetup_blob_state *state,
        struct tevent_req *subreq;
        uint16_t thistime;
 
+       thistime = MIN(state->blob.length, state->max_blob_size);
+
+       if (smbXcli_conn_protocol(state->cli->conn) >= PROTOCOL_SMB2_02) {
+
+               state->smb2_blob.data = state->blob.data;
+               state->smb2_blob.length = thistime;
+
+               state->blob.data += thistime;
+               state->blob.length -= thistime;
+
+               subreq = smb2cli_session_setup_send(state, state->ev,
+                                                   state->cli->conn,
+                                                   state->cli->timeout,
+                                                   state->cli->smb2.session,
+                                                   0, /* in_flags */
+                                                   SMB2_CAP_DFS, /* in_capabilities */
+                                                   0, /* in_channel */
+                                                   0, /* in_previous_session_id */
+                                                   &state->smb2_blob);
+               if (subreq == NULL) {
+                       return false;
+               }
+               *psubreq = subreq;
+               return true;
+       }
+
        SCVAL(state->vwv+0, 0, 0xFF);
        SCVAL(state->vwv+0, 1, 0);
        SSVAL(state->vwv+1, 0, 0);
@@ -1241,14 +1249,12 @@ static bool cli_sesssetup_blob_next(struct cli_sesssetup_blob_state *state,
        SSVAL(state->vwv+4, 0, 1);
        SIVAL(state->vwv+5, 0, 0);
 
-       thistime = MIN(state->blob.length, state->max_blob_size);
        SSVAL(state->vwv+7, 0, thistime);
 
        SSVAL(state->vwv+8, 0, 0);
        SSVAL(state->vwv+9, 0, 0);
        SIVAL(state->vwv+10, 0,
-             cli_session_setup_capabilities(state->cli)
-             | CAP_EXTENDED_SECURITY);
+               cli_session_setup_capabilities(state->cli, CAP_EXTENDED_SECURITY));
 
        state->buf = (uint8_t *)talloc_memdup(state, state->blob.data,
                                              thistime);
@@ -1292,8 +1298,15 @@ static void cli_sesssetup_blob_done(struct tevent_req *subreq)
        uint8_t *inbuf;
        ssize_t ret;
 
-       status = cli_smb_recv(subreq, state, &inbuf, 4, &wct, &vwv,
-                             &num_bytes, &bytes);
+       if (smbXcli_conn_protocol(state->cli->conn) >= PROTOCOL_SMB2_02) {
+               status = smb2cli_session_setup_recv(subreq, state,
+                                                   &state->recv_iov,
+                                                   &state->ret_blob);
+       } else {
+               status = cli_smb_recv(subreq, state, &inbuf, 4, &wct, &vwv,
+                                     &num_bytes, &bytes);
+               TALLOC_FREE(state->buf);
+       }
        TALLOC_FREE(subreq);
        if (!NT_STATUS_IS_OK(status)
            && !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
@@ -1302,10 +1315,13 @@ static void cli_sesssetup_blob_done(struct tevent_req *subreq)
        }
 
        state->status = status;
-       TALLOC_FREE(state->buf);
+
+       if (smbXcli_conn_protocol(state->cli->conn) >= PROTOCOL_SMB2_02) {
+               goto next;
+       }
 
        state->inbuf = (char *)inbuf;
-       cli->vuid = SVAL(state->inbuf, smb_uid);
+       cli_state_set_uid(state->cli, SVAL(inbuf, smb_uid));
        cli->is_guestlogin = ((SVAL(vwv+2, 0) & 1) != 0);
 
        blob_length = SVAL(vwv+3, 0);
@@ -1356,16 +1372,13 @@ static void cli_sesssetup_blob_done(struct tevent_req *subreq)
        }
        p += ret;
 
-       if (strstr(cli->server_type, "Samba")) {
-               cli->is_samba = True;
-       }
-
+next:
        if (state->blob.length != 0) {
                /*
                 * More to send
                 */
                if (!cli_sesssetup_blob_next(state, &subreq)) {
-                       tevent_req_nomem(NULL, req);
+                       tevent_req_oom(req);
                        return;
                }
                tevent_req_set_callback(subreq, cli_sesssetup_blob_done, req);
@@ -1377,25 +1390,32 @@ static void cli_sesssetup_blob_done(struct tevent_req *subreq)
 static NTSTATUS cli_sesssetup_blob_recv(struct tevent_req *req,
                                        TALLOC_CTX *mem_ctx,
                                        DATA_BLOB *pblob,
-                                       char **pinbuf)
+                                       char **pinbuf,
+                                       struct iovec **precv_iov)
 {
        struct cli_sesssetup_blob_state *state = tevent_req_data(
                req, struct cli_sesssetup_blob_state);
        NTSTATUS status;
        char *inbuf;
+       struct iovec *recv_iov;
 
        if (tevent_req_is_nterror(req, &status)) {
-               state->cli->vuid = 0;
+               TALLOC_FREE(state->cli->smb2.session);
+               cli_state_set_uid(state->cli, UID_FIELD_INVALID);
                return status;
        }
 
        inbuf = talloc_move(mem_ctx, &state->inbuf);
+       recv_iov = talloc_move(mem_ctx, &state->recv_iov);
        if (pblob != NULL) {
                *pblob = state->ret_blob;
        }
        if (pinbuf != NULL) {
                *pinbuf = inbuf;
        }
+       if (precv_iov != NULL) {
+               *precv_iov = recv_iov;
+       }
         /* could be NT_STATUS_MORE_PROCESSING_REQUIRED */
        return state->status;
 }
@@ -1441,8 +1461,6 @@ static struct tevent_req *cli_session_setup_kerberos_send(
        state->cli = cli;
        state->ads_status = ADS_SUCCESS;
 
-       cli_temp_set_signing(cli);
-
        /*
         * Ok, this is cheating: spnego_gen_krb5_negTokenInit can block if
         * we have to acquire a ticket. To be fixed later :-)
@@ -1463,6 +1481,14 @@ static struct tevent_req *cli_session_setup_kerberos_send(
                  state->negTokenTarg.length);
 #endif
 
+       if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) {
+               state->cli->smb2.session = smbXcli_session_create(cli,
+                                                                 cli->conn);
+               if (tevent_req_nomem(state->cli->smb2.session, req)) {
+                       return tevent_req_post(req, ev);
+               }
+       }
+
        subreq = cli_sesssetup_blob_send(state, ev, cli, state->negTokenTarg);
        if (tevent_req_nomem(subreq, req)) {
                return tevent_req_post(req, ev);
@@ -1478,25 +1504,36 @@ static void cli_session_setup_kerberos_done(struct tevent_req *subreq)
        struct cli_session_setup_kerberos_state *state = tevent_req_data(
                req, struct cli_session_setup_kerberos_state);
        char *inbuf = NULL;
+       struct iovec *recv_iov = NULL;
        NTSTATUS status;
 
-       status = cli_sesssetup_blob_recv(subreq, talloc_tos(), NULL, &inbuf);
+       status = cli_sesssetup_blob_recv(subreq, state,
+                                        NULL, &inbuf, &recv_iov);
+       TALLOC_FREE(subreq);
        if (!NT_STATUS_IS_OK(status)) {
-               TALLOC_FREE(subreq);
                tevent_req_nterror(req, status);
                return;
        }
 
        cli_set_session_key(state->cli, state->session_key_krb5);
 
-       if (cli_simple_set_signing(state->cli, state->session_key_krb5,
-                                  data_blob_null)
-           && !cli_check_sign_mac(state->cli, inbuf, 1)) {
-               TALLOC_FREE(subreq);
-               tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
-               return;
+       if (smbXcli_conn_protocol(state->cli->conn) >= PROTOCOL_SMB2_02) {
+               struct smbXcli_session *session = state->cli->smb2.session;
+               status = smb2cli_session_set_session_key(session,
+                                               state->session_key_krb5,
+                                               recv_iov);
+               if (tevent_req_nterror(req, status)) {
+                       return;
+               }
+       } else {
+               if (cli_simple_set_signing(state->cli, state->session_key_krb5,
+                                          data_blob_null)
+                   && !cli_check_sign_mac(state->cli, inbuf, 1)) {
+                       tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
+                       return;
+               }
        }
-       TALLOC_FREE(subreq);
+
        tevent_req_done(req);
 }
 
@@ -1587,10 +1624,8 @@ static struct tevent_req *cli_session_setup_ntlmssp_send(
        talloc_set_destructor(
                state, cli_session_setup_ntlmssp_state_destructor);
 
-       cli_temp_set_signing(cli);
-
        status = ntlmssp_client_start(state,
-                                     global_myname(),
+                                     lp_netbios_name(),
                                      lp_workgroup(),
                                      lp_client_ntlmv2_auth(),
                                      &state->ntlmssp_state);
@@ -1624,6 +1659,14 @@ static struct tevent_req *cli_session_setup_ntlmssp_send(
        state->blob_out = spnego_gen_negTokenInit(state, OIDs_ntlm, &blob_out, NULL);
        data_blob_free(&blob_out);
 
+       if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) {
+               state->cli->smb2.session = smbXcli_session_create(cli,
+                                                                 cli->conn);
+               if (tevent_req_nomem(state->cli->smb2.session, req)) {
+                       return tevent_req_post(req, ev);
+               }
+       }
+
        subreq = cli_sesssetup_blob_send(state, ev, cli, state->blob_out);
        if (tevent_req_nomem(subreq, req)) {
                return tevent_req_post(req, ev);
@@ -1643,11 +1686,12 @@ static void cli_session_setup_ntlmssp_done(struct tevent_req *subreq)
                req, struct cli_session_setup_ntlmssp_state);
        DATA_BLOB blob_in, msg_in, blob_out;
        char *inbuf = NULL;
+       struct iovec *recv_iov = NULL;
        bool parse_ret;
        NTSTATUS status;
 
        status = cli_sesssetup_blob_recv(subreq, talloc_tos(), &blob_in,
-                                        &inbuf);
+                                        &inbuf, &recv_iov);
        TALLOC_FREE(subreq);
        data_blob_free(&state->blob_out);
 
@@ -1657,7 +1701,6 @@ static void cli_session_setup_ntlmssp_done(struct tevent_req *subreq)
                        state->cli->server_domain = talloc_strdup(state->cli,
                                                state->ntlmssp_state->server.netbios_domain);
                        if (state->cli->server_domain == NULL) {
-                               TALLOC_FREE(subreq);
                                tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
                                return;
                        }
@@ -1665,15 +1708,39 @@ static void cli_session_setup_ntlmssp_done(struct tevent_req *subreq)
                cli_set_session_key(
                        state->cli, state->ntlmssp_state->session_key);
 
-               if (cli_simple_set_signing(
-                           state->cli, state->ntlmssp_state->session_key,
-                           data_blob_null)
-                   && !cli_check_sign_mac(state->cli, inbuf, 1)) {
-                       TALLOC_FREE(subreq);
-                       tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
-                       return;
+               if (smbXcli_conn_protocol(state->cli->conn) >= PROTOCOL_SMB2_02) {
+                       struct smbXcli_session *session = state->cli->smb2.session;
+
+                       if (ntlmssp_is_anonymous(state->ntlmssp_state)) {
+                               /*
+                                * Windows server does not set the
+                                * SMB2_SESSION_FLAG_IS_GUEST nor
+                                * SMB2_SESSION_FLAG_IS_NULL flag.
+                                *
+                                * This fix makes sure we do not try
+                                * to verify a signature on the final
+                                * session setup response.
+                                */
+                               TALLOC_FREE(state->ntlmssp_state);
+                               tevent_req_done(req);
+                               return;
+                       }
+
+                       status = smb2cli_session_set_session_key(session,
+                                               state->ntlmssp_state->session_key,
+                                               recv_iov);
+                       if (tevent_req_nterror(req, status)) {
+                               return;
+                       }
+               } else {
+                       if (cli_simple_set_signing(
+                                   state->cli, state->ntlmssp_state->session_key,
+                                   data_blob_null)
+                           && !cli_check_sign_mac(state->cli, inbuf, 1)) {
+                               tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
+                               return;
+                       }
                }
-               TALLOC_FREE(subreq);
                TALLOC_FREE(state->ntlmssp_state);
                tevent_req_done(req);
                return;
@@ -1716,14 +1783,12 @@ static void cli_session_setup_ntlmssp_done(struct tevent_req *subreq)
 
        if (!NT_STATUS_IS_OK(status)
            && !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
-               TALLOC_FREE(subreq);
                TALLOC_FREE(state->ntlmssp_state);
                tevent_req_nterror(req, status);
                return;
        }
 
        state->blob_out = spnego_gen_auth(state, blob_out);
-       TALLOC_FREE(subreq);
        if (tevent_req_nomem(state->blob_out.data, req)) {
                return;
        }
@@ -1743,7 +1808,7 @@ static NTSTATUS cli_session_setup_ntlmssp_recv(struct tevent_req *req)
        NTSTATUS status;
 
        if (tevent_req_is_nterror(req, &status)) {
-               state->cli->vuid = 0;
+               cli_state_set_uid(state->cli, UID_FIELD_INVALID);
                return status;
        }
        return NT_STATUS_OK;
@@ -1785,22 +1850,30 @@ fail:
  dest_realm: The realm we're connecting to, if NULL we use our default realm.
 ****************************************************************************/
 
-ADS_STATUS cli_session_setup_spnego(struct cli_state *cli, const char *user, 
-                             const char *pass, const char *user_domain,
+static ADS_STATUS cli_session_setup_spnego(struct cli_state *cli,
+                             const char *user,
+                             const char *pass,
+                             const char *user_domain,
                              const char * dest_realm)
 {
        char *principal = NULL;
        char *OIDs[ASN1_MAX_OIDS];
        int i;
-       DATA_BLOB blob;
+       const DATA_BLOB *server_blob;
+       DATA_BLOB blob = data_blob_null;
        const char *p = NULL;
        char *account = NULL;
        NTSTATUS status;
 
-       DEBUG(3,("Doing spnego session setup (blob length=%lu)\n", (unsigned long)cli->secblob.length));
+       server_blob = smbXcli_conn_server_gss_blob(cli->conn);
+       if (server_blob) {
+               blob = data_blob(server_blob->data, server_blob->length);
+       }
+
+       DEBUG(3,("Doing spnego session setup (blob length=%lu)\n", (unsigned long)blob.length));
 
        /* the server might not even do spnego */
-       if (cli->secblob.length <= 16) {
+       if (blob.length == 0) {
                DEBUG(3,("server didn't supply a full spnego negprot\n"));
                goto ntlmssp;
        }
@@ -1809,9 +1882,6 @@ ADS_STATUS cli_session_setup_spnego(struct cli_state *cli, const char *user,
        file_save("negprot.dat", cli->secblob.data, cli->secblob.length);
 #endif
 
-       /* there is 16 bytes of GUID before the real spnego packet starts */
-       blob = data_blob(cli->secblob.data+16, cli->secblob.length-16);
-
        /* The server sent us the first part of the SPNEGO exchange in the
         * negprot reply. It is WRONG to depend on the principal sent in the
         * negprot reply, but right now we do it. If we don't receive one,
@@ -1848,8 +1918,9 @@ ADS_STATUS cli_session_setup_spnego(struct cli_state *cli, const char *user,
        /* If password is set we reauthenticate to kerberos server
         * and do not store results */
 
-       if (cli->got_kerberos_mechanism && cli->use_kerberos) {
+       if (user && *user && cli->got_kerberos_mechanism && cli->use_kerberos) {
                ADS_STATUS rc;
+               const char *remote_name = smbXcli_conn_remote_name(cli->conn);
 
                if (pass && *pass) {
                        int ret;
@@ -1873,59 +1944,34 @@ ADS_STATUS cli_session_setup_spnego(struct cli_state *cli, const char *user,
                }
 
                if (principal == NULL &&
-                       !is_ipaddress(cli->desthost) &&
+                       !is_ipaddress(remote_name) &&
                        !strequal(STAR_SMBSERVER,
-                               cli->desthost)) {
-                       char *realm = NULL;
-                       char *host = NULL;
+                                 remote_name)) {
                        DEBUG(3,("cli_session_setup_spnego: using target "
                                 "hostname not SPNEGO principal\n"));
 
-                       host = strchr_m(cli->desthost, '.');
                        if (dest_realm) {
-                               realm = SMB_STRDUP(dest_realm);
-                               if (!realm) {
-                                       return ADS_ERROR_NT(NT_STATUS_NO_MEMORY);
+                               char *realm = strupper_talloc(talloc_tos(), dest_realm);
+                               if (realm) {
+                                       principal = talloc_asprintf(talloc_tos(),
+                                                                   "cifs/%s@%s",
+                                                                   remote_name,
+                                                                   realm);
+                                       TALLOC_FREE(realm);
                                }
-                               strupper_m(realm);
                        } else {
-                               if (host) {
-                                       /* DNS name. */
-                                       realm = kerberos_get_realm_from_hostname(cli->desthost);
-                               } else {
-                                       /* NetBIOS name - use our realm. */
-                                       realm = kerberos_get_default_realm_from_ccache();
-                               }
-                       }
-
-                       if (realm == NULL || *realm == '\0') {
-                               realm = SMB_STRDUP(lp_realm());
-                               if (!realm) {
-                                       return ADS_ERROR_NT(NT_STATUS_NO_MEMORY);
-                               }
-                               strupper_m(realm);
-                               DEBUG(3,("cli_session_setup_spnego: cannot "
-                                       "get realm from dest_realm %s, "
-                                       "desthost %s. Using default "
-                                       "smb.conf realm %s\n",
-                                       dest_realm ? dest_realm : "<null>",
-                                       cli->desthost,
-                                       realm));
+                               principal = kerberos_get_principal_from_service_hostname(talloc_tos(),
+                                                                                        "cifs",
+                                                                                        remote_name,
+                                                                                        lp_realm());
                        }
 
-                       principal = talloc_asprintf(talloc_tos(),
-                                                   "cifs/%s@%s",
-                                                   cli->desthost,
-                                                   realm);
                        if (!principal) {
-                               SAFE_FREE(realm);
                                return ADS_ERROR_NT(NT_STATUS_NO_MEMORY);
                        }
                        DEBUG(3,("cli_session_setup_spnego: guessed "
                                "server principal=%s\n",
                                principal ? principal : "<null>"));
-
-                       SAFE_FREE(realm);
                }
 
                if (principal) {
@@ -1971,6 +2017,7 @@ NTSTATUS cli_session_setup(struct cli_state *cli,
 {
        char *p;
        char *user2;
+       uint16_t sec_mode = smb1cli_conn_server_security_mode(cli->conn);
 
        if (user) {
                user2 = talloc_strdup(talloc_tos(), user);
@@ -1994,7 +2041,7 @@ NTSTATUS cli_session_setup(struct cli_state *cli,
                workgroup = user2;
        }
 
-       if (cli->protocol < PROTOCOL_LANMAN1) {
+       if (smbXcli_conn_protocol(cli->conn) < PROTOCOL_LANMAN1) {
                return NT_STATUS_OK;
        }
 
@@ -2004,14 +2051,14 @@ NTSTATUS cli_session_setup(struct cli_state *cli,
 
        /* if its an older server then we have to use the older request format */
 
-       if (cli->protocol < PROTOCOL_NT1) {
+       if (smbXcli_conn_protocol(cli->conn) < PROTOCOL_NT1) {
                if (!lp_client_lanman_auth() && passlen != 24 && (*pass)) {
                        DEBUG(1, ("Server requested LM password but 'client lanman auth = no'"
                                  " or 'client ntlmv2 auth = yes'\n"));
                        return NT_STATUS_ACCESS_DENIED;
                }
 
-               if ((cli->sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) == 0 &&
+               if ((sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) == 0 &&
                    !lp_client_plaintext_auth() && (*pass)) {
                        DEBUG(1, ("Server requested LM password but 'client plaintext auth = no'"
                                  " or 'client ntlmv2 auth = yes'\n"));
@@ -2022,6 +2069,18 @@ NTSTATUS cli_session_setup(struct cli_state *cli,
                                                 workgroup);
        }
 
+       if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) {
+               const char *remote_realm = cli_state_remote_realm(cli);
+               ADS_STATUS status = cli_session_setup_spnego(cli, user, pass,
+                                                            workgroup,
+                                                            remote_realm);
+               if (!ADS_ERR_OK(status)) {
+                       DEBUG(3, ("SMB2-SPNEGO login failed: %s\n", ads_errstr(status)));
+                       return ads_ntstatus(status);
+               }
+               return NT_STATUS_OK;
+       }
+
        /* if no user is supplied then we have to do an anonymous connection.
           passwords are ignored */
 
@@ -2032,13 +2091,13 @@ NTSTATUS cli_session_setup(struct cli_state *cli,
            password at this point. The password is sent in the tree
            connect */
 
-       if ((cli->sec_mode & NEGOTIATE_SECURITY_USER_LEVEL) == 0) 
+       if ((sec_mode & NEGOTIATE_SECURITY_USER_LEVEL) == 0)
                return cli_session_setup_plain(cli, user, "", workgroup);
 
        /* if the server doesn't support encryption then we have to use 
           plaintext. The second password is ignored */
 
-       if ((cli->sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) == 0) {
+       if ((sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) == 0) {
                if (!lp_client_plaintext_auth() && (*pass)) {
                        DEBUG(1, ("Server requested LM password but 'client plaintext auth = no'"
                                  " or 'client ntlmv2 auth = yes'\n"));
@@ -2049,9 +2108,11 @@ NTSTATUS cli_session_setup(struct cli_state *cli,
 
        /* if the server supports extended security then use SPNEGO */
 
-       if (cli->capabilities & CAP_EXTENDED_SECURITY) {
+       if (smb1cli_conn_capabilities(cli->conn) & CAP_EXTENDED_SECURITY) {
+               const char *remote_realm = cli_state_remote_realm(cli);
                ADS_STATUS status = cli_session_setup_spnego(cli, user, pass,
-                                                            workgroup, NULL);
+                                                            workgroup,
+                                                            remote_realm);
                if (!ADS_ERR_OK(status)) {
                        DEBUG(3, ("SPNEGO login failed: %s\n", ads_errstr(status)));
                        return ads_ntstatus(status);
@@ -2069,10 +2130,6 @@ NTSTATUS cli_session_setup(struct cli_state *cli,
                }
        }
 
-       if (strstr(cli->server_type, "Samba")) {
-               cli->is_samba = True;
-       }
-
        return NT_STATUS_OK;
 }
 
@@ -2126,7 +2183,7 @@ static void cli_ulogoff_done(struct tevent_req *subreq)
                tevent_req_nterror(req, status);
                return;
        }
-       state->cli->vuid = -1;
+       cli_state_set_uid(state->cli, UID_FIELD_INVALID);
        tevent_req_done(req);
 }
 
@@ -2186,6 +2243,7 @@ struct tevent_req *cli_tcon_andx_create(TALLOC_CTX *mem_ctx,
        uint16_t *vwv;
        char *tmp = NULL;
        uint8_t *bytes;
+       uint16_t sec_mode = smb1cli_conn_server_security_mode(cli->conn);
 
        *psmbreq = NULL;
 
@@ -2202,7 +2260,7 @@ struct tevent_req *cli_tcon_andx_create(TALLOC_CTX *mem_ctx,
        }
 
        /* in user level security don't send a password now */
-       if (cli->sec_mode & NEGOTIATE_SECURITY_USER_LEVEL) {
+       if (sec_mode & NEGOTIATE_SECURITY_USER_LEVEL) {
                passlen = 1;
                pass = "";
        } else if (pass == NULL) {
@@ -2211,7 +2269,7 @@ struct tevent_req *cli_tcon_andx_create(TALLOC_CTX *mem_ctx,
                goto access_denied;
        }
 
-       if ((cli->sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) &&
+       if ((sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) &&
            *pass && passlen != 24) {
                if (!lp_client_lanman_auth()) {
                        DEBUG(1, ("Server requested LANMAN password "
@@ -2224,14 +2282,14 @@ struct tevent_req *cli_tcon_andx_create(TALLOC_CTX *mem_ctx,
                 * Non-encrypted passwords - convert to DOS codepage before
                 * encryption.
                 */
-               SMBencrypt(pass, cli->secblob.data, p24);
+               SMBencrypt(pass, smb1cli_conn_server_challenge(cli->conn), p24);
                passlen = 24;
                pass = (const char *)p24;
        } else {
-               if((cli->sec_mode & (NEGOTIATE_SECURITY_USER_LEVEL
+               if((sec_mode & (NEGOTIATE_SECURITY_USER_LEVEL
                                     |NEGOTIATE_SECURITY_CHALLENGE_RESPONSE))
                   == 0) {
-                       char *tmp_pass;
+                       uint8_t *tmp_pass;
 
                        if (!lp_client_plaintext_auth() && (*pass)) {
                                DEBUG(1, ("Server requested plaintext "
@@ -2244,21 +2302,20 @@ struct tevent_req *cli_tcon_andx_create(TALLOC_CTX *mem_ctx,
                         * Non-encrypted passwords - convert to DOS codepage
                         * before using.
                         */
-                       tmp_pass = talloc_array(talloc_tos(), char, 128);
-                       if (tmp_pass == NULL) {
-                               tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
+                       tmp_pass = talloc_array(talloc_tos(), uint8, 0);
+                       if (tevent_req_nomem(tmp_pass, req)) {
                                return tevent_req_post(req, ev);
                        }
-                       passlen = clistr_push(cli,
-                                       tmp_pass,
-                                       pass,
-                                       talloc_get_size(tmp_pass),
-                                       STR_TERMINATE);
-                       if (passlen == -1) {
-                               tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
+                       tmp_pass = trans2_bytes_push_str(tmp_pass,
+                                                        false, /* always DOS */
+                                                        pass,
+                                                        passlen,
+                                                        NULL);
+                       if (tevent_req_nomem(tmp_pass, req)) {
                                return tevent_req_post(req, ev);
                        }
-                       pass = tmp_pass;
+                       pass = (const char *)tmp_pass;
+                       passlen = talloc_get_size(tmp_pass);
                }
        }
 
@@ -2278,7 +2335,7 @@ struct tevent_req *cli_tcon_andx_create(TALLOC_CTX *mem_ctx,
         * Add the sharename
         */
        tmp = talloc_asprintf_strupper_m(talloc_tos(), "\\\\%s\\%s",
-                                        cli->desthost, share);
+                                        smbXcli_conn_remote_name(cli->conn), share);
        if (tmp == NULL) {
                TALLOC_FREE(req);
                return NULL;
@@ -2390,7 +2447,7 @@ static void cli_tcon_andx_done(struct tevent_req *subreq)
                }
        }
 
-       if ((cli->protocol >= PROTOCOL_NT1) && (num_bytes == 3)) {
+       if ((smbXcli_conn_protocol(cli->conn) >= PROTOCOL_NT1) && (num_bytes == 3)) {
                /* almost certainly win95 - enable bug fixes */
                cli->win95 = True;
        }
@@ -2402,11 +2459,11 @@ static void cli_tcon_andx_done(struct tevent_req *subreq)
 
        cli->dfsroot = false;
 
-       if ((wct > 2) && (cli->protocol >= PROTOCOL_LANMAN2)) {
+       if ((wct > 2) && (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_LANMAN2)) {
                cli->dfsroot = ((SVAL(vwv+2, 0) & SMB_SHARE_IN_DFS) != 0);
        }
 
-       cli->cnum = SVAL(inbuf,smb_tid);
+       cli->smb1.tid = SVAL(inbuf,smb_tid);
        tevent_req_done(req);
 }
 
@@ -2454,6 +2511,21 @@ NTSTATUS cli_tcon_andx(struct cli_state *cli, const char *share,
        return status;
 }
 
+NTSTATUS cli_tree_connect(struct cli_state *cli, const char *share,
+                         const char *dev, const char *pass, int passlen)
+{
+       cli->share = talloc_strdup(cli, share);
+       if (!cli->share) {
+               return NT_STATUS_NO_MEMORY;
+       }
+
+       if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) {
+               return smb2cli_tcon(cli, share);
+       }
+
+       return cli_tcon_andx(cli, share, dev, pass, passlen);
+}
+
 /****************************************************************************
  Send a tree disconnect.
 ****************************************************************************/
@@ -2499,7 +2571,7 @@ static void cli_tdis_done(struct tevent_req *subreq)
                tevent_req_nterror(req, status);
                return;
        }
-       state->cli->cnum = -1;
+       state->cli->smb1.tid = UINT16_MAX;
        tevent_req_done(req);
 }
 
@@ -2534,564 +2606,6 @@ fail:
        return status;
 }
 
-/****************************************************************************
- Send a negprot command.
-****************************************************************************/
-
-struct cli_negprot_state {
-       struct cli_state *cli;
-};
-
-static void cli_negprot_done(struct tevent_req *subreq);
-
-struct tevent_req *cli_negprot_send(TALLOC_CTX *mem_ctx,
-                                   struct event_context *ev,
-                                   struct cli_state *cli)
-{
-       struct tevent_req *req, *subreq;
-       struct cli_negprot_state *state;
-       uint8_t *bytes = NULL;
-       int numprots;
-       uint16_t cnum;
-
-       req = tevent_req_create(mem_ctx, &state, struct cli_negprot_state);
-       if (req == NULL) {
-               return NULL;
-       }
-       state->cli = cli;
-
-       if (cli->protocol < PROTOCOL_NT1)
-               cli->use_spnego = False;
-
-       /* setup the protocol strings */
-       for (numprots=0; numprots < ARRAY_SIZE(prots); numprots++) {
-               uint8_t c = 2;
-               if (prots[numprots].prot > cli->protocol) {
-                       break;
-               }
-               bytes = (uint8_t *)talloc_append_blob(
-                       state, bytes, data_blob_const(&c, sizeof(c)));
-               if (tevent_req_nomem(bytes, req)) {
-                       return tevent_req_post(req, ev);
-               }
-               bytes = smb_bytes_push_str(bytes, false,
-                                          prots[numprots].name,
-                                          strlen(prots[numprots].name)+1,
-                                          NULL);
-               if (tevent_req_nomem(bytes, req)) {
-                       return tevent_req_post(req, ev);
-               }
-       }
-
-       cnum = cli->cnum;
-
-       cli->cnum = 0;
-       subreq = cli_smb_send(state, ev, cli, SMBnegprot, 0, 0, NULL,
-                             talloc_get_size(bytes), bytes);
-       cli->cnum = cnum;
-
-       if (tevent_req_nomem(subreq, req)) {
-               return tevent_req_post(req, ev);
-       }
-       tevent_req_set_callback(subreq, cli_negprot_done, req);
-       return req;
-}
-
-static void cli_negprot_done(struct tevent_req *subreq)
-{
-       struct tevent_req *req = tevent_req_callback_data(
-               subreq, struct tevent_req);
-       struct cli_negprot_state *state = tevent_req_data(
-               req, struct cli_negprot_state);
-       struct cli_state *cli = state->cli;
-       uint8_t wct;
-       uint16_t *vwv;
-       uint32_t num_bytes;
-       uint8_t *bytes;
-       NTSTATUS status;
-       uint16_t protnum;
-       uint8_t *inbuf;
-
-       status = cli_smb_recv(subreq, state, &inbuf, 1, &wct, &vwv,
-                             &num_bytes, &bytes);
-       TALLOC_FREE(subreq);
-       if (!NT_STATUS_IS_OK(status)) {
-               tevent_req_nterror(req, status);
-               return;
-       }
-
-       protnum = SVAL(vwv, 0);
-
-       if ((protnum >= ARRAY_SIZE(prots))
-           || (prots[protnum].prot > cli->protocol)) {
-               tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
-               return;
-       }
-
-       cli->protocol = prots[protnum].prot;
-
-       if ((cli->protocol < PROTOCOL_NT1) &&
-           client_is_signing_mandatory(cli)) {
-               DEBUG(0,("cli_negprot: SMB signing is mandatory and the selected protocol level doesn't support it.\n"));
-               tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
-               return;
-       }
-
-       if (cli->protocol >= PROTOCOL_NT1) {    
-               struct timespec ts;
-               bool negotiated_smb_signing = false;
-
-               /* NT protocol */
-               cli->sec_mode = CVAL(vwv + 1, 0);
-               cli->max_mux = SVAL(vwv + 1, 1);
-               cli->max_xmit = IVAL(vwv + 3, 1);
-               cli->sesskey = IVAL(vwv + 7, 1);
-               cli->serverzone = SVALS(vwv + 15, 1);
-               cli->serverzone *= 60;
-               /* this time arrives in real GMT */
-               ts = interpret_long_date(((char *)(vwv+11))+1);
-               cli->servertime = ts.tv_sec;
-               cli->secblob = data_blob(bytes, num_bytes);
-               cli->capabilities = IVAL(vwv + 9, 1);
-               if (cli->capabilities & CAP_RAW_MODE) {
-                       cli->readbraw_supported = True;
-                       cli->writebraw_supported = True;      
-               }
-               /* work out if they sent us a workgroup */
-               if (!(cli->capabilities & CAP_EXTENDED_SECURITY) &&
-                   smb_buflen(inbuf) > 8) {
-                       ssize_t ret;
-                       status = smb_bytes_talloc_string(
-                               cli, (char *)inbuf, &cli->server_domain,
-                               bytes + 8, num_bytes - 8, &ret);
-                       if (tevent_req_nterror(req, status)) {
-                               return;
-                       }
-               }
-
-               /*
-                * As signing is slow we only turn it on if either the client or
-                * the server require it. JRA.
-                */
-
-               if (cli->sec_mode & NEGOTIATE_SECURITY_SIGNATURES_REQUIRED) {
-                       /* Fail if server says signing is mandatory and we don't want to support it. */
-                       if (!client_is_signing_allowed(cli)) {
-                               DEBUG(0,("cli_negprot: SMB signing is mandatory and we have disabled it.\n"));
-                               tevent_req_nterror(req,
-                                                  NT_STATUS_ACCESS_DENIED);
-                               return;
-                       }
-                       negotiated_smb_signing = true;
-               } else if (client_is_signing_mandatory(cli) && client_is_signing_allowed(cli)) {
-                       /* Fail if client says signing is mandatory and the server doesn't support it. */
-                       if (!(cli->sec_mode & NEGOTIATE_SECURITY_SIGNATURES_ENABLED)) {
-                               DEBUG(1,("cli_negprot: SMB signing is mandatory and the server doesn't support it.\n"));
-                               tevent_req_nterror(req,
-                                                  NT_STATUS_ACCESS_DENIED);
-                               return;
-                       }
-                       negotiated_smb_signing = true;
-               } else if (cli->sec_mode & NEGOTIATE_SECURITY_SIGNATURES_ENABLED) {
-                       negotiated_smb_signing = true;
-               }
-
-               if (negotiated_smb_signing) {
-                       cli_set_signing_negotiated(cli);
-               }
-
-               if (cli->capabilities & (CAP_LARGE_READX|CAP_LARGE_WRITEX)) {
-                       SAFE_FREE(cli->outbuf);
-                       SAFE_FREE(cli->inbuf);
-                       cli->outbuf = (char *)SMB_MALLOC(CLI_SAMBA_MAX_LARGE_READX_SIZE+LARGE_WRITEX_HDR_SIZE+SAFETY_MARGIN);
-                       cli->inbuf = (char *)SMB_MALLOC(CLI_SAMBA_MAX_LARGE_READX_SIZE+LARGE_WRITEX_HDR_SIZE+SAFETY_MARGIN);
-                       if (!cli->outbuf || !cli->inbuf) {
-                               tevent_req_nterror(req,
-                                               NT_STATUS_NO_MEMORY);
-                               return;
-                       }
-                       cli->bufsize = CLI_SAMBA_MAX_LARGE_READX_SIZE + LARGE_WRITEX_HDR_SIZE;
-               }
-
-       } else if (cli->protocol >= PROTOCOL_LANMAN1) {
-               cli->use_spnego = False;
-               cli->sec_mode = SVAL(vwv + 1, 0);
-               cli->max_xmit = SVAL(vwv + 2, 0);
-               cli->max_mux = SVAL(vwv + 3, 0);
-               cli->sesskey = IVAL(vwv + 6, 0);
-               cli->serverzone = SVALS(vwv + 10, 0);
-               cli->serverzone *= 60;
-               /* this time is converted to GMT by make_unix_date */
-               cli->servertime = make_unix_date(
-                       (char *)(vwv + 8), cli->serverzone);
-               cli->readbraw_supported = ((SVAL(vwv + 5, 0) & 0x1) != 0);
-               cli->writebraw_supported = ((SVAL(vwv + 5, 0) & 0x2) != 0);
-               cli->secblob = data_blob(bytes, num_bytes);
-       } else {
-               /* the old core protocol */
-               cli->use_spnego = False;
-               cli->sec_mode = 0;
-               cli->serverzone = get_time_zone(time(NULL));
-       }
-
-       cli->max_xmit = MIN(cli->max_xmit, CLI_BUFFER_SIZE);
-
-       /* a way to force ascii SMB */
-       if (getenv("CLI_FORCE_ASCII"))
-               cli->capabilities &= ~CAP_UNICODE;
-
-       tevent_req_done(req);
-}
-
-NTSTATUS cli_negprot_recv(struct tevent_req *req)
-{
-       return tevent_req_simple_recv_ntstatus(req);
-}
-
-NTSTATUS cli_negprot(struct cli_state *cli)
-{
-       TALLOC_CTX *frame = talloc_stackframe();
-       struct event_context *ev;
-       struct tevent_req *req;
-       NTSTATUS status = NT_STATUS_OK;
-
-       if (cli_has_async_calls(cli)) {
-               /*
-                * Can't use sync call while an async call is in flight
-                */
-               status = NT_STATUS_INVALID_PARAMETER;
-               goto fail;
-       }
-
-       ev = event_context_init(frame);
-       if (ev == NULL) {
-               status = NT_STATUS_NO_MEMORY;
-               goto fail;
-       }
-
-       req = cli_negprot_send(frame, ev, cli);
-       if (req == NULL) {
-               status = NT_STATUS_NO_MEMORY;
-               goto fail;
-       }
-
-       if (!tevent_req_poll(req, ev)) {
-               status = map_nt_error_from_unix(errno);
-               goto fail;
-       }
-
-       status = cli_negprot_recv(req);
- fail:
-       TALLOC_FREE(frame);
-       return status;
-}
-
-/****************************************************************************
- Send a session request. See rfc1002.txt 4.3 and 4.3.2.
-****************************************************************************/
-
-bool cli_session_request(struct cli_state *cli,
-                        struct nmb_name *calling, struct nmb_name *called)
-{
-       TALLOC_CTX *frame;
-       uint8_t len_buf[4];
-       struct iovec iov[3];
-       ssize_t len;
-       uint8_t *inbuf;
-       int err;
-       bool ret = false;
-
-       /* 445 doesn't have session request */
-       if (cli->port == 445)
-               return True;
-
-       memcpy(&(cli->calling), calling, sizeof(*calling));
-       memcpy(&(cli->called ), called , sizeof(*called ));
-
-       /* put in the destination name */
-
-       frame = talloc_stackframe();
-
-       iov[0].iov_base = len_buf;
-       iov[0].iov_len  = sizeof(len_buf);
-
-       /* put in the destination name */
-
-       iov[1].iov_base = name_mangle(talloc_tos(), called->name,
-                                     called->name_type);
-       if (iov[1].iov_base == NULL) {
-               goto fail;
-       }
-       iov[1].iov_len = name_len((unsigned char *)iov[1].iov_base,
-                                 talloc_get_size(iov[1].iov_base));
-
-       /* and my name */
-
-       iov[2].iov_base = name_mangle(talloc_tos(), calling->name,
-                                     calling->name_type);
-       if (iov[2].iov_base == NULL) {
-               goto fail;
-       }
-       iov[2].iov_len = name_len((unsigned char *)iov[2].iov_base,
-                                 talloc_get_size(iov[2].iov_base));
-
-       /* send a session request (RFC 1002) */
-       /* setup the packet length
-         * Remove four bytes from the length count, since the length
-         * field in the NBT Session Service header counts the number
-         * of bytes which follow.  The cli_send_smb() function knows
-         * about this and accounts for those four bytes.
-         * CRH.
-         */
-
-       _smb_setlen(len_buf, iov[1].iov_len + iov[2].iov_len);
-       SCVAL(len_buf,0,0x81);
-
-       len = write_data_iov(cli->fd, iov, 3);
-       if (len == -1) {
-               goto fail;
-       }
-       len = read_smb(cli->fd, talloc_tos(), &inbuf, &err);
-       if (len == -1) {
-               errno = err;
-               goto fail;
-       }
-
-       if (CVAL(inbuf,0) == 0x84) {
-               /* C. Hoch  9/14/95 Start */
-               /* For information, here is the response structure.
-                * We do the byte-twiddling to for portability.
-               struct RetargetResponse{
-               unsigned char type;
-               unsigned char flags;
-               int16 length;
-               int32 ip_addr;
-               int16 port;
-               };
-               */
-               uint16_t port = (CVAL(inbuf,8)<<8)+CVAL(inbuf,9);
-               struct in_addr dest_ip;
-               NTSTATUS status;
-
-               /* SESSION RETARGET */
-               putip((char *)&dest_ip,inbuf+4);
-               in_addr_to_sockaddr_storage(&cli->dest_ss, dest_ip);
-
-               status = open_socket_out(&cli->dest_ss, port,
-                                        LONG_CONNECT_TIMEOUT, &cli->fd);
-               if (!NT_STATUS_IS_OK(status)) {
-                       goto fail;
-               }
-
-               DEBUG(3,("Retargeted\n"));
-
-               set_socket_options(cli->fd, lp_socket_options());
-
-               /* Try again */
-               {
-                       static int depth;
-                       if (depth > 4) {
-                               DEBUG(0,("Retarget recursion - failing\n"));
-                               goto fail;
-                       }
-                       depth++;
-                       ret = cli_session_request(cli, calling, called);
-                       depth--;
-                       goto done;
-               }
-       } /* C. Hoch 9/14/95 End */
-
-       if (CVAL(inbuf,0) != 0x82) {
-                /* This is the wrong place to put the error... JRA. */
-               cli->rap_error = CVAL(inbuf,4);
-               goto fail;
-       }
-done:
-       ret = true;
-fail:
-       err = errno;
-       TALLOC_FREE(frame);
-       errno = err;
-       return ret;
-}
-
-struct fd_struct {
-       int fd;
-};
-
-static void smb_sock_connected(struct tevent_req *req)
-{
-       struct fd_struct *pfd = tevent_req_callback_data(
-               req, struct fd_struct);
-       int fd;
-       NTSTATUS status;
-
-       status = open_socket_out_defer_recv(req, &fd);
-       if (NT_STATUS_IS_OK(status)) {
-               pfd->fd = fd;
-       }
-}
-
-static NTSTATUS open_smb_socket(const struct sockaddr_storage *pss,
-                               uint16_t *port, int timeout, int *pfd)
-{
-       struct event_context *ev;
-       struct tevent_req *r139, *r445;
-       struct fd_struct *fd139, *fd445;
-       NTSTATUS status = NT_STATUS_NO_MEMORY;
-
-       if (*port != 0) {
-               return open_socket_out(pss, *port, timeout, pfd);
-       }
-
-       ev = event_context_init(talloc_tos());
-       if (ev == NULL) {
-               return NT_STATUS_NO_MEMORY;
-       }
-
-       fd139 = talloc(ev, struct fd_struct);
-       if (fd139 == NULL) {
-               goto done;
-       }
-       fd139->fd = -1;
-
-       fd445 = talloc(ev, struct fd_struct);
-       if (fd445 == NULL) {
-               goto done;
-       }
-       fd445->fd = -1;
-
-       r445 = open_socket_out_defer_send(ev, ev, timeval_set(0, 0),
-                                         pss, 445, timeout);
-       r139 = open_socket_out_defer_send(ev, ev, timeval_set(0, 3000),
-                                         pss, 139, timeout);
-       if ((r445 == NULL) || (r139 == NULL)) {
-               goto done;
-       }
-       tevent_req_set_callback(r445, smb_sock_connected, fd445);
-       tevent_req_set_callback(r139, smb_sock_connected, fd139);
-
-       while ((fd445->fd == -1) && (fd139->fd == -1)
-              && (tevent_req_is_in_progress(r139)
-                  || tevent_req_is_in_progress(r445))) {
-               event_loop_once(ev);
-       }
-
-       if ((fd139->fd != -1) && (fd445->fd != -1)) {
-               close(fd139->fd);
-               fd139->fd = -1;
-       }
-
-       if (fd445->fd != -1) {
-               *port = 445;
-               *pfd = fd445->fd;
-               status = NT_STATUS_OK;
-               goto done;
-       }
-       if (fd139->fd != -1) {
-               *port = 139;
-               *pfd = fd139->fd;
-               status = NT_STATUS_OK;
-               goto done;
-       }
-
-       status = open_socket_out_defer_recv(r445, &fd445->fd);
- done:
-       TALLOC_FREE(ev);
-       return status;
-}
-
-/****************************************************************************
- Open the client sockets.
-****************************************************************************/
-
-NTSTATUS cli_connect(struct cli_state *cli,
-               const char *host,
-               struct sockaddr_storage *dest_ss)
-
-{
-       int name_type = 0x20;
-       TALLOC_CTX *frame = talloc_stackframe();
-       unsigned int num_addrs = 0;
-       unsigned int i = 0;
-       struct sockaddr_storage *ss_arr = NULL;
-       char *p = NULL;
-
-       /* reasonable default hostname */
-       if (!host) {
-               host = STAR_SMBSERVER;
-       }
-
-       cli->desthost = talloc_strdup(cli, host);
-       if (cli->desthost == NULL) {
-               return NT_STATUS_NO_MEMORY;
-       }
-
-       /* allow hostnames of the form NAME#xx and do a netbios lookup */
-       if ((p = strchr(cli->desthost, '#'))) {
-               name_type = strtol(p+1, NULL, 16);
-               *p = 0;
-       }
-
-       if (!dest_ss || is_zero_addr(dest_ss)) {
-               NTSTATUS status =resolve_name_list(frame,
-                                       cli->desthost,
-                                       name_type,
-                                       &ss_arr,
-                                       &num_addrs);
-               if (!NT_STATUS_IS_OK(status)) {
-                       TALLOC_FREE(frame);
-                       return NT_STATUS_BAD_NETWORK_NAME;
-                }
-       } else {
-               num_addrs = 1;
-               ss_arr = TALLOC_P(frame, struct sockaddr_storage);
-               if (!ss_arr) {
-                       TALLOC_FREE(frame);
-                       return NT_STATUS_NO_MEMORY;
-               }
-               *ss_arr = *dest_ss;
-       }
-
-       for (i = 0; i < num_addrs; i++) {
-               cli->dest_ss = ss_arr[i];
-               if (getenv("LIBSMB_PROG")) {
-                       cli->fd = sock_exec(getenv("LIBSMB_PROG"));
-               } else {
-                       uint16_t port = cli->port;
-                       NTSTATUS status;
-                       status = open_smb_socket(&cli->dest_ss, &port,
-                                                cli->timeout, &cli->fd);
-                       if (NT_STATUS_IS_OK(status)) {
-                               cli->port = port;
-                       }
-               }
-               if (cli->fd == -1) {
-                       char addr[INET6_ADDRSTRLEN];
-                       print_sockaddr(addr, sizeof(addr), &ss_arr[i]);
-                       DEBUG(2,("Error connecting to %s (%s)\n",
-                                dest_ss?addr:host,strerror(errno)));
-               } else {
-                       /* Exit from loop on first connection. */
-                       break;
-               }
-       }
-
-       if (cli->fd == -1) {
-               TALLOC_FREE(frame);
-               return map_nt_error_from_unix(errno);
-       }
-
-       if (dest_ss) {
-               *dest_ss = cli->dest_ss;
-       }
-
-       set_socket_options(cli->fd, lp_socket_options());
-
-       TALLOC_FREE(frame);
-       return NT_STATUS_OK;
-}
-
 static NTSTATUS cli_connect_sock(const char *host, int name_type,
                                 const struct sockaddr_storage *pss,
                                 const char *myname, uint16_t port,
@@ -3154,6 +2668,7 @@ static NTSTATUS cli_connect_sock(const char *host, int name_type,
        if (!NT_STATUS_IS_OK(status)) {
                goto fail;
        }
+       set_socket_options(fd, lp_socket_options());
 done:
        *pfd = fd;
        *pport = port;
@@ -3163,9 +2678,9 @@ fail:
        return status;
 }
 
-NTSTATUS cli_connect_nb(const char *host, struct sockaddr_storage *pss,
+NTSTATUS cli_connect_nb(const char *host, const struct sockaddr_storage *dest_ss,
                        uint16_t port, int name_type, const char *myname,
-                       int signing_state, struct cli_state **pcli)
+                       int signing_state, int flags, struct cli_state **pcli)
 {
        TALLOC_CTX *frame = talloc_stackframe();
        struct cli_state *cli;
@@ -3173,8 +2688,6 @@ NTSTATUS cli_connect_nb(const char *host, struct sockaddr_storage *pss,
        int fd = -1;
        char *desthost;
        char *p;
-       socklen_t length;
-       int ret;
 
        desthost = talloc_strdup(talloc_tos(), host);
        if (desthost == NULL) {
@@ -3190,34 +2703,19 @@ NTSTATUS cli_connect_nb(const char *host, struct sockaddr_storage *pss,
                }
        }
 
-       cli = cli_initialise_ex(signing_state);
-       if (cli == NULL) {
-               goto fail;
-       }
-       cli->desthost = talloc_move(cli, &desthost);
-
-       status = cli_connect_sock(host, name_type, pss, myname, port, 20, &fd,
-                                 &port);
+       status = cli_connect_sock(host, name_type, dest_ss, myname, port,
+                                 20, &fd, &port);
        if (!NT_STATUS_IS_OK(status)) {
-               cli_shutdown(cli);
                goto fail;
        }
-       cli->fd = fd;
-       cli->port = port;
 
-       length = sizeof(cli->dest_ss);
-       ret = getpeername(fd, (struct sockaddr *)(void *)&cli->dest_ss,
-                         &length);
-       if (ret == -1) {
-               status = map_nt_error_from_unix(errno);
-               cli_shutdown(cli);
+       cli = cli_state_create(NULL, fd, desthost, NULL, signing_state, flags);
+       if (cli == NULL) {
+               close(fd);
+               fd = -1;
                goto fail;
        }
 
-       if (pss != NULL) {
-               *pss = cli->dest_ss;
-       }
-
        *pcli = cli;
        status = NT_STATUS_OK;
 fail:
@@ -3235,34 +2733,22 @@ fail:
 NTSTATUS cli_start_connection(struct cli_state **output_cli, 
                              const char *my_name, 
                              const char *dest_host, 
-                             struct sockaddr_storage *dest_ss, int port,
+                             const struct sockaddr_storage *dest_ss, int port,
                              int signing_state, int flags)
 {
        NTSTATUS nt_status;
        struct cli_state *cli;
 
        nt_status = cli_connect_nb(dest_host, dest_ss, port, 0x20, my_name,
-                                  signing_state, &cli);
+                                  signing_state, flags, &cli);
        if (!NT_STATUS_IS_OK(nt_status)) {
                DEBUG(10, ("cli_connect_nb failed: %s\n",
                           nt_errstr(nt_status)));
                return nt_status;
        }
 
-       if (flags & CLI_FULL_CONNECTION_DONT_SPNEGO)
-               cli->use_spnego = False;
-       else if (flags & CLI_FULL_CONNECTION_USE_KERBEROS)
-               cli->use_kerberos = True;
-
-       if ((flags & CLI_FULL_CONNECTION_FALLBACK_AFTER_KERBEROS) &&
-            cli->use_kerberos) {
-               cli->fallback_after_kerberos = true;
-       }
-       if (flags & CLI_FULL_CONNECTION_USE_CCACHE) {
-               cli->use_ccache = true;
-       }
-
-       nt_status = cli_negprot(cli);
+       nt_status = smbXcli_negprot(cli->conn, cli->timeout, PROTOCOL_CORE,
+                                   PROTOCOL_NT1);
        if (!NT_STATUS_IS_OK(nt_status)) {
                DEBUG(1, ("failed negprot: %s\n", nt_errstr(nt_status)));
                cli_shutdown(cli);
@@ -3290,7 +2776,7 @@ NTSTATUS cli_start_connection(struct cli_state **output_cli,
 NTSTATUS cli_full_connection(struct cli_state **output_cli, 
                             const char *my_name, 
                             const char *dest_host, 
-                            struct sockaddr_storage *dest_ss, int port,
+                            const struct sockaddr_storage *dest_ss, int port,
                             const char *service, const char *service_type,
                             const char *user, const char *domain, 
                             const char *password, int flags,
@@ -3314,10 +2800,6 @@ NTSTATUS cli_full_connection(struct cli_state **output_cli,
                return nt_status;
        }
 
-       cli->use_oplocks = ((flags & CLI_FULL_CONNECTION_OPLOCKS) != 0);
-       cli->use_level_II_oplocks =
-               ((flags & CLI_FULL_CONNECTION_LEVEL_II_OPLOCKS) != 0);
-
        nt_status = cli_session_setup(cli, user, password, pw_len, password,
                                      pw_len, domain);
        if (!NT_STATUS_IS_OK(nt_status)) {
@@ -3361,71 +2843,6 @@ NTSTATUS cli_full_connection(struct cli_state **output_cli,
        return NT_STATUS_OK;
 }
 
-/****************************************************************************
- Attempt a NetBIOS session request, falling back to *SMBSERVER if needed.
-****************************************************************************/
-
-bool attempt_netbios_session_request(struct cli_state **ppcli, const char *srchost, const char *desthost,
-                                     struct sockaddr_storage *pdest_ss)
-{
-       struct nmb_name calling, called;
-
-       make_nmb_name(&calling, srchost, 0x0);
-
-       /*
-        * If the called name is an IP address
-        * then use *SMBSERVER immediately.
-        */
-
-       if(is_ipaddress(desthost)) {
-               make_nmb_name(&called, STAR_SMBSERVER, 0x20);
-       } else {
-               make_nmb_name(&called, desthost, 0x20);
-       }
-
-       if (!cli_session_request(*ppcli, &calling, &called)) {
-               NTSTATUS status;
-               struct nmb_name smbservername;
-
-               make_nmb_name(&smbservername, STAR_SMBSERVER, 0x20);
-
-               /*
-                * If the name wasn't *SMBSERVER then
-                * try with *SMBSERVER if the first name fails.
-                */
-
-               if (nmb_name_equal(&called, &smbservername)) {
-
-                       /*
-                        * The name used was *SMBSERVER, don't bother with another name.
-                        */
-
-                       DEBUG(0,("attempt_netbios_session_request: %s rejected the session for name *SMBSERVER \
-with error %s.\n", desthost, cli_errstr(*ppcli) ));
-                       return False;
-               }
-
-               /* Try again... */
-               cli_shutdown(*ppcli);
-
-               *ppcli = cli_initialise();
-               if (!*ppcli) {
-                       /* Out of memory... */
-                       return False;
-               }
-
-               status = cli_connect(*ppcli, desthost, pdest_ss);
-               if (!NT_STATUS_IS_OK(status) ||
-                               !cli_session_request(*ppcli, &calling, &smbservername)) {
-                       DEBUG(0,("attempt_netbios_session_request: %s rejected the session for \
-name *SMBSERVER with error %s\n", desthost, cli_errstr(*ppcli) ));
-                       return False;
-               }
-       }
-
-       return True;
-}
-
 /****************************************************************************
  Send an old style tcon.
 ****************************************************************************/
@@ -3487,7 +2904,7 @@ struct cli_state *get_ipc_connect(char *server,
                                        lp_workgroup(),
                                        user_info->password ? user_info->password : "",
                                        flags,
-                                       Undefined);
+                                       SMB_SIGNING_DEFAULT);
 
        if (NT_STATUS_IS_OK(nt_status)) {
                return cli;
@@ -3591,7 +3008,7 @@ struct cli_state *get_ipc_connect_master_ip_bcast(TALLOC_CTX *ctx,
         if (!NT_STATUS_IS_OK(status)) {
                 DEBUG(99, ("No master browsers responded: %s\n",
                           nt_errstr(status)));
-                return False;
+                return NULL;
         }
 
        for (i = 0; i < count; i++) {