Ignore:
Timestamp:
Nov 24, 2016, 1:14:11 PM (9 years ago)
Author:
Silvan Scherrer
Message:

Samba Server: update vendor to version 4.4.3

File:
1 edited

Legend:

Unmodified
Added
Removed
  • vendor/current/source3/libsmb/cliconnect.c

    r919 r988  
    2323#include "includes.h"
    2424#include "libsmb/libsmb.h"
    25 #include "popt_common.h"
     25#include "auth_info.h"
    2626#include "../libcli/auth/libcli_auth.h"
    2727#include "../libcli/auth/spnego.h"
    2828#include "smb_krb5.h"
    29 #include "../libcli/auth/ntlmssp.h"
     29#include "auth/credentials/credentials.h"
     30#include "auth/gensec/gensec.h"
     31#include "auth/ntlmssp/ntlmssp.h"
     32#include "auth_generic.h"
    3033#include "libads/kerberos_proto.h"
    3134#include "krb5_env.h"
     
    3336#include "async_smb.h"
    3437#include "libsmb/nmblib.h"
    35 
    36 static const struct {
    37         int prot;
    38         const char name[24];
    39 } prots[10] = {
    40         {PROTOCOL_CORE,         "PC NETWORK PROGRAM 1.0"},
    41         {PROTOCOL_COREPLUS,     "MICROSOFT NETWORKS 1.03"},
    42         {PROTOCOL_LANMAN1,      "MICROSOFT NETWORKS 3.0"},
    43         {PROTOCOL_LANMAN1,      "LANMAN1.0"},
    44         {PROTOCOL_LANMAN2,      "LM1.2X002"},
    45         {PROTOCOL_LANMAN2,      "DOS LANMAN2.1"},
    46         {PROTOCOL_LANMAN2,      "LANMAN2.1"},
    47         {PROTOCOL_LANMAN2,      "Samba"},
    48         {PROTOCOL_NT1,          "NT LANMAN 1.0"},
    49         {PROTOCOL_NT1,          "NT LM 0.12"},
    50 };
     38#include "librpc/ndr/libndr.h"
     39#include "../libcli/smb/smbXcli_base.h"
    5140
    5241#define STAR_SMBSERVER "*SMBSERVER"
     
    5948*******************************************************/
    6049
    61 static NTSTATUS smb_bytes_talloc_string(struct cli_state *cli,
    62                                         char *inbuf,
     50static NTSTATUS smb_bytes_talloc_string(TALLOC_CTX *mem_ctx,
     51                                        const uint8_t *hdr,
    6352                                        char **dest,
    6453                                        uint8_t *src,
     
    6655                                        ssize_t *destlen)
    6756{
    68         *destlen = clistr_pull_talloc(cli,
    69                                 inbuf,
    70                                 SVAL(inbuf, smb_flg2),
     57        *destlen = clistr_pull_talloc(mem_ctx,
     58                                (const char *)hdr,
     59                                SVAL(hdr, HDR_FLG2),
    7160                                dest,
    7261                                (char *)src,
     
    7867
    7968        if (*dest == NULL) {
    80                 *dest = talloc_strdup(cli, "");
     69                *dest = talloc_strdup(mem_ctx, "");
    8170                if (*dest == NULL) {
    8271                        return NT_STATUS_NO_MEMORY;
     
    8473        }
    8574        return NT_STATUS_OK;
    86 }
    87 
    88 /**
    89  * Set the user session key for a connection
    90  * @param cli The cli structure to add it too
    91  * @param session_key The session key used.  (A copy of this is taken for the cli struct)
    92  *
    93  */
    94 
    95 static void cli_set_session_key (struct cli_state *cli, const DATA_BLOB session_key)
    96 {
    97         cli->user_session_key = data_blob(NULL, 16);
    98         data_blob_clear(&cli->user_session_key);
    99         memcpy(cli->user_session_key.data, session_key.data, MIN(session_key.length, 16));
    10075}
    10176
     
    12499        uint8_t *bytes;
    125100        char *tmp;
     101        uint16_t sec_mode = smb1cli_conn_server_security_mode(cli->conn);
    126102
    127103        req = tevent_req_create(mem_ctx, &state,
     
    135111
    136112        /*
    137          * LANMAN servers predate NT status codes and Unicode and
    138          * ignore those smb flags so we must disable the corresponding
    139          * default capabilities that would otherwise cause the Unicode
    140          * and NT Status flags to be set (and even returned by the
    141          * server)
    142          */
    143 
    144         cli->capabilities &= ~(CAP_UNICODE | CAP_STATUS32);
    145 
    146         /*
    147113         * if in share level security then don't send a password now
    148114         */
    149         if (!(cli->sec_mode & NEGOTIATE_SECURITY_USER_LEVEL)) {
     115        if (!(sec_mode & NEGOTIATE_SECURITY_USER_LEVEL)) {
    150116                passlen = 0;
    151117        }
    152118
    153119        if (passlen > 0
    154             && (cli->sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE)
     120            && (sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE)
    155121            && passlen != 24) {
    156122                /*
     
    163129                }
    164130
    165                 if (!SMBencrypt(pass, cli->secblob.data,
     131                if (!SMBencrypt(pass, smb1cli_conn_server_challenge(cli->conn),
    166132                                (uint8_t *)lm_response.data)) {
    167133                        DEBUG(1, ("Password is > 14 chars in length, and is "
     
    171137                        return tevent_req_post(req, ev);
    172138                }
    173         } else if ((cli->sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE)
     139        } else if ((sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE)
    174140                   && passlen == 24) {
    175141                /*
     
    188154                 */
    189155                buf = talloc_array(talloc_tos(), uint8_t, 0);
    190                 buf = smb_bytes_push_str(buf, cli_ucs2(cli), pass, passlen+1,
     156                buf = smb_bytes_push_str(buf, smbXcli_conn_use_unicode(cli->conn), pass, passlen+1,
    191157                                         &converted_size);
    192158                if (tevent_req_nomem(buf, req)) {
     
    206172        SSVAL(vwv+3, 0, 2);
    207173        SSVAL(vwv+4, 0, 1);
    208         SIVAL(vwv+5, 0, cli->sesskey);
     174        SIVAL(vwv+5, 0, smb1cli_conn_server_session_key(cli->conn));
    209175        SSVAL(vwv+7, 0, lm_response.length);
    210176
     
    222188                return tevent_req_post(req, ev);
    223189        }
    224         bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), tmp, strlen(tmp)+1,
     190        bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn), tmp, strlen(tmp)+1,
    225191                                   NULL);
    226192        TALLOC_FREE(tmp);
     
    230196                return tevent_req_post(req, ev);
    231197        }
    232         bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), tmp, strlen(tmp)+1,
     198        bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn), tmp, strlen(tmp)+1,
    233199                                   NULL);
    234         bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), "Unix", 5, NULL);
    235         bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), "Samba", 6, NULL);
     200        bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn), "Unix", 5, NULL);
     201        bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn), "Samba", 6, NULL);
    236202
    237203        if (tevent_req_nomem(bytes, req)) {
     
    257223        uint32_t num_bytes;
    258224        uint8_t *in;
    259         char *inbuf;
     225        uint8_t *inhdr;
    260226        uint8_t *bytes;
    261227        uint8_t *p;
     
    273239        }
    274240
    275         inbuf = (char *)in;
     241        inhdr = in + NBT_HDR_SIZE;
    276242        p = bytes;
    277243
    278         cli->vuid = SVAL(inbuf, smb_uid);
    279         cli->is_guestlogin = ((SVAL(vwv+2, 0) & 1) != 0);
     244        cli_state_set_uid(state->cli, SVAL(inhdr, HDR_UID));
     245        smb1cli_session_set_action(cli->smb1.session, SVAL(vwv+2, 0));
    280246
    281247        status = smb_bytes_talloc_string(cli,
    282                                         inbuf,
     248                                        inhdr,
    283249                                        &cli->server_os,
    284250                                        p,
     
    293259
    294260        status = smb_bytes_talloc_string(cli,
    295                                         inbuf,
     261                                        inhdr,
    296262                                        &cli->server_type,
    297263                                        p,
     
    306272
    307273        status = smb_bytes_talloc_string(cli,
    308                                         inbuf,
     274                                        inhdr,
    309275                                        &cli->server_domain,
    310276                                        p,
     
    318284        p += ret;
    319285
    320         if (strstr(cli->server_type, "Samba")) {
    321                 cli->is_samba = True;
    322         }
    323         status = cli_set_username(cli, state->user);
    324         if (tevent_req_nterror(req, status)) {
    325                 return;
    326         }
    327286        tevent_req_done(req);
    328287}
     
    331290{
    332291        return tevent_req_simple_recv_ntstatus(req);
    333 }
    334 
    335 static NTSTATUS cli_session_setup_lanman2(struct cli_state *cli, const char *user,
    336                                           const char *pass, size_t passlen,
    337                                           const char *workgroup)
    338 {
    339         TALLOC_CTX *frame = talloc_stackframe();
    340         struct event_context *ev;
    341         struct tevent_req *req;
    342         NTSTATUS status = NT_STATUS_NO_MEMORY;
    343 
    344         if (cli_has_async_calls(cli)) {
    345                 /*
    346                  * Can't use sync call while an async call is in flight
    347                  */
    348                 status = NT_STATUS_INVALID_PARAMETER;
    349                 goto fail;
    350         }
    351         ev = event_context_init(frame);
    352         if (ev == NULL) {
    353                 goto fail;
    354         }
    355         req = cli_session_setup_lanman2_send(frame, ev, cli, user, pass, passlen,
    356                                              workgroup);
    357         if (req == NULL) {
    358                 goto fail;
    359         }
    360         if (!tevent_req_poll_ntstatus(req, ev, &status)) {
    361                 goto fail;
    362         }
    363         status = cli_session_setup_lanman2_recv(req);
    364  fail:
    365         TALLOC_FREE(frame);
    366         return status;
    367292}
    368293
     
    371296****************************************************************************/
    372297
    373 static uint32 cli_session_setup_capabilities(struct cli_state *cli)
    374 {
    375         uint32 capabilities = CAP_NT_SMBS;
    376 
    377         if (!cli->force_dos_errors)
    378                 capabilities |= CAP_STATUS32;
    379 
    380         if (cli->use_level_II_oplocks)
    381                 capabilities |= CAP_LEVEL_II_OPLOCKS;
    382 
    383         capabilities |= (cli->capabilities & (CAP_UNICODE|CAP_LARGE_FILES|CAP_LARGE_READX|CAP_LARGE_WRITEX|CAP_DFS));
    384         return capabilities;
     298static uint32_t cli_session_setup_capabilities(struct cli_state *cli,
     299                                               uint32_t sesssetup_capabilities)
     300{
     301        uint32_t client_capabilities = smb1cli_conn_capabilities(cli->conn);
     302
     303        /*
     304         * We only send capabilities based on the mask for:
     305         * - client only flags
     306         * - flags used in both directions
     307         *
     308         * We do not echo the server only flags, except some legacy flags.
     309         *
     310         * SMB_CAP_LEGACY_CLIENT_MASK contains CAP_LARGE_READX and
     311         * CAP_LARGE_WRITEX in order to allow us to do large reads
     312         * against old Samba releases (<= 3.6.x).
     313         */
     314        client_capabilities &= (SMB_CAP_BOTH_MASK | SMB_CAP_LEGACY_CLIENT_MASK);
     315
     316        /*
     317         * Session Setup specific flags CAP_DYNAMIC_REAUTH
     318         * and CAP_EXTENDED_SECURITY are passed by the caller.
     319         * We need that in order to do guest logins even if
     320         * CAP_EXTENDED_SECURITY is negotiated.
     321         */
     322        client_capabilities &= ~(CAP_DYNAMIC_REAUTH|CAP_EXTENDED_SECURITY);
     323        sesssetup_capabilities &= (CAP_DYNAMIC_REAUTH|CAP_EXTENDED_SECURITY);
     324        client_capabilities |= sesssetup_capabilities;
     325
     326        return client_capabilities;
    385327}
    386328
     
    398340
    399341struct tevent_req *cli_session_setup_guest_create(TALLOC_CTX *mem_ctx,
    400                                                   struct event_context *ev,
     342                                                  struct tevent_context *ev,
    401343                                                  struct cli_state *cli,
    402344                                                  struct tevent_req **psmbreq)
     
    420362        SSVAL(vwv+2, 0, CLI_BUFFER_SIZE);
    421363        SSVAL(vwv+3, 0, 2);
    422         SSVAL(vwv+4, 0, cli->pid);
    423         SIVAL(vwv+5, 0, cli->sesskey);
     364        SSVAL(vwv+4, 0, cli_state_get_vc_num(cli));
     365        SIVAL(vwv+5, 0, smb1cli_conn_server_session_key(cli->conn));
    424366        SSVAL(vwv+7, 0, 0);
    425367        SSVAL(vwv+8, 0, 0);
    426368        SSVAL(vwv+9, 0, 0);
    427369        SSVAL(vwv+10, 0, 0);
    428         SIVAL(vwv+11, 0, cli_session_setup_capabilities(cli));
     370        SIVAL(vwv+11, 0, cli_session_setup_capabilities(cli, 0));
    429371
    430372        bytes = talloc_array(state, uint8_t, 0);
    431373
    432         bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), "",  1, /* username */
     374        bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn), "",  1, /* username */
    433375                                   NULL);
    434         bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), "", 1, /* workgroup */
     376        bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn), "", 1, /* workgroup */
    435377                                   NULL);
    436         bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), "Unix", 5, NULL);
    437         bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), "Samba", 6, NULL);
     378        bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn), "Unix", 5, NULL);
     379        bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn), "Samba", 6, NULL);
    438380
    439381        if (bytes == NULL) {
     
    457399
    458400struct tevent_req *cli_session_setup_guest_send(TALLOC_CTX *mem_ctx,
    459                                                 struct event_context *ev,
     401                                                struct tevent_context *ev,
    460402                                                struct cli_state *cli)
    461403{
     
    468410        }
    469411
    470         status = cli_smb_req_send(subreq);
    471         if (NT_STATUS_IS_OK(status)) {
     412        status = smb1cli_req_chain_submit(&subreq, 1);
     413        if (!NT_STATUS_IS_OK(status)) {
    472414                tevent_req_nterror(req, status);
    473415                return tevent_req_post(req, ev);
     
    485427        uint32_t num_bytes;
    486428        uint8_t *in;
    487         char *inbuf;
     429        uint8_t *inhdr;
    488430        uint8_t *bytes;
    489431        uint8_t *p;
     
    501443        }
    502444
    503         inbuf = (char *)in;
     445        inhdr = in + NBT_HDR_SIZE;
    504446        p = bytes;
    505447
    506         cli->vuid = SVAL(inbuf, smb_uid);
    507         cli->is_guestlogin = ((SVAL(vwv+2, 0) & 1) != 0);
     448        cli_state_set_uid(state->cli, SVAL(inhdr, HDR_UID));
     449        smb1cli_session_set_action(cli->smb1.session, SVAL(vwv+2, 0));
    508450
    509451        status = smb_bytes_talloc_string(cli,
    510                                         inbuf,
     452                                        inhdr,
    511453                                        &cli->server_os,
    512454                                        p,
     
    521463
    522464        status = smb_bytes_talloc_string(cli,
    523                                         inbuf,
     465                                        inhdr,
    524466                                        &cli->server_type,
    525467                                        p,
     
    534476
    535477        status = smb_bytes_talloc_string(cli,
    536                                         inbuf,
     478                                        inhdr,
    537479                                        &cli->server_domain,
    538480                                        p,
     
    546488        p += ret;
    547489
    548         if (strstr(cli->server_type, "Samba")) {
    549                 cli->is_samba = True;
    550         }
    551 
    552         status = cli_set_username(cli, "");
    553         if (!NT_STATUS_IS_OK(status)) {
    554                 tevent_req_nterror(req, status);
    555                 return;
    556         }
    557490        tevent_req_done(req);
    558491}
     
    561494{
    562495        return tevent_req_simple_recv_ntstatus(req);
    563 }
    564 
    565 static NTSTATUS cli_session_setup_guest(struct cli_state *cli)
    566 {
    567         TALLOC_CTX *frame = talloc_stackframe();
    568         struct event_context *ev;
    569         struct tevent_req *req;
    570         NTSTATUS status = NT_STATUS_OK;
    571 
    572         if (cli_has_async_calls(cli)) {
    573                 /*
    574                  * Can't use sync call while an async call is in flight
    575                  */
    576                 status = NT_STATUS_INVALID_PARAMETER;
    577                 goto fail;
    578         }
    579 
    580         ev = event_context_init(frame);
    581         if (ev == NULL) {
    582                 status = NT_STATUS_NO_MEMORY;
    583                 goto fail;
    584         }
    585 
    586         req = cli_session_setup_guest_send(frame, ev, cli);
    587         if (req == NULL) {
    588                 status = NT_STATUS_NO_MEMORY;
    589                 goto fail;
    590         }
    591 
    592         if (!tevent_req_poll(req, ev)) {
    593                 status = map_nt_error_from_unix(errno);
    594                 goto fail;
    595         }
    596 
    597         status = cli_session_setup_guest_recv(req);
    598  fail:
    599         TALLOC_FREE(frame);
    600         return status;
    601496}
    602497
     
    639534        SSVAL(vwv+2, 0, CLI_BUFFER_SIZE);
    640535        SSVAL(vwv+3, 0, 2);
    641         SSVAL(vwv+4, 0, cli->pid);
    642         SIVAL(vwv+5, 0, cli->sesskey);
     536        SSVAL(vwv+4, 0, cli_state_get_vc_num(cli));
     537        SIVAL(vwv+5, 0, smb1cli_conn_server_session_key(cli->conn));
    643538        SSVAL(vwv+7, 0, 0);
    644539        SSVAL(vwv+8, 0, 0);
    645540        SSVAL(vwv+9, 0, 0);
    646541        SSVAL(vwv+10, 0, 0);
    647         SIVAL(vwv+11, 0, cli_session_setup_capabilities(cli));
     542        SIVAL(vwv+11, 0, cli_session_setup_capabilities(cli, 0));
    648543
    649544        bytes = talloc_array(state, uint8_t, 0);
    650         bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), pass, strlen(pass)+1,
     545        bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn), pass, strlen(pass)+1,
    651546                                   &passlen);
    652547        if (tevent_req_nomem(bytes, req)) {
    653548                return tevent_req_post(req, ev);
    654549        }
    655         SSVAL(vwv + (cli_ucs2(cli) ? 8 : 7), 0, passlen);
    656 
    657         bytes = smb_bytes_push_str(bytes, cli_ucs2(cli),
     550        SSVAL(vwv + (smbXcli_conn_use_unicode(cli->conn) ? 8 : 7), 0, passlen);
     551
     552        bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn),
    658553                                   user, strlen(user)+1, NULL);
    659         bytes = smb_bytes_push_str(bytes, cli_ucs2(cli),
     554        bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn),
    660555                                   workgroup, strlen(workgroup)+1, NULL);
    661         bytes = smb_bytes_push_str(bytes, cli_ucs2(cli),
     556        bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn),
    662557                                   "Unix", 5, NULL);
    663558
     
    667562                return tevent_req_post(req, ev);
    668563        }
    669         bytes = smb_bytes_push_str(bytes, cli_ucs2(cli),
     564        bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn),
    670565                                   version, strlen(version)+1, NULL);
    671566        TALLOC_FREE(version);
     
    693588        uint32_t num_bytes;
    694589        uint8_t *in;
    695         char *inbuf;
     590        uint8_t *inhdr;
    696591        uint8_t *bytes;
    697592        uint8_t *p;
     
    708603        }
    709604
    710         inbuf = (char *)in;
     605        inhdr = in + NBT_HDR_SIZE;
    711606        p = bytes;
    712607
    713         cli->vuid = SVAL(inbuf, smb_uid);
    714         cli->is_guestlogin = ((SVAL(vwv+2, 0) & 1) != 0);
     608        cli_state_set_uid(state->cli, SVAL(inhdr, HDR_UID));
     609        smb1cli_session_set_action(cli->smb1.session, SVAL(vwv+2, 0));
    715610
    716611        status = smb_bytes_talloc_string(cli,
    717                                         inbuf,
     612                                        inhdr,
    718613                                        &cli->server_os,
    719614                                        p,
     
    728623
    729624        status = smb_bytes_talloc_string(cli,
    730                                         inbuf,
     625                                        inhdr,
    731626                                        &cli->server_type,
    732627                                        p,
     
    741636
    742637        status = smb_bytes_talloc_string(cli,
    743                                         inbuf,
     638                                        inhdr,
    744639                                        &cli->server_domain,
    745640                                        p,
     
    753648        p += ret;
    754649
    755         status = cli_set_username(cli, state->user);
    756         if (tevent_req_nterror(req, status)) {
    757                 return;
    758         }
    759         if (strstr(cli->server_type, "Samba")) {
    760                 cli->is_samba = True;
    761         }
    762650        tevent_req_done(req);
    763651}
     
    766654{
    767655        return tevent_req_simple_recv_ntstatus(req);
    768 }
    769 
    770 static NTSTATUS cli_session_setup_plain(struct cli_state *cli,
    771                                         const char *user, const char *pass,
    772                                         const char *workgroup)
    773 {
    774         TALLOC_CTX *frame = talloc_stackframe();
    775         struct event_context *ev;
    776         struct tevent_req *req;
    777         NTSTATUS status = NT_STATUS_NO_MEMORY;
    778 
    779         if (cli_has_async_calls(cli)) {
    780                 /*
    781                  * Can't use sync call while an async call is in flight
    782                  */
    783                 status = NT_STATUS_INVALID_PARAMETER;
    784                 goto fail;
    785         }
    786         ev = event_context_init(frame);
    787         if (ev == NULL) {
    788                 goto fail;
    789         }
    790         req = cli_session_setup_plain_send(frame, ev, cli, user, pass,
    791                                            workgroup);
    792         if (req == NULL) {
    793                 goto fail;
    794         }
    795         if (!tevent_req_poll_ntstatus(req, ev, &status)) {
    796                 goto fail;
    797         }
    798         status = cli_session_setup_plain_recv(req);
    799  fail:
    800         TALLOC_FREE(frame);
    801         return status;
    802656}
    803657
     
    854708                        DATA_BLOB names_blob;
    855709
    856                         server_chal = data_blob(cli->secblob.data,
    857                                                 MIN(cli->secblob.length, 8));
    858                         if (tevent_req_nomem(server_chal.data, req)) {
    859                                 return tevent_req_post(req, ev);
    860                         }
     710                        server_chal =
     711                                data_blob_const(smb1cli_conn_server_challenge(cli->conn),
     712                                                8);
    861713
    862714                        /*
    863715                         * note that the 'workgroup' here is a best
    864716                         * guess - we don't know the server's domain
    865                          * at this point.  The 'server name' is also
    866                          * dodgy...
     717                         * at this point. Windows clients also don't
     718                         * use hostname...
    867719                         */
    868720                        names_blob = NTLMv2_generate_names_blob(
    869                                 NULL, cli->called.name, workgroup);
     721                                NULL, NULL, workgroup);
    870722
    871723                        if (tevent_req_nomem(names_blob.data, req)) {
     
    878730                                              NULL, &session_key)) {
    879731                                data_blob_free(&names_blob);
    880                                 data_blob_free(&server_chal);
    881732                                tevent_req_nterror(
    882733                                        req, NT_STATUS_ACCESS_DENIED);
     
    884735                        }
    885736                        data_blob_free(&names_blob);
    886                         data_blob_free(&server_chal);
    887737
    888738                } else {
     
    898748                        }
    899749
    900                         SMBNTencrypt(pass, cli->secblob.data,
     750                        SMBNTencrypt(pass, smb1cli_conn_server_challenge(cli->conn),
    901751                                     nt_response.data);
    902752#endif
     
    909759                                }
    910760
    911                                 if (!SMBencrypt(pass,cli->secblob.data,
     761                                if (!SMBencrypt(pass,
     762                                                smb1cli_conn_server_challenge(cli->conn),
    912763                                                lm_response.data)) {
    913764                                        /*
     
    945796#endif
    946797                }
    947                 cli_temp_set_signing(cli);
    948798        } else {
    949799                /* pre-encrypted password supplied.  Only used for
     
    987837        SSVAL(vwv+2, 0, CLI_BUFFER_SIZE);
    988838        SSVAL(vwv+3, 0, 2);
    989         SSVAL(vwv+4, 0, cli->pid);
    990         SIVAL(vwv+5, 0, cli->sesskey);
     839        SSVAL(vwv+4, 0, cli_state_get_vc_num(cli));
     840        SIVAL(vwv+5, 0, smb1cli_conn_server_session_key(cli->conn));
    991841        SSVAL(vwv+7, 0, lm_response.length);
    992842        SSVAL(vwv+8, 0, nt_response.length);
    993843        SSVAL(vwv+9, 0, 0);
    994844        SSVAL(vwv+10, 0, 0);
    995         SIVAL(vwv+11, 0, cli_session_setup_capabilities(cli));
     845        SIVAL(vwv+11, 0, cli_session_setup_capabilities(cli, 0));
    996846
    997847        bytes = talloc_array(state, uint8_t,
     
    1010860        data_blob_free(&nt_response);
    1011861
    1012         bytes = smb_bytes_push_str(bytes, cli_ucs2(cli),
     862        bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn),
    1013863                                   user, strlen(user)+1, NULL);
    1014864
     
    1020870                return tevent_req_post(req, ev);
    1021871        }
    1022         bytes = smb_bytes_push_str(bytes, cli_ucs2(cli),
     872        bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn),
    1023873                                   workgroup_upper, strlen(workgroup_upper)+1,
    1024874                                   NULL);
    1025875        TALLOC_FREE(workgroup_upper);
    1026876
    1027         bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), "Unix", 5, NULL);
    1028         bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), "Samba", 6, NULL);
     877        bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn), "Unix", 5, NULL);
     878        bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn), "Samba", 6, NULL);
    1029879        if (tevent_req_nomem(bytes, req)) {
    1030880                return tevent_req_post(req, ev);
     
    1049899        uint32_t num_bytes;
    1050900        uint8_t *in;
    1051         char *inbuf;
     901        uint8_t *inhdr;
    1052902        uint8_t *bytes;
    1053903        uint8_t *p;
     
    1065915        }
    1066916
    1067         inbuf = (char *)in;
     917        inhdr = in + NBT_HDR_SIZE;
    1068918        p = bytes;
    1069919
    1070         cli->vuid = SVAL(inbuf, smb_uid);
    1071         cli->is_guestlogin = ((SVAL(vwv+2, 0) & 1) != 0);
     920        cli_state_set_uid(state->cli, SVAL(inhdr, HDR_UID));
     921        smb1cli_session_set_action(cli->smb1.session, SVAL(vwv+2, 0));
    1072922
    1073923        status = smb_bytes_talloc_string(cli,
    1074                                         inbuf,
     924                                        inhdr,
    1075925                                        &cli->server_os,
    1076926                                        p,
     
    1084934
    1085935        status = smb_bytes_talloc_string(cli,
    1086                                         inbuf,
     936                                        inhdr,
    1087937                                        &cli->server_type,
    1088938                                        p,
     
    1096946
    1097947        status = smb_bytes_talloc_string(cli,
    1098                                         inbuf,
     948                                        inhdr,
    1099949                                        &cli->server_domain,
    1100950                                        p,
     
    1107957        p += ret;
    1108958
    1109         if (strstr(cli->server_type, "Samba")) {
    1110                 cli->is_samba = True;
    1111         }
    1112 
    1113         status = cli_set_username(cli, state->user);
    1114         if (tevent_req_nterror(req, status)) {
    1115                 return;
    1116         }
    1117         if (cli_simple_set_signing(cli, state->session_key, state->response)
    1118             && !cli_check_sign_mac(cli, (char *)in, 1)) {
     959        if (smb1cli_conn_activate_signing(cli->conn, state->session_key, state->response)
     960            && !smb1cli_conn_check_signing(cli->conn, (uint8_t *)in, 1)) {
    1119961                tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
    1120962                return;
    1121963        }
    1122964        if (state->session_key.data) {
    1123                 /* Have plaintext orginal */
    1124                 cli_set_session_key(cli, state->session_key);
     965                struct smbXcli_session *session = state->cli->smb1.session;
     966
     967                status = smb1cli_session_set_session_key(session,
     968                                state->session_key);
     969                if (tevent_req_nterror(req, status)) {
     970                        return;
     971                }
    1125972        }
    1126973        tevent_req_done(req);
     
    1130977{
    1131978        return tevent_req_simple_recv_ntstatus(req);
    1132 }
    1133 
    1134 static NTSTATUS cli_session_setup_nt1(struct cli_state *cli, const char *user,
    1135                                       const char *pass, size_t passlen,
    1136                                       const char *ntpass, size_t ntpasslen,
    1137                                       const char *workgroup)
    1138 {
    1139         TALLOC_CTX *frame = talloc_stackframe();
    1140         struct event_context *ev;
    1141         struct tevent_req *req;
    1142         NTSTATUS status = NT_STATUS_NO_MEMORY;
    1143 
    1144         if (cli_has_async_calls(cli)) {
    1145                 /*
    1146                  * Can't use sync call while an async call is in flight
    1147                  */
    1148                 status = NT_STATUS_INVALID_PARAMETER;
    1149                 goto fail;
    1150         }
    1151         ev = event_context_init(frame);
    1152         if (ev == NULL) {
    1153                 goto fail;
    1154         }
    1155         req = cli_session_setup_nt1_send(frame, ev, cli, user, pass, passlen,
    1156                                          ntpass, ntpasslen, workgroup);
    1157         if (req == NULL) {
    1158                 goto fail;
    1159         }
    1160         if (!tevent_req_poll_ntstatus(req, ev, &status)) {
    1161                 goto fail;
    1162         }
    1163         status = cli_session_setup_nt1_recv(req);
    1164  fail:
    1165         TALLOC_FREE(frame);
    1166         return status;
    1167979}
    1168980
     
    1184996        uint8_t *buf;
    1185997
    1186         NTSTATUS status;
    1187         char *inbuf;
     998        DATA_BLOB smb2_blob;
     999        struct iovec *recv_iov;
     1000
     1001        NTSTATUS status;
     1002        uint8_t *inbuf;
    11881003        DATA_BLOB ret_blob;
    11891004};
     
    12001015        struct tevent_req *req, *subreq;
    12011016        struct cli_sesssetup_blob_state *state;
     1017        uint32_t usable_space;
    12021018
    12031019        req = tevent_req_create(mem_ctx, &state,
     
    12101026        state->cli = cli;
    12111027
    1212         if (cli->max_xmit < BASE_SESSSETUP_BLOB_PACKET_SIZE + 1) {
     1028        if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) {
     1029                usable_space = UINT16_MAX;
     1030        } else {
     1031                usable_space = cli_state_available_size(cli,
     1032                                BASE_SESSSETUP_BLOB_PACKET_SIZE);
     1033        }
     1034
     1035        if (usable_space == 0) {
    12131036                DEBUG(1, ("cli_session_setup_blob: cli->max_xmit too small "
    1214                           "(was %u, need minimum %u)\n",
    1215                           (unsigned int)cli->max_xmit,
    1216                           BASE_SESSSETUP_BLOB_PACKET_SIZE));
     1037                          "(not possible to send %u bytes)\n",
     1038                          BASE_SESSSETUP_BLOB_PACKET_SIZE + 1));
    12171039                tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
    12181040                return tevent_req_post(req, ev);
    12191041        }
    1220         state->max_blob_size =
    1221                 MIN(cli->max_xmit - BASE_SESSSETUP_BLOB_PACKET_SIZE, 0xFFFF);
     1042        state->max_blob_size = MIN(usable_space, 0xFFFF);
    12221043
    12231044        if (!cli_sesssetup_blob_next(state, &subreq)) {
     
    12341055        struct tevent_req *subreq;
    12351056        uint16_t thistime;
     1057
     1058        thistime = MIN(state->blob.length, state->max_blob_size);
     1059
     1060        if (smbXcli_conn_protocol(state->cli->conn) >= PROTOCOL_SMB2_02) {
     1061
     1062                state->smb2_blob.data = state->blob.data;
     1063                state->smb2_blob.length = thistime;
     1064
     1065                state->blob.data += thistime;
     1066                state->blob.length -= thistime;
     1067
     1068                subreq = smb2cli_session_setup_send(state, state->ev,
     1069                                                    state->cli->conn,
     1070                                                    state->cli->timeout,
     1071                                                    state->cli->smb2.session,
     1072                                                    0, /* in_flags */
     1073                                                    SMB2_CAP_DFS, /* in_capabilities */
     1074                                                    0, /* in_channel */
     1075                                                    0, /* in_previous_session_id */
     1076                                                    &state->smb2_blob);
     1077                if (subreq == NULL) {
     1078                        return false;
     1079                }
     1080                *psubreq = subreq;
     1081                return true;
     1082        }
    12361083
    12371084        SCVAL(state->vwv+0, 0, 0xFF);
     
    12431090        SIVAL(state->vwv+5, 0, 0);
    12441091
    1245         thistime = MIN(state->blob.length, state->max_blob_size);
    12461092        SSVAL(state->vwv+7, 0, thistime);
    12471093
     
    12491095        SSVAL(state->vwv+9, 0, 0);
    12501096        SIVAL(state->vwv+10, 0,
    1251               cli_session_setup_capabilities(state->cli)
    1252               | CAP_EXTENDED_SECURITY);
     1097                cli_session_setup_capabilities(state->cli, CAP_EXTENDED_SECURITY));
    12531098
    12541099        state->buf = (uint8_t *)talloc_memdup(state, state->blob.data,
     
    12601105        state->blob.length -= thistime;
    12611106
    1262         state->buf = smb_bytes_push_str(state->buf, cli_ucs2(state->cli),
     1107        state->buf = smb_bytes_push_str(state->buf, smbXcli_conn_use_unicode(state->cli->conn),
    12631108                                        "Unix", 5, NULL);
    1264         state->buf = smb_bytes_push_str(state->buf, cli_ucs2(state->cli),
     1109        state->buf = smb_bytes_push_str(state->buf, smbXcli_conn_use_unicode(state->cli->conn),
    12651110                                        "Samba", 6, NULL);
    12661111        if (state->buf == NULL) {
     
    12911136        uint8_t *p;
    12921137        uint16_t blob_length;
    1293         uint8_t *inbuf;
     1138        uint8_t *in;
     1139        uint8_t *inhdr;
    12941140        ssize_t ret;
    12951141
    1296         status = cli_smb_recv(subreq, state, &inbuf, 4, &wct, &vwv,
    1297                               &num_bytes, &bytes);
     1142        if (smbXcli_conn_protocol(state->cli->conn) >= PROTOCOL_SMB2_02) {
     1143                status = smb2cli_session_setup_recv(subreq, state,
     1144                                                    &state->recv_iov,
     1145                                                    &state->ret_blob);
     1146        } else {
     1147                status = cli_smb_recv(subreq, state, &in, 4, &wct, &vwv,
     1148                                      &num_bytes, &bytes);
     1149                TALLOC_FREE(state->buf);
     1150        }
    12981151        TALLOC_FREE(subreq);
    12991152        if (!NT_STATUS_IS_OK(status)
     
    13041157
    13051158        state->status = status;
    1306         TALLOC_FREE(state->buf);
    1307 
    1308         state->inbuf = (char *)inbuf;
    1309         cli->vuid = SVAL(state->inbuf, smb_uid);
    1310         cli->is_guestlogin = ((SVAL(vwv+2, 0) & 1) != 0);
     1159
     1160        if (smbXcli_conn_protocol(state->cli->conn) >= PROTOCOL_SMB2_02) {
     1161                goto next;
     1162        }
     1163
     1164        state->inbuf = in;
     1165        inhdr = in + NBT_HDR_SIZE;
     1166        cli_state_set_uid(state->cli, SVAL(inhdr, HDR_UID));
     1167        smb1cli_session_set_action(cli->smb1.session, SVAL(vwv+2, 0));
    13111168
    13121169        blob_length = SVAL(vwv+3, 0);
     
    13201177
    13211178        status = smb_bytes_talloc_string(cli,
    1322                                         (char *)inbuf,
     1179                                        inhdr,
    13231180                                        &cli->server_os,
    13241181                                        p,
     
    13331190
    13341191        status = smb_bytes_talloc_string(cli,
    1335                                         (char *)inbuf,
     1192                                        inhdr,
    13361193                                        &cli->server_type,
    13371194                                        p,
     
    13461203
    13471204        status = smb_bytes_talloc_string(cli,
    1348                                         (char *)inbuf,
     1205                                        inhdr,
    13491206                                        &cli->server_domain,
    13501207                                        p,
     
    13581215        p += ret;
    13591216
    1360         if (strstr(cli->server_type, "Samba")) {
    1361                 cli->is_samba = True;
    1362         }
    1363 
     1217next:
    13641218        if (state->blob.length != 0) {
    13651219                /*
     
    13671221                 */
    13681222                if (!cli_sesssetup_blob_next(state, &subreq)) {
    1369                         tevent_req_nomem(NULL, req);
     1223                        tevent_req_oom(req);
    13701224                        return;
    13711225                }
     
    13791233                                        TALLOC_CTX *mem_ctx,
    13801234                                        DATA_BLOB *pblob,
    1381                                         char **pinbuf)
     1235                                        uint8_t **pinbuf,
     1236                                        struct iovec **precv_iov)
    13821237{
    13831238        struct cli_sesssetup_blob_state *state = tevent_req_data(
    13841239                req, struct cli_sesssetup_blob_state);
    13851240        NTSTATUS status;
    1386         char *inbuf;
     1241        uint8_t *inbuf;
     1242        struct iovec *recv_iov;
    13871243
    13881244        if (tevent_req_is_nterror(req, &status)) {
    1389                 state->cli->vuid = 0;
     1245                TALLOC_FREE(state->cli->smb2.session);
     1246                cli_state_set_uid(state->cli, UID_FIELD_INVALID);
    13901247                return status;
    13911248        }
    13921249
    13931250        inbuf = talloc_move(mem_ctx, &state->inbuf);
     1251        recv_iov = talloc_move(mem_ctx, &state->recv_iov);
    13941252        if (pblob != NULL) {
    13951253                *pblob = state->ret_blob;
     
    13971255        if (pinbuf != NULL) {
    13981256                *pinbuf = inbuf;
     1257        }
     1258        if (precv_iov != NULL) {
     1259                *precv_iov = recv_iov;
    13991260        }
    14001261        /* could be NT_STATUS_MORE_PROCESSING_REQUIRED */
     
    14121273}
    14131274
    1414 /****************************************************************************
    1415  Do a spnego/kerberos encrypted session setup.
    1416 ****************************************************************************/
    1417 
    1418 struct cli_session_setup_kerberos_state {
    1419         struct cli_state *cli;
    1420         DATA_BLOB negTokenTarg;
    1421         DATA_BLOB session_key_krb5;
    1422         ADS_STATUS ads_status;
    1423 };
    1424 
    1425 static void cli_session_setup_kerberos_done(struct tevent_req *subreq);
    1426 
    1427 static struct tevent_req *cli_session_setup_kerberos_send(
    1428         TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct cli_state *cli,
    1429         const char *principal, const char *workgroup)
    1430 {
    1431         struct tevent_req *req, *subreq;
    1432         struct cli_session_setup_kerberos_state *state;
    1433         int rc;
    1434 
    1435         DEBUG(2,("Doing kerberos session setup\n"));
    1436 
    1437         req = tevent_req_create(mem_ctx, &state,
    1438                                 struct cli_session_setup_kerberos_state);
    1439         if (req == NULL) {
    1440                 return NULL;
    1441         }
    1442         state->cli = cli;
    1443         state->ads_status = ADS_SUCCESS;
    1444 
    1445         cli_temp_set_signing(cli);
    1446 
    1447         /*
    1448          * Ok, this is cheating: spnego_gen_krb5_negTokenInit can block if
    1449          * we have to acquire a ticket. To be fixed later :-)
    1450          */
    1451         rc = spnego_gen_krb5_negTokenInit(state, principal, 0, &state->negTokenTarg,
    1452                                      &state->session_key_krb5, 0, NULL);
    1453         if (rc) {
    1454                 DEBUG(1, ("cli_session_setup_kerberos: "
    1455                           "spnego_gen_krb5_negTokenInit failed: %s\n",
    1456                           error_message(rc)));
    1457                 state->ads_status = ADS_ERROR_KRB5(rc);
    1458                 tevent_req_nterror(req, NT_STATUS_UNSUCCESSFUL);
    1459                 return tevent_req_post(req, ev);
    1460         }
    1461 
    1462 #if 0
    1463         file_save("negTokenTarg.dat", state->negTokenTarg.data,
    1464                   state->negTokenTarg.length);
    1465 #endif
    1466 
    1467         subreq = cli_sesssetup_blob_send(state, ev, cli, state->negTokenTarg);
    1468         if (tevent_req_nomem(subreq, req)) {
    1469                 return tevent_req_post(req, ev);
    1470         }
    1471         tevent_req_set_callback(subreq, cli_session_setup_kerberos_done, req);
    1472         return req;
    1473 }
    1474 
    1475 static void cli_session_setup_kerberos_done(struct tevent_req *subreq)
    1476 {
    1477         struct tevent_req *req = tevent_req_callback_data(
    1478                 subreq, struct tevent_req);
    1479         struct cli_session_setup_kerberos_state *state = tevent_req_data(
    1480                 req, struct cli_session_setup_kerberos_state);
    1481         char *inbuf = NULL;
    1482         NTSTATUS status;
    1483 
    1484         status = cli_sesssetup_blob_recv(subreq, talloc_tos(), NULL, &inbuf);
    1485         if (!NT_STATUS_IS_OK(status)) {
    1486                 TALLOC_FREE(subreq);
    1487                 tevent_req_nterror(req, status);
    1488                 return;
    1489         }
    1490 
    1491         cli_set_session_key(state->cli, state->session_key_krb5);
    1492 
    1493         if (cli_simple_set_signing(state->cli, state->session_key_krb5,
    1494                                    data_blob_null)
    1495             && !cli_check_sign_mac(state->cli, inbuf, 1)) {
    1496                 TALLOC_FREE(subreq);
    1497                 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
    1498                 return;
    1499         }
    1500         TALLOC_FREE(subreq);
    1501         tevent_req_done(req);
    1502 }
    1503 
    1504 static ADS_STATUS cli_session_setup_kerberos_recv(struct tevent_req *req)
    1505 {
    1506         struct cli_session_setup_kerberos_state *state = tevent_req_data(
    1507                 req, struct cli_session_setup_kerberos_state);
    1508         NTSTATUS status;
    1509 
    1510         if (tevent_req_is_nterror(req, &status)) {
    1511                 return ADS_ERROR_NT(status);
    1512         }
    1513         return state->ads_status;
    1514 }
    1515 
    1516 static ADS_STATUS cli_session_setup_kerberos(struct cli_state *cli,
    1517                                              const char *principal,
    1518                                              const char *workgroup)
    1519 {
    1520         struct tevent_context *ev;
    1521         struct tevent_req *req;
    1522         ADS_STATUS status = ADS_ERROR_NT(NT_STATUS_NO_MEMORY);
    1523 
    1524         if (cli_has_async_calls(cli)) {
    1525                 return ADS_ERROR_NT(NT_STATUS_INVALID_PARAMETER);
    1526         }
    1527         ev = tevent_context_init(talloc_tos());
    1528         if (ev == NULL) {
    1529                 goto fail;
    1530         }
    1531         req = cli_session_setup_kerberos_send(ev, ev, cli, principal,
    1532                                               workgroup);
    1533         if (req == NULL) {
    1534                 goto fail;
    1535         }
    1536         if (!tevent_req_poll(req, ev)) {
    1537                 status = ADS_ERROR_SYSTEM(errno);
    1538                 goto fail;
    1539         }
    1540         status = cli_session_setup_kerberos_recv(req);
    1541 fail:
    1542         TALLOC_FREE(ev);
    1543         return status;
    1544 }
    15451275#endif  /* HAVE_KRB5 */
    15461276
     
    15491279****************************************************************************/
    15501280
    1551 struct cli_session_setup_ntlmssp_state {
     1281struct cli_session_setup_gensec_state {
    15521282        struct tevent_context *ev;
    15531283        struct cli_state *cli;
    1554         struct ntlmssp_state *ntlmssp_state;
    1555         int turn;
     1284        struct auth_generic_state *auth_generic;
     1285        bool is_anonymous;
     1286        DATA_BLOB blob_in;
     1287        uint8_t *inbuf;
     1288        struct iovec *recv_iov;
    15561289        DATA_BLOB blob_out;
     1290        bool local_ready;
     1291        bool remote_ready;
     1292        DATA_BLOB session_key;
    15571293};
    15581294
    1559 static int cli_session_setup_ntlmssp_state_destructor(
    1560         struct cli_session_setup_ntlmssp_state *state)
    1561 {
    1562         if (state->ntlmssp_state != NULL) {
    1563                 TALLOC_FREE(state->ntlmssp_state);
    1564         }
     1295static int cli_session_setup_gensec_state_destructor(
     1296        struct cli_session_setup_gensec_state *state)
     1297{
     1298        TALLOC_FREE(state->auth_generic);
     1299        data_blob_clear_free(&state->session_key);
    15651300        return 0;
    15661301}
    15671302
    1568 static void cli_session_setup_ntlmssp_done(struct tevent_req *req);
    1569 
    1570 static struct tevent_req *cli_session_setup_ntlmssp_send(
     1303static void cli_session_setup_gensec_local_next(struct tevent_req *req);
     1304static void cli_session_setup_gensec_local_done(struct tevent_req *subreq);
     1305static void cli_session_setup_gensec_remote_next(struct tevent_req *req);
     1306static void cli_session_setup_gensec_remote_done(struct tevent_req *subreq);
     1307static void cli_session_setup_gensec_ready(struct tevent_req *req);
     1308
     1309static struct tevent_req *cli_session_setup_gensec_send(
    15711310        TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct cli_state *cli,
    1572         const char *user, const char *pass, const char *domain)
    1573 {
    1574         struct tevent_req *req, *subreq;
    1575         struct cli_session_setup_ntlmssp_state *state;
    1576         NTSTATUS status;
    1577         DATA_BLOB blob_out;
    1578         const char *OIDs_ntlm[] = {OID_NTLMSSP, NULL};
     1311        const char *user, const char *pass, const char *domain,
     1312        enum credentials_use_kerberos krb5_state,
     1313        const char *target_service,
     1314        const char *target_hostname,
     1315        const char *target_principal)
     1316{
     1317        struct tevent_req *req;
     1318        struct cli_session_setup_gensec_state *state;
     1319        NTSTATUS status;
     1320        bool use_spnego_principal = lp_client_use_spnego_principal();
    15791321
    15801322        req = tevent_req_create(mem_ctx, &state,
    1581                                 struct cli_session_setup_ntlmssp_state);
     1323                                struct cli_session_setup_gensec_state);
    15821324        if (req == NULL) {
    15831325                return NULL;
     
    15851327        state->ev = ev;
    15861328        state->cli = cli;
    1587         state->turn = 1;
    1588 
    1589         state->ntlmssp_state = NULL;
     1329
    15901330        talloc_set_destructor(
    1591                 state, cli_session_setup_ntlmssp_state_destructor);
    1592 
    1593         cli_temp_set_signing(cli);
    1594 
    1595         status = ntlmssp_client_start(state,
    1596                                       global_myname(),
    1597                                       lp_workgroup(),
    1598                                       lp_client_ntlmv2_auth(),
    1599                                       &state->ntlmssp_state);
    1600         if (!NT_STATUS_IS_OK(status)) {
    1601                 goto fail;
    1602         }
    1603         ntlmssp_want_feature(state->ntlmssp_state,
    1604                              NTLMSSP_FEATURE_SESSION_KEY);
     1331                state, cli_session_setup_gensec_state_destructor);
     1332
     1333        if (user == NULL || strlen(user) == 0) {
     1334                if (pass != NULL && strlen(pass) == 0) {
     1335                        /*
     1336                         * some callers pass "" as no password
     1337                         *
     1338                         * gensec only handles NULL as no password.
     1339                         */
     1340                        pass = NULL;
     1341                }
     1342        }
     1343
     1344        status = auth_generic_client_prepare(state, &state->auth_generic);
     1345        if (tevent_req_nterror(req, status)) {
     1346                return tevent_req_post(req, ev);
     1347        }
     1348
     1349        gensec_want_feature(state->auth_generic->gensec_security,
     1350                            GENSEC_FEATURE_SESSION_KEY);
    16051351        if (cli->use_ccache) {
    1606                 ntlmssp_want_feature(state->ntlmssp_state,
    1607                                      NTLMSSP_FEATURE_CCACHE);
    1608         }
    1609         status = ntlmssp_set_username(state->ntlmssp_state, user);
    1610         if (!NT_STATUS_IS_OK(status)) {
    1611                 goto fail;
    1612         }
    1613         status = ntlmssp_set_domain(state->ntlmssp_state, domain);
    1614         if (!NT_STATUS_IS_OK(status)) {
    1615                 goto fail;
    1616         }
    1617         status = ntlmssp_set_password(state->ntlmssp_state, pass);
    1618         if (!NT_STATUS_IS_OK(status)) {
    1619                 goto fail;
    1620         }
    1621         status = ntlmssp_update(state->ntlmssp_state, data_blob_null,
    1622                                 &blob_out);
    1623         if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
    1624                 goto fail;
    1625         }
    1626 
    1627         state->blob_out = spnego_gen_negTokenInit(state, OIDs_ntlm, &blob_out, NULL);
    1628         data_blob_free(&blob_out);
    1629 
    1630         subreq = cli_sesssetup_blob_send(state, ev, cli, state->blob_out);
     1352                gensec_want_feature(state->auth_generic->gensec_security,
     1353                                    GENSEC_FEATURE_NTLM_CCACHE);
     1354                if (pass != NULL && strlen(pass) == 0) {
     1355                        /*
     1356                         * some callers pass "" as no password
     1357                         *
     1358                         * GENSEC_FEATURE_NTLM_CCACHE only handles
     1359                         * NULL as no password.
     1360                         */
     1361                        pass = NULL;
     1362                }
     1363        }
     1364
     1365        status = auth_generic_set_username(state->auth_generic, user);
     1366        if (tevent_req_nterror(req, status)) {
     1367                return tevent_req_post(req, ev);
     1368        }
     1369
     1370        status = auth_generic_set_domain(state->auth_generic, domain);
     1371        if (tevent_req_nterror(req, status)) {
     1372                return tevent_req_post(req, ev);
     1373        }
     1374
     1375        if (cli->pw_nt_hash) {
     1376                struct samr_Password nt_hash;
     1377                size_t converted;
     1378                bool ok;
     1379
     1380                if (pass == NULL) {
     1381                        tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER_MIX);
     1382                        return tevent_req_post(req, ev);
     1383                }
     1384
     1385                converted = strhex_to_str((char *)nt_hash.hash,
     1386                                          sizeof(nt_hash.hash),
     1387                                          pass, strlen(pass));
     1388                if (converted != sizeof(nt_hash.hash)) {
     1389                        tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER_MIX);
     1390                        return tevent_req_post(req, ev);
     1391                }
     1392
     1393                ok = cli_credentials_set_nt_hash(state->auth_generic->credentials,
     1394                                                 &nt_hash, CRED_SPECIFIED);
     1395                if (!ok) {
     1396                        tevent_req_oom(req);
     1397                        return tevent_req_post(req, ev);
     1398                }
     1399        } else {
     1400                status = auth_generic_set_password(state->auth_generic, pass);
     1401                if (tevent_req_nterror(req, status)) {
     1402                        return tevent_req_post(req, ev);
     1403                }
     1404        }
     1405
     1406        cli_credentials_set_kerberos_state(state->auth_generic->credentials,
     1407                                           krb5_state);
     1408
     1409        if (krb5_state == CRED_DONT_USE_KERBEROS) {
     1410                use_spnego_principal = false;
     1411        }
     1412
     1413        if (target_service != NULL) {
     1414                status = gensec_set_target_service(
     1415                                state->auth_generic->gensec_security,
     1416                                target_service);
     1417                if (tevent_req_nterror(req, status)) {
     1418                        return tevent_req_post(req, ev);
     1419                }
     1420        }
     1421
     1422        if (target_hostname != NULL) {
     1423                status = gensec_set_target_hostname(
     1424                                state->auth_generic->gensec_security,
     1425                                target_hostname);
     1426                if (tevent_req_nterror(req, status)) {
     1427                        return tevent_req_post(req, ev);
     1428                }
     1429        }
     1430
     1431        if (target_principal != NULL) {
     1432                status = gensec_set_target_principal(
     1433                                state->auth_generic->gensec_security,
     1434                                target_principal);
     1435                if (tevent_req_nterror(req, status)) {
     1436                        return tevent_req_post(req, ev);
     1437                }
     1438                use_spnego_principal = false;
     1439        } else if (target_service != NULL && target_hostname != NULL) {
     1440                use_spnego_principal = false;
     1441        }
     1442
     1443        if (use_spnego_principal) {
     1444                const DATA_BLOB *b;
     1445                b = smbXcli_conn_server_gss_blob(cli->conn);
     1446                if (b != NULL) {
     1447                        state->blob_in = *b;
     1448                }
     1449        }
     1450
     1451        state->is_anonymous = cli_credentials_is_anonymous(state->auth_generic->credentials);
     1452
     1453        status = auth_generic_client_start(state->auth_generic,
     1454                                           GENSEC_OID_SPNEGO);
     1455        if (tevent_req_nterror(req, status)) {
     1456                return tevent_req_post(req, ev);
     1457        }
     1458
     1459        if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) {
     1460                state->cli->smb2.session = smbXcli_session_create(cli,
     1461                                                                  cli->conn);
     1462                if (tevent_req_nomem(state->cli->smb2.session, req)) {
     1463                        return tevent_req_post(req, ev);
     1464                }
     1465        }
     1466
     1467        cli_session_setup_gensec_local_next(req);
     1468        if (!tevent_req_is_in_progress(req)) {
     1469                return tevent_req_post(req, ev);
     1470        }
     1471
     1472        return req;
     1473}
     1474
     1475static void cli_session_setup_gensec_local_next(struct tevent_req *req)
     1476{
     1477        struct cli_session_setup_gensec_state *state =
     1478                tevent_req_data(req,
     1479                struct cli_session_setup_gensec_state);
     1480        struct tevent_req *subreq = NULL;
     1481
     1482        if (state->local_ready) {
     1483                tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
     1484                return;
     1485        }
     1486
     1487        subreq = gensec_update_send(state, state->ev,
     1488                        state->auth_generic->gensec_security,
     1489                        state->blob_in);
    16311490        if (tevent_req_nomem(subreq, req)) {
    1632                 return tevent_req_post(req, ev);
    1633         }
    1634         tevent_req_set_callback(subreq, cli_session_setup_ntlmssp_done, req);
    1635         return req;
    1636 fail:
    1637         tevent_req_nterror(req, status);
    1638         return tevent_req_post(req, ev);
    1639 }
    1640 
    1641 static void cli_session_setup_ntlmssp_done(struct tevent_req *subreq)
    1642 {
    1643         struct tevent_req *req = tevent_req_callback_data(
    1644                 subreq, struct tevent_req);
    1645         struct cli_session_setup_ntlmssp_state *state = tevent_req_data(
    1646                 req, struct cli_session_setup_ntlmssp_state);
    1647         DATA_BLOB blob_in, msg_in, blob_out;
    1648         char *inbuf = NULL;
    1649         bool parse_ret;
    1650         NTSTATUS status;
    1651 
    1652         status = cli_sesssetup_blob_recv(subreq, talloc_tos(), &blob_in,
    1653                                          &inbuf);
     1491                return;
     1492        }
     1493        tevent_req_set_callback(subreq, cli_session_setup_gensec_local_done, req);
     1494}
     1495
     1496static void cli_session_setup_gensec_local_done(struct tevent_req *subreq)
     1497{
     1498        struct tevent_req *req =
     1499                tevent_req_callback_data(subreq,
     1500                struct tevent_req);
     1501        struct cli_session_setup_gensec_state *state =
     1502                tevent_req_data(req,
     1503                struct cli_session_setup_gensec_state);
     1504        NTSTATUS status;
     1505
     1506        status = gensec_update_recv(subreq, state, &state->blob_out);
     1507        TALLOC_FREE(subreq);
     1508        state->blob_in = data_blob_null;
     1509        if (!NT_STATUS_IS_OK(status) &&
     1510            !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED))
     1511        {
     1512                tevent_req_nterror(req, status);
     1513                return;
     1514        }
     1515
     1516        if (NT_STATUS_IS_OK(status)) {
     1517                state->local_ready = true;
     1518        }
     1519
     1520        if (state->local_ready && state->remote_ready) {
     1521                cli_session_setup_gensec_ready(req);
     1522                return;
     1523        }
     1524
     1525        cli_session_setup_gensec_remote_next(req);
     1526}
     1527
     1528static void cli_session_setup_gensec_remote_next(struct tevent_req *req)
     1529{
     1530        struct cli_session_setup_gensec_state *state =
     1531                tevent_req_data(req,
     1532                struct cli_session_setup_gensec_state);
     1533        struct tevent_req *subreq = NULL;
     1534
     1535        if (state->remote_ready) {
     1536                tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
     1537                return;
     1538        }
     1539
     1540        subreq = cli_sesssetup_blob_send(state, state->ev,
     1541                                         state->cli, state->blob_out);
     1542        if (tevent_req_nomem(subreq, req)) {
     1543                return;
     1544        }
     1545        tevent_req_set_callback(subreq,
     1546                                cli_session_setup_gensec_remote_done,
     1547                                req);
     1548}
     1549
     1550static void cli_session_setup_gensec_remote_done(struct tevent_req *subreq)
     1551{
     1552        struct tevent_req *req =
     1553                tevent_req_callback_data(subreq,
     1554                struct tevent_req);
     1555        struct cli_session_setup_gensec_state *state =
     1556                tevent_req_data(req,
     1557                struct cli_session_setup_gensec_state);
     1558        NTSTATUS status;
     1559
     1560        TALLOC_FREE(state->inbuf);
     1561        TALLOC_FREE(state->recv_iov);
     1562
     1563        status = cli_sesssetup_blob_recv(subreq, state, &state->blob_in,
     1564                                         &state->inbuf, &state->recv_iov);
    16541565        TALLOC_FREE(subreq);
    16551566        data_blob_free(&state->blob_out);
     1567        if (!NT_STATUS_IS_OK(status) &&
     1568            !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED))
     1569        {
     1570                tevent_req_nterror(req, status);
     1571                return;
     1572        }
    16561573
    16571574        if (NT_STATUS_IS_OK(status)) {
    1658                 if (state->cli->server_domain[0] == '\0') {
    1659                         TALLOC_FREE(state->cli->server_domain);
    1660                         state->cli->server_domain = talloc_strdup(state->cli,
    1661                                                 state->ntlmssp_state->server.netbios_domain);
    1662                         if (state->cli->server_domain == NULL) {
    1663                                 TALLOC_FREE(subreq);
    1664                                 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
     1575                struct smbXcli_session *session = NULL;
     1576                bool is_guest = false;
     1577
     1578                if (smbXcli_conn_protocol(state->cli->conn) >= PROTOCOL_SMB2_02) {
     1579                        session = state->cli->smb2.session;
     1580                } else {
     1581                        session = state->cli->smb1.session;
     1582                }
     1583
     1584                is_guest = smbXcli_session_is_guest(session);
     1585                if (is_guest) {
     1586                        /*
     1587                         * We can't finish the gensec handshake, we don't
     1588                         * have a negotiated session key.
     1589                         *
     1590                         * So just pretend we are completely done.
     1591                         */
     1592                        state->blob_in = data_blob_null;
     1593                        state->local_ready = true;
     1594                }
     1595
     1596                state->remote_ready = true;
     1597        }
     1598
     1599        if (state->local_ready && state->remote_ready) {
     1600                cli_session_setup_gensec_ready(req);
     1601                return;
     1602        }
     1603
     1604        cli_session_setup_gensec_local_next(req);
     1605}
     1606
     1607static void cli_session_setup_gensec_ready(struct tevent_req *req)
     1608{
     1609        struct cli_session_setup_gensec_state *state =
     1610                tevent_req_data(req,
     1611                struct cli_session_setup_gensec_state);
     1612        const char *server_domain = NULL;
     1613        NTSTATUS status;
     1614
     1615        if (state->blob_in.length != 0) {
     1616                tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
     1617                return;
     1618        }
     1619
     1620        if (state->blob_out.length != 0) {
     1621                tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
     1622                return;
     1623        }
     1624
     1625        /*
     1626         * gensec_ntlmssp_server_domain() returns NULL
     1627         * if NTLMSSP is not used.
     1628         *
     1629         * We can remove this later
     1630         * and leave the server domain empty for SMB2 and above
     1631         * in future releases.
     1632         */
     1633        server_domain = gensec_ntlmssp_server_domain(
     1634                                state->auth_generic->gensec_security);
     1635
     1636        if (state->cli->server_domain[0] == '\0' && server_domain != NULL) {
     1637                TALLOC_FREE(state->cli->server_domain);
     1638                state->cli->server_domain = talloc_strdup(state->cli,
     1639                                        server_domain);
     1640                if (state->cli->server_domain == NULL) {
     1641                        tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
     1642                        return;
     1643                }
     1644        }
     1645
     1646        if (state->is_anonymous) {
     1647                /*
     1648                 * Windows server does not set the
     1649                 * SMB2_SESSION_FLAG_IS_NULL flag.
     1650                 *
     1651                 * This fix makes sure we do not try
     1652                 * to verify a signature on the final
     1653                 * session setup response.
     1654                 */
     1655                tevent_req_done(req);
     1656                return;
     1657        }
     1658
     1659        status = gensec_session_key(state->auth_generic->gensec_security,
     1660                                    state, &state->session_key);
     1661        if (tevent_req_nterror(req, status)) {
     1662                return;
     1663        }
     1664
     1665        if (smbXcli_conn_protocol(state->cli->conn) >= PROTOCOL_SMB2_02) {
     1666                struct smbXcli_session *session = state->cli->smb2.session;
     1667
     1668                status = smb2cli_session_set_session_key(session,
     1669                                                         state->session_key,
     1670                                                         state->recv_iov);
     1671                if (tevent_req_nterror(req, status)) {
     1672                        return;
     1673                }
     1674        } else {
     1675                struct smbXcli_session *session = state->cli->smb1.session;
     1676                bool active;
     1677
     1678                status = smb1cli_session_set_session_key(session,
     1679                                                         state->session_key);
     1680                if (tevent_req_nterror(req, status)) {
     1681                        return;
     1682                }
     1683
     1684                active = smb1cli_conn_activate_signing(state->cli->conn,
     1685                                                       state->session_key,
     1686                                                       data_blob_null);
     1687                if (active) {
     1688                        bool ok;
     1689
     1690                        ok = smb1cli_conn_check_signing(state->cli->conn,
     1691                                                        state->inbuf, 1);
     1692                        if (!ok) {
     1693                                tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
    16651694                                return;
    16661695                        }
    16671696                }
    1668                 cli_set_session_key(
    1669                         state->cli, state->ntlmssp_state->session_key);
    1670 
    1671                 if (cli_simple_set_signing(
    1672                             state->cli, state->ntlmssp_state->session_key,
    1673                             data_blob_null)
    1674                     && !cli_check_sign_mac(state->cli, inbuf, 1)) {
    1675                         TALLOC_FREE(subreq);
    1676                         tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
    1677                         return;
    1678                 }
    1679                 TALLOC_FREE(subreq);
    1680                 TALLOC_FREE(state->ntlmssp_state);
    1681                 tevent_req_done(req);
    1682                 return;
    1683         }
    1684         if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
    1685                 tevent_req_nterror(req, status);
    1686                 return;
    1687         }
    1688 
    1689         if (blob_in.length == 0) {
    1690                 tevent_req_nterror(req, NT_STATUS_UNSUCCESSFUL);
    1691                 return;
    1692         }
    1693 
    1694         if ((state->turn == 1)
    1695             && NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
    1696                 DATA_BLOB tmp_blob = data_blob_null;
    1697                 /* the server might give us back two challenges */
    1698                 parse_ret = spnego_parse_challenge(state, blob_in, &msg_in,
    1699                                                    &tmp_blob);
    1700                 data_blob_free(&tmp_blob);
     1697        }
     1698
     1699        tevent_req_done(req);
     1700}
     1701
     1702static NTSTATUS cli_session_setup_gensec_recv(struct tevent_req *req)
     1703{
     1704        struct cli_session_setup_gensec_state *state =
     1705                tevent_req_data(req,
     1706                struct cli_session_setup_gensec_state);
     1707        NTSTATUS status;
     1708
     1709        if (tevent_req_is_nterror(req, &status)) {
     1710                cli_state_set_uid(state->cli, UID_FIELD_INVALID);
     1711                return status;
     1712        }
     1713        return NT_STATUS_OK;
     1714}
     1715
     1716#ifdef HAVE_KRB5
     1717
     1718static char *cli_session_setup_get_principal(
     1719        TALLOC_CTX *mem_ctx, const char *spnego_principal,
     1720        const char *remote_name, const char *dest_realm)
     1721{
     1722        char *principal = NULL;
     1723
     1724        if (!lp_client_use_spnego_principal() ||
     1725            strequal(spnego_principal, ADS_IGNORE_PRINCIPAL)) {
     1726                spnego_principal = NULL;
     1727        }
     1728        if (spnego_principal != NULL) {
     1729                DEBUG(3, ("cli_session_setup_spnego: using spnego provided "
     1730                          "principal %s\n", spnego_principal));
     1731                return talloc_strdup(mem_ctx, spnego_principal);
     1732        }
     1733        if (is_ipaddress(remote_name) ||
     1734            strequal(remote_name, STAR_SMBSERVER)) {
     1735                return NULL;
     1736        }
     1737
     1738        DEBUG(3, ("cli_session_setup_spnego: using target "
     1739                  "hostname not SPNEGO principal\n"));
     1740
     1741        if (dest_realm) {
     1742                char *realm = strupper_talloc(talloc_tos(), dest_realm);
     1743                if (realm == NULL) {
     1744                        return NULL;
     1745                }
     1746                principal = talloc_asprintf(talloc_tos(), "cifs/%s@%s",
     1747                                            remote_name, realm);
     1748                TALLOC_FREE(realm);
    17011749        } else {
    1702                 parse_ret = spnego_parse_auth_response(state, blob_in, status,
    1703                                                        OID_NTLMSSP, &msg_in);
    1704         }
    1705         state->turn += 1;
    1706 
    1707         if (!parse_ret) {
    1708                 DEBUG(3,("Failed to parse auth response\n"));
    1709                 if (NT_STATUS_IS_OK(status)
    1710                     || NT_STATUS_EQUAL(status,
    1711                                        NT_STATUS_MORE_PROCESSING_REQUIRED)) {
    1712                         tevent_req_nterror(
    1713                                 req, NT_STATUS_INVALID_NETWORK_RESPONSE);
    1714                         return;
    1715                 }
    1716         }
    1717 
    1718         status = ntlmssp_update(state->ntlmssp_state, msg_in, &blob_out);
    1719 
    1720         if (!NT_STATUS_IS_OK(status)
    1721             && !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
    1722                 TALLOC_FREE(subreq);
    1723                 TALLOC_FREE(state->ntlmssp_state);
    1724                 tevent_req_nterror(req, status);
    1725                 return;
    1726         }
    1727 
    1728         state->blob_out = spnego_gen_auth(state, blob_out);
    1729         TALLOC_FREE(subreq);
    1730         if (tevent_req_nomem(state->blob_out.data, req)) {
    1731                 return;
    1732         }
    1733 
    1734         subreq = cli_sesssetup_blob_send(state, state->ev, state->cli,
    1735                                          state->blob_out);
    1736         if (tevent_req_nomem(subreq, req)) {
    1737                 return;
    1738         }
    1739         tevent_req_set_callback(subreq, cli_session_setup_ntlmssp_done, req);
    1740 }
    1741 
    1742 static NTSTATUS cli_session_setup_ntlmssp_recv(struct tevent_req *req)
    1743 {
    1744         struct cli_session_setup_ntlmssp_state *state = tevent_req_data(
    1745                 req, struct cli_session_setup_ntlmssp_state);
    1746         NTSTATUS status;
    1747 
    1748         if (tevent_req_is_nterror(req, &status)) {
    1749                 state->cli->vuid = 0;
    1750                 return status;
    1751         }
    1752         return NT_STATUS_OK;
    1753 }
    1754 
    1755 static NTSTATUS cli_session_setup_ntlmssp(struct cli_state *cli,
    1756                                           const char *user,
    1757                                           const char *pass,
    1758                                           const char *domain)
    1759 {
    1760         struct tevent_context *ev;
    1761         struct tevent_req *req;
    1762         NTSTATUS status = NT_STATUS_NO_MEMORY;
    1763 
    1764         if (cli_has_async_calls(cli)) {
    1765                 return NT_STATUS_INVALID_PARAMETER;
    1766         }
    1767         ev = tevent_context_init(talloc_tos());
    1768         if (ev == NULL) {
    1769                 goto fail;
    1770         }
    1771         req = cli_session_setup_ntlmssp_send(ev, ev, cli, user, pass, domain);
    1772         if (req == NULL) {
    1773                 goto fail;
    1774         }
    1775         if (!tevent_req_poll_ntstatus(req, ev, &status)) {
    1776                 goto fail;
    1777         }
    1778         status = cli_session_setup_ntlmssp_recv(req);
    1779 fail:
    1780         TALLOC_FREE(ev);
    1781         return status;
     1750                principal = kerberos_get_principal_from_service_hostname(
     1751                        talloc_tos(), "cifs", remote_name, lp_realm());
     1752        }
     1753        DEBUG(3, ("cli_session_setup_spnego: guessed server principal=%s\n",
     1754                  principal ? principal : "<null>"));
     1755
     1756        return principal;
     1757}
     1758#endif
     1759
     1760static char *cli_session_setup_get_account(TALLOC_CTX *mem_ctx,
     1761                                           const char *principal)
     1762{
     1763        char *account, *p;
     1764
     1765        account = talloc_strdup(mem_ctx, principal);
     1766        if (account == NULL) {
     1767                return NULL;
     1768        }
     1769        p = strchr_m(account, '@');
     1770        if (p != NULL) {
     1771                *p = '\0';
     1772        }
     1773        return account;
    17821774}
    17831775
     
    17891781****************************************************************************/
    17901782
    1791 ADS_STATUS cli_session_setup_spnego(struct cli_state *cli, const char *user,
    1792                               const char *pass, const char *user_domain,
    1793                               const char * dest_realm)
    1794 {
     1783struct cli_session_setup_spnego_state {
     1784        struct tevent_context *ev;
     1785        struct cli_state *cli;
     1786        const char *target_hostname;
     1787        const char *user;
     1788        const char *account;
     1789        const char *pass;
     1790        const char *user_domain;
     1791        const char *dest_realm;
     1792        ADS_STATUS result;
     1793};
     1794
     1795#ifdef HAVE_KRB5
     1796static void cli_session_setup_spnego_done_krb(struct tevent_req *subreq);
     1797#endif
     1798
     1799static void cli_session_setup_spnego_done_ntlmssp(struct tevent_req *subreq);
     1800
     1801static struct tevent_req *cli_session_setup_spnego_send(
     1802        TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct cli_state *cli,
     1803        const char *user, const char *pass, const char *user_domain)
     1804{
     1805        struct tevent_req *req, *subreq;
     1806        struct cli_session_setup_spnego_state *state;
    17951807        char *principal = NULL;
    17961808        char *OIDs[ASN1_MAX_OIDS];
    17971809        int i;
    1798         DATA_BLOB blob;
    1799         const char *p = NULL;
    1800         char *account = NULL;
    1801         NTSTATUS status;
    1802 
    1803         DEBUG(3,("Doing spnego session setup (blob length=%lu)\n", (unsigned long)cli->secblob.length));
     1810        const char *dest_realm = cli_state_remote_realm(cli);
     1811        const DATA_BLOB *server_blob;
     1812
     1813        req = tevent_req_create(mem_ctx, &state,
     1814                                struct cli_session_setup_spnego_state);
     1815        if (req == NULL) {
     1816                return NULL;
     1817        }
     1818        state->ev = ev;
     1819        state->cli = cli;
     1820        state->user = user;
     1821        state->pass = pass;
     1822        state->user_domain = user_domain;
     1823        state->dest_realm = dest_realm;
     1824
     1825        state->account = cli_session_setup_get_account(state, user);
     1826        if (tevent_req_nomem(state->account, req)) {
     1827                return tevent_req_post(req, ev);
     1828        }
     1829
     1830        state->target_hostname = smbXcli_conn_remote_name(cli->conn);
     1831        server_blob = smbXcli_conn_server_gss_blob(cli->conn);
     1832
     1833        DEBUG(3,("Doing spnego session setup (blob length=%lu)\n",
     1834                 (unsigned long)server_blob->length));
    18041835
    18051836        /* the server might not even do spnego */
    1806         if (cli->secblob.length <= 16) {
     1837        if (server_blob->length == 0) {
    18071838                DEBUG(3,("server didn't supply a full spnego negprot\n"));
    18081839                goto ntlmssp;
     
    18121843        file_save("negprot.dat", cli->secblob.data, cli->secblob.length);
    18131844#endif
    1814 
    1815         /* there is 16 bytes of GUID before the real spnego packet starts */
    1816         blob = data_blob(cli->secblob.data+16, cli->secblob.length-16);
    18171845
    18181846        /* The server sent us the first part of the SPNEGO exchange in the
     
    18201848         * negprot reply, but right now we do it. If we don't receive one,
    18211849         * we try to best guess, then fall back to NTLM.  */
    1822         if (!spnego_parse_negTokenInit(talloc_tos(), blob, OIDs, &principal, NULL) ||
     1850        if (!spnego_parse_negTokenInit(state, *server_blob, OIDs,
     1851                                       &principal, NULL) ||
    18231852                        OIDs[0] == NULL) {
    1824                 data_blob_free(&blob);
    1825                 return ADS_ERROR_NT(NT_STATUS_INVALID_PARAMETER);
    1826         }
    1827         data_blob_free(&blob);
     1853                state->result = ADS_ERROR_NT(NT_STATUS_INVALID_PARAMETER);
     1854                tevent_req_done(req);
     1855                return tevent_req_post(req, ev);
     1856        }
    18281857
    18291858        /* make sure the server understands kerberos */
     
    18421871        DEBUG(3,("got principal=%s\n", principal ? principal : "<null>"));
    18431872
    1844         status = cli_set_username(cli, user);
    1845         if (!NT_STATUS_IS_OK(status)) {
    1846                 TALLOC_FREE(principal);
    1847                 return ADS_ERROR_NT(status);
    1848         }
    1849 
    18501873#ifdef HAVE_KRB5
    18511874        /* If password is set we reauthenticate to kerberos server
    18521875         * and do not store results */
    18531876
    1854         if (cli->got_kerberos_mechanism && cli->use_kerberos) {
    1855                 ADS_STATUS rc;
     1877        if (user && *user && cli->got_kerberos_mechanism && cli->use_kerberos) {
     1878                char *tmp;
     1879
     1880                tmp = cli_session_setup_get_principal(
     1881                        talloc_tos(), principal, state->target_hostname, dest_realm);
     1882                TALLOC_FREE(principal);
     1883                principal = tmp;
    18561884
    18571885                if (pass && *pass) {
     
    18621890
    18631891                        if (ret){
     1892                                DEBUG(0, ("Kinit for %s to access %s failed: %s\n", user, principal, error_message(ret)));
    18641893                                TALLOC_FREE(principal);
    1865                                 DEBUG(0, ("Kinit failed: %s\n", error_message(ret)));
    18661894                                if (cli->fallback_after_kerberos)
    18671895                                        goto ntlmssp;
    1868                                 return ADS_ERROR_KRB5(ret);
     1896                                state->result = ADS_ERROR_KRB5(ret);
     1897                                tevent_req_done(req);
     1898                                return tevent_req_post(req, ev);
    18691899                        }
    18701900                }
    18711901
    1872                 /* We may not be allowed to use the server-supplied SPNEGO principal, or it may not have been supplied to us
    1873                  */
    1874                 if (!lp_client_use_spnego_principal() || strequal(principal, ADS_IGNORE_PRINCIPAL)) {
    1875                         TALLOC_FREE(principal);
    1876                 }
    1877 
    1878                 if (principal == NULL &&
    1879                         !is_ipaddress(cli->desthost) &&
    1880                         !strequal(STAR_SMBSERVER,
    1881                                 cli->desthost)) {
    1882                         char *realm = NULL;
    1883                         char *host = NULL;
    1884                         DEBUG(3,("cli_session_setup_spnego: using target "
    1885                                  "hostname not SPNEGO principal\n"));
    1886 
    1887                         host = strchr_m(cli->desthost, '.');
    1888                         if (dest_realm) {
    1889                                 realm = SMB_STRDUP(dest_realm);
    1890                                 if (!realm) {
    1891                                         return ADS_ERROR_NT(NT_STATUS_NO_MEMORY);
    1892                                 }
    1893                                 strupper_m(realm);
    1894                         } else {
    1895                                 if (host) {
    1896                                         /* DNS name. */
    1897                                         realm = kerberos_get_realm_from_hostname(cli->desthost);
    1898                                 } else {
    1899                                         /* NetBIOS name - use our realm. */
    1900                                         realm = kerberos_get_default_realm_from_ccache();
    1901                                 }
     1902                if (principal) {
     1903                        subreq = cli_session_setup_gensec_send(
     1904                                state, ev, cli,
     1905                                state->account, pass, user_domain,
     1906                                CRED_MUST_USE_KERBEROS,
     1907                                "cifs", state->target_hostname, principal);
     1908                        if (tevent_req_nomem(subreq, req)) {
     1909                                return tevent_req_post(req, ev);
    19021910                        }
    1903 
    1904                         if (realm == NULL || *realm == '\0') {
    1905                                 realm = SMB_STRDUP(lp_realm());
    1906                                 if (!realm) {
    1907                                         return ADS_ERROR_NT(NT_STATUS_NO_MEMORY);
    1908                                 }
    1909                                 strupper_m(realm);
    1910                                 DEBUG(3,("cli_session_setup_spnego: cannot "
    1911                                         "get realm from dest_realm %s, "
    1912                                         "desthost %s. Using default "
    1913                                         "smb.conf realm %s\n",
    1914                                         dest_realm ? dest_realm : "<null>",
    1915                                         cli->desthost,
    1916                                         realm));
    1917                         }
    1918 
    1919                         principal = talloc_asprintf(talloc_tos(),
    1920                                                     "cifs/%s@%s",
    1921                                                     cli->desthost,
    1922                                                     realm);
    1923                         if (!principal) {
    1924                                 SAFE_FREE(realm);
    1925                                 return ADS_ERROR_NT(NT_STATUS_NO_MEMORY);
    1926                         }
    1927                         DEBUG(3,("cli_session_setup_spnego: guessed "
    1928                                 "server principal=%s\n",
    1929                                 principal ? principal : "<null>"));
    1930 
    1931                         SAFE_FREE(realm);
    1932                 }
    1933 
    1934                 if (principal) {
    1935                         rc = cli_session_setup_kerberos(cli, principal,
    1936                                 dest_realm);
    1937                         if (ADS_ERR_OK(rc) || !cli->fallback_after_kerberos) {
    1938                                 TALLOC_FREE(principal);
    1939                                 return rc;
    1940                         }
     1911                        tevent_req_set_callback(
     1912                                subreq, cli_session_setup_spnego_done_krb,
     1913                                req);
     1914                        return req;
    19411915                }
    19421916        }
    19431917#endif
    19441918
    1945         TALLOC_FREE(principal);
    1946 
    19471919ntlmssp:
    1948 
    1949         account = talloc_strdup(talloc_tos(), user);
    1950         if (!account) {
    1951                 return ADS_ERROR_NT(NT_STATUS_NO_MEMORY);
    1952         }
    1953 
    1954         /* when falling back to ntlmssp while authenticating with a machine
    1955          * account strip off the realm - gd */
    1956 
    1957         if ((p = strchr_m(user, '@')) != NULL) {
    1958                 account[PTR_DIFF(p,user)] = '\0';
    1959         }
    1960 
    1961         return ADS_ERROR_NT(cli_session_setup_ntlmssp(cli, account, pass, user_domain));
    1962 }
     1920        subreq = cli_session_setup_gensec_send(
     1921                state, state->ev, state->cli,
     1922                state->account, state->pass, state->user_domain,
     1923                CRED_DONT_USE_KERBEROS,
     1924                "cifs", state->target_hostname, NULL);
     1925        if (tevent_req_nomem(subreq, req)) {
     1926                return tevent_req_post(req, ev);
     1927        }
     1928        tevent_req_set_callback(
     1929                subreq, cli_session_setup_spnego_done_ntlmssp, req);
     1930        return req;
     1931}
     1932
     1933#ifdef HAVE_KRB5
     1934static void cli_session_setup_spnego_done_krb(struct tevent_req *subreq)
     1935{
     1936        struct tevent_req *req = tevent_req_callback_data(
     1937                subreq, struct tevent_req);
     1938        struct cli_session_setup_spnego_state *state = tevent_req_data(
     1939                req, struct cli_session_setup_spnego_state);
     1940        NTSTATUS status;
     1941
     1942        status = cli_session_setup_gensec_recv(subreq);
     1943        TALLOC_FREE(subreq);
     1944        state->result = ADS_ERROR_NT(status);
     1945
     1946        if (ADS_ERR_OK(state->result) ||
     1947            !state->cli->fallback_after_kerberos) {
     1948                tevent_req_done(req);
     1949                return;
     1950        }
     1951
     1952        subreq = cli_session_setup_gensec_send(
     1953                state, state->ev, state->cli,
     1954                state->account, state->pass, state->user_domain,
     1955                CRED_DONT_USE_KERBEROS,
     1956                "cifs", state->target_hostname, NULL);
     1957        if (tevent_req_nomem(subreq, req)) {
     1958                return;
     1959        }
     1960        tevent_req_set_callback(subreq, cli_session_setup_spnego_done_ntlmssp,
     1961                                req);
     1962}
     1963#endif
     1964
     1965static void cli_session_setup_spnego_done_ntlmssp(struct tevent_req *subreq)
     1966{
     1967        struct tevent_req *req = tevent_req_callback_data(
     1968                subreq, struct tevent_req);
     1969        struct cli_session_setup_spnego_state *state = tevent_req_data(
     1970                req, struct cli_session_setup_spnego_state);
     1971        NTSTATUS status;
     1972
     1973        status = cli_session_setup_gensec_recv(subreq);
     1974        TALLOC_FREE(subreq);
     1975        state->result = ADS_ERROR_NT(status);
     1976        tevent_req_done(req);
     1977}
     1978
     1979static ADS_STATUS cli_session_setup_spnego_recv(struct tevent_req *req)
     1980{
     1981        struct cli_session_setup_spnego_state *state = tevent_req_data(
     1982                req, struct cli_session_setup_spnego_state);
     1983
     1984        return state->result;
     1985}
     1986
     1987struct cli_session_setup_state {
     1988        uint8_t dummy;
     1989};
     1990
     1991static void cli_session_setup_done_lanman2(struct tevent_req *subreq);
     1992static void cli_session_setup_done_spnego(struct tevent_req *subreq);
     1993static void cli_session_setup_done_guest(struct tevent_req *subreq);
     1994static void cli_session_setup_done_plain(struct tevent_req *subreq);
     1995static void cli_session_setup_done_nt1(struct tevent_req *subreq);
    19631996
    19641997/****************************************************************************
     
    19682001****************************************************************************/
    19692002
    1970 NTSTATUS cli_session_setup(struct cli_state *cli,
    1971                            const char *user,
    1972                            const char *pass, int passlen,
    1973                            const char *ntpass, int ntpasslen,
    1974                            const char *workgroup)
    1975 {
     2003struct tevent_req *cli_session_setup_send(TALLOC_CTX *mem_ctx,
     2004                                          struct tevent_context *ev,
     2005                                          struct cli_state *cli,
     2006                                          const char *user,
     2007                                          const char *pass, int passlen,
     2008                                          const char *ntpass, int ntpasslen,
     2009                                          const char *workgroup)
     2010{
     2011        struct tevent_req *req, *subreq;
     2012        struct cli_session_setup_state *state;
    19762013        char *p;
    19772014        char *user2;
     2015        uint16_t sec_mode = smb1cli_conn_server_security_mode(cli->conn);
     2016
     2017        req = tevent_req_create(mem_ctx, &state,
     2018                                struct cli_session_setup_state);
     2019        if (req == NULL) {
     2020                return NULL;
     2021        }
    19782022
    19792023        if (user) {
    1980                 user2 = talloc_strdup(talloc_tos(), user);
     2024                user2 = talloc_strdup(state, user);
    19812025        } else {
    1982                 user2 = talloc_strdup(talloc_tos(), "");
     2026                user2 = talloc_strdup(state, "");
    19832027        }
    19842028        if (user2 == NULL) {
    1985                 return NT_STATUS_NO_MEMORY;
     2029                tevent_req_oom(req);
     2030                return tevent_req_post(req, ev);
    19862031        }
    19872032
     
    19952040                *p = 0;
    19962041                user = p+1;
    1997                 strupper_m(user2);
     2042                if (!strupper_m(user2)) {
     2043                        tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
     2044                        return tevent_req_post(req, ev);
     2045                }
    19982046                workgroup = user2;
    19992047        }
    20002048
    2001         if (cli->protocol < PROTOCOL_LANMAN1) {
    2002                 /*
    2003                  * Ensure cli->server_domain,
    2004                  * cli->server_os and cli->server_type
    2005                  * are valid pointers.
    2006                  */
    2007                 cli->server_domain = talloc_strdup(cli, "");
    2008                 cli->server_os = talloc_strdup(cli, "");
    2009                 cli->server_type = talloc_strdup(cli, "");
    2010                 if (cli->server_domain == NULL ||
    2011                                 cli->server_os == NULL ||
    2012                                 cli->server_type == NULL) {
    2013                         return NT_STATUS_NO_MEMORY;
    2014                 }
    2015                 return NT_STATUS_OK;
     2049        if (smbXcli_conn_protocol(cli->conn) < PROTOCOL_LANMAN1) {
     2050                tevent_req_done(req);
     2051                return tevent_req_post(req, ev);
    20162052        }
    20172053
     
    20222058        /* if its an older server then we have to use the older request format */
    20232059
    2024         if (cli->protocol < PROTOCOL_NT1) {
     2060        if (smbXcli_conn_protocol(cli->conn) < PROTOCOL_NT1) {
    20252061                if (!lp_client_lanman_auth() && passlen != 24 && (*pass)) {
    20262062                        DEBUG(1, ("Server requested LM password but 'client lanman auth = no'"
    20272063                                  " or 'client ntlmv2 auth = yes'\n"));
    2028                         return NT_STATUS_ACCESS_DENIED;
    2029                 }
    2030 
    2031                 if ((cli->sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) == 0 &&
     2064                        tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
     2065                        return tevent_req_post(req, ev);
     2066                }
     2067
     2068                if ((sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) == 0 &&
    20322069                    !lp_client_plaintext_auth() && (*pass)) {
    2033                         DEBUG(1, ("Server requested LM password but 'client plaintext auth = no'"
     2070                        DEBUG(1, ("Server requested PLAINTEXT password but 'client plaintext auth = no'"
    20342071                                  " or 'client ntlmv2 auth = yes'\n"));
    2035                         return NT_STATUS_ACCESS_DENIED;
    2036                 }
    2037 
    2038                 return cli_session_setup_lanman2(cli, user, pass, passlen,
    2039                                                  workgroup);
     2072                        tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
     2073                        return tevent_req_post(req, ev);
     2074                }
     2075
     2076                subreq = cli_session_setup_lanman2_send(
     2077                        state, ev, cli, user, pass, passlen, workgroup);
     2078                if (tevent_req_nomem(subreq, req)) {
     2079                        return tevent_req_post(req, ev);
     2080                }
     2081                tevent_req_set_callback(subreq, cli_session_setup_done_lanman2,
     2082                                        req);
     2083                return req;
     2084        }
     2085
     2086        if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) {
     2087                subreq = cli_session_setup_spnego_send(
     2088                        state, ev, cli, user, pass, workgroup);
     2089                if (tevent_req_nomem(subreq, req)) {
     2090                        return tevent_req_post(req, ev);
     2091                }
     2092                tevent_req_set_callback(subreq, cli_session_setup_done_spnego,
     2093                                        req);
     2094                return req;
     2095        }
     2096
     2097        /*
     2098         * if the server supports extended security then use SPNEGO
     2099         * even for anonymous connections.
     2100         */
     2101        if (smb1cli_conn_capabilities(cli->conn) & CAP_EXTENDED_SECURITY) {
     2102                subreq = cli_session_setup_spnego_send(
     2103                        state, ev, cli, user, pass, workgroup);
     2104                if (tevent_req_nomem(subreq, req)) {
     2105                        return tevent_req_post(req, ev);
     2106                }
     2107                tevent_req_set_callback(subreq, cli_session_setup_done_spnego,
     2108                                        req);
     2109                return req;
    20402110        }
    20412111
     
    20432113           passwords are ignored */
    20442114
    2045         if (!user || !*user)
    2046                 return cli_session_setup_guest(cli);
     2115        if (!user || !*user) {
     2116                subreq = cli_session_setup_guest_send(state, ev, cli);
     2117                if (tevent_req_nomem(subreq, req)) {
     2118                        return tevent_req_post(req, ev);
     2119                }
     2120                tevent_req_set_callback(subreq, cli_session_setup_done_guest,
     2121                                        req);
     2122                return req;
     2123        }
    20472124
    20482125        /* if the server is share level then send a plaintext null
     
    20502127           connect */
    20512128
    2052         if ((cli->sec_mode & NEGOTIATE_SECURITY_USER_LEVEL) == 0)
    2053                 return cli_session_setup_plain(cli, user, "", workgroup);
     2129        if ((sec_mode & NEGOTIATE_SECURITY_USER_LEVEL) == 0) {
     2130                subreq = cli_session_setup_plain_send(
     2131                        state, ev, cli, user, "", workgroup);
     2132                if (tevent_req_nomem(subreq, req)) {
     2133                        return tevent_req_post(req, ev);
     2134                }
     2135                tevent_req_set_callback(subreq, cli_session_setup_done_plain,
     2136                                        req);
     2137                return req;
     2138        }
    20542139
    20552140        /* if the server doesn't support encryption then we have to use
    20562141           plaintext. The second password is ignored */
    20572142
    2058         if ((cli->sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) == 0) {
     2143        if ((sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) == 0) {
    20592144                if (!lp_client_plaintext_auth() && (*pass)) {
    2060                         DEBUG(1, ("Server requested LM password but 'client plaintext auth = no'"
     2145                        DEBUG(1, ("Server requested PLAINTEXT password but 'client plaintext auth = no'"
    20612146                                  " or 'client ntlmv2 auth = yes'\n"));
    2062                         return NT_STATUS_ACCESS_DENIED;
    2063                 }
    2064                 return cli_session_setup_plain(cli, user, pass, workgroup);
    2065         }
    2066 
    2067         /* if the server supports extended security then use SPNEGO */
    2068 
    2069         if (cli->capabilities & CAP_EXTENDED_SECURITY) {
    2070                 ADS_STATUS status = cli_session_setup_spnego(cli, user, pass,
    2071                                                              workgroup, NULL);
    2072                 if (!ADS_ERR_OK(status)) {
    2073                         DEBUG(3, ("SPNEGO login failed: %s\n", ads_errstr(status)));
    2074                         return ads_ntstatus(status);
    2075                 }
    2076         } else {
    2077                 NTSTATUS status;
    2078 
     2147                        tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
     2148                        return tevent_req_post(req, ev);
     2149                }
     2150                subreq = cli_session_setup_plain_send(
     2151                        state, ev, cli, user, pass, workgroup);
     2152                if (tevent_req_nomem(subreq, req)) {
     2153                        return tevent_req_post(req, ev);
     2154                }
     2155                tevent_req_set_callback(subreq, cli_session_setup_done_plain,
     2156                                        req);
     2157                return req;
     2158        }
     2159
     2160        {
    20792161                /* otherwise do a NT1 style session setup */
    20802162                if (lp_client_ntlmv2_auth() && lp_client_use_spnego()) {
     
    20862168                                  " but 'client use spnego = yes"
    20872169                                  " and 'client ntlmv2 auth = yes'\n"));
    2088                         return NT_STATUS_ACCESS_DENIED;
    2089                 }
    2090 
    2091                 status = cli_session_setup_nt1(cli, user, pass, passlen,
    2092                                                ntpass, ntpasslen, workgroup);
    2093                 if (!NT_STATUS_IS_OK(status)) {
    2094                         DEBUG(3,("cli_session_setup: NT1 session setup "
    2095                                  "failed: %s\n", nt_errstr(status)));
    2096                         return status;
    2097                 }
    2098         }
    2099 
    2100         if (strstr(cli->server_type, "Samba")) {
    2101                 cli->is_samba = True;
    2102         }
    2103 
    2104         return NT_STATUS_OK;
     2170                        tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
     2171                        return tevent_req_post(req, ev);
     2172                }
     2173
     2174                subreq = cli_session_setup_nt1_send(
     2175                        state, ev, cli, user, pass, passlen, ntpass, ntpasslen,
     2176                        workgroup);
     2177                if (tevent_req_nomem(subreq, req)) {
     2178                        return tevent_req_post(req, ev);
     2179                }
     2180                tevent_req_set_callback(subreq, cli_session_setup_done_nt1,
     2181                                        req);
     2182                return req;
     2183        }
     2184
     2185        tevent_req_done(req);
     2186        return tevent_req_post(req, ev);
     2187}
     2188
     2189static void cli_session_setup_done_lanman2(struct tevent_req *subreq)
     2190{
     2191        struct tevent_req *req = tevent_req_callback_data(
     2192                subreq, struct tevent_req);
     2193        NTSTATUS status;
     2194
     2195        status = cli_session_setup_lanman2_recv(subreq);
     2196        TALLOC_FREE(subreq);
     2197        if (!NT_STATUS_IS_OK(status)) {
     2198                tevent_req_nterror(req, status);
     2199                return;
     2200        }
     2201        tevent_req_done(req);
     2202}
     2203
     2204static void cli_session_setup_done_spnego(struct tevent_req *subreq)
     2205{
     2206        struct tevent_req *req = tevent_req_callback_data(
     2207                subreq, struct tevent_req);
     2208        ADS_STATUS status;
     2209
     2210        status = cli_session_setup_spnego_recv(subreq);
     2211        TALLOC_FREE(subreq);
     2212        if (!ADS_ERR_OK(status)) {
     2213                DEBUG(3, ("SPNEGO login failed: %s\n", ads_errstr(status)));
     2214                tevent_req_nterror(req, ads_ntstatus(status));
     2215                return;
     2216        }
     2217        tevent_req_done(req);
     2218}
     2219
     2220static void cli_session_setup_done_guest(struct tevent_req *subreq)
     2221{
     2222        struct tevent_req *req = tevent_req_callback_data(
     2223                subreq, struct tevent_req);
     2224        NTSTATUS status;
     2225
     2226        status = cli_session_setup_guest_recv(subreq);
     2227        TALLOC_FREE(subreq);
     2228        if (!NT_STATUS_IS_OK(status)) {
     2229                tevent_req_nterror(req, status);
     2230                return;
     2231        }
     2232        tevent_req_done(req);
     2233}
     2234
     2235static void cli_session_setup_done_plain(struct tevent_req *subreq)
     2236{
     2237        struct tevent_req *req = tevent_req_callback_data(
     2238                subreq, struct tevent_req);
     2239        NTSTATUS status;
     2240
     2241        status = cli_session_setup_plain_recv(subreq);
     2242        TALLOC_FREE(subreq);
     2243        if (!NT_STATUS_IS_OK(status)) {
     2244                tevent_req_nterror(req, status);
     2245                return;
     2246        }
     2247        tevent_req_done(req);
     2248}
     2249
     2250static void cli_session_setup_done_nt1(struct tevent_req *subreq)
     2251{
     2252        struct tevent_req *req = tevent_req_callback_data(
     2253                subreq, struct tevent_req);
     2254        NTSTATUS status;
     2255
     2256        status = cli_session_setup_nt1_recv(subreq);
     2257        TALLOC_FREE(subreq);
     2258        if (!NT_STATUS_IS_OK(status)) {
     2259                DEBUG(3, ("cli_session_setup: NT1 session setup "
     2260                          "failed: %s\n", nt_errstr(status)));
     2261                tevent_req_nterror(req, status);
     2262                return;
     2263        }
     2264        tevent_req_done(req);
     2265}
     2266
     2267NTSTATUS cli_session_setup_recv(struct tevent_req *req)
     2268{
     2269        return tevent_req_simple_recv_ntstatus(req);
     2270}
     2271
     2272NTSTATUS cli_session_setup(struct cli_state *cli,
     2273                           const char *user,
     2274                           const char *pass, int passlen,
     2275                           const char *ntpass, int ntpasslen,
     2276                           const char *workgroup)
     2277{
     2278        struct tevent_context *ev;
     2279        struct tevent_req *req;
     2280        NTSTATUS status = NT_STATUS_NO_MEMORY;
     2281
     2282        if (smbXcli_conn_has_async_calls(cli->conn)) {
     2283                return NT_STATUS_INVALID_PARAMETER;
     2284        }
     2285        ev = samba_tevent_context_init(talloc_tos());
     2286        if (ev == NULL) {
     2287                goto fail;
     2288        }
     2289        req = cli_session_setup_send(ev, ev, cli, user, pass, passlen,
     2290                                     ntpass, ntpasslen, workgroup);
     2291        if (req == NULL) {
     2292                goto fail;
     2293        }
     2294        if (!tevent_req_poll_ntstatus(req, ev, &status)) {
     2295                goto fail;
     2296        }
     2297        status = cli_session_setup_recv(req);
     2298 fail:
     2299        TALLOC_FREE(ev);
     2300        return status;
    21052301}
    21062302
     
    21162312static void cli_ulogoff_done(struct tevent_req *subreq);
    21172313
    2118 struct tevent_req *cli_ulogoff_send(TALLOC_CTX *mem_ctx,
     2314static struct tevent_req *cli_ulogoff_send(TALLOC_CTX *mem_ctx,
    21192315                                    struct tevent_context *ev,
    21202316                                    struct cli_state *cli)
     
    21552351                return;
    21562352        }
    2157         state->cli->vuid = -1;
     2353        cli_state_set_uid(state->cli, UID_FIELD_INVALID);
    21582354        tevent_req_done(req);
    21592355}
    21602356
    2161 NTSTATUS cli_ulogoff_recv(struct tevent_req *req)
     2357static NTSTATUS cli_ulogoff_recv(struct tevent_req *req)
    21622358{
    21632359        return tevent_req_simple_recv_ntstatus(req);
     
    21702366        NTSTATUS status = NT_STATUS_NO_MEMORY;
    21712367
    2172         if (cli_has_async_calls(cli)) {
     2368        if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) {
     2369                status = smb2cli_logoff(cli->conn,
     2370                                        cli->timeout,
     2371                                        cli->smb2.session);
     2372                if (!NT_STATUS_IS_OK(status)) {
     2373                        return status;
     2374                }
     2375                smb2cli_session_set_id_and_flags(cli->smb2.session,
     2376                                                 UINT64_MAX, 0);
     2377                return NT_STATUS_OK;
     2378        }
     2379
     2380        if (smbXcli_conn_has_async_calls(cli->conn)) {
    21732381                return NT_STATUS_INVALID_PARAMETER;
    21742382        }
    2175         ev = tevent_context_init(talloc_tos());
     2383        ev = samba_tevent_context_init(talloc_tos());
    21762384        if (ev == NULL) {
    21772385                goto fail;
     
    22032411
    22042412struct tevent_req *cli_tcon_andx_create(TALLOC_CTX *mem_ctx,
    2205                                         struct event_context *ev,
     2413                                        struct tevent_context *ev,
    22062414                                        struct cli_state *cli,
    22072415                                        const char *share, const char *dev,
     
    22152423        char *tmp = NULL;
    22162424        uint8_t *bytes;
     2425        uint16_t sec_mode = smb1cli_conn_server_security_mode(cli->conn);
     2426        uint16_t tcon_flags = 0;
    22172427
    22182428        *psmbreq = NULL;
     
    22312441
    22322442        /* in user level security don't send a password now */
    2233         if (cli->sec_mode & NEGOTIATE_SECURITY_USER_LEVEL) {
     2443        if (sec_mode & NEGOTIATE_SECURITY_USER_LEVEL) {
    22342444                passlen = 1;
    22352445                pass = "";
     
    22402450        }
    22412451
    2242         if ((cli->sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) &&
     2452        if ((sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) &&
    22432453            *pass && passlen != 24) {
    22442454                if (!lp_client_lanman_auth()) {
     
    22532463                 * encryption.
    22542464                 */
    2255                 SMBencrypt(pass, cli->secblob.data, p24);
     2465                SMBencrypt(pass, smb1cli_conn_server_challenge(cli->conn), p24);
    22562466                passlen = 24;
    22572467                pass = (const char *)p24;
    22582468        } else {
    2259                 if((cli->sec_mode & (NEGOTIATE_SECURITY_USER_LEVEL
     2469                if((sec_mode & (NEGOTIATE_SECURITY_USER_LEVEL
    22602470                                     |NEGOTIATE_SECURITY_CHALLENGE_RESPONSE))
    22612471                   == 0) {
    2262                         char *tmp_pass;
     2472                        uint8_t *tmp_pass;
    22632473
    22642474                        if (!lp_client_plaintext_auth() && (*pass)) {
    2265                                 DEBUG(1, ("Server requested plaintext "
     2475                                DEBUG(1, ("Server requested PLAINTEXT "
    22662476                                          "password but "
    2267                                           "'client lanman auth = no' or 'client ntlmv2 auth = yes'\n"));
     2477                                          "'client plaintext auth = no' or 'client ntlmv2 auth = yes'\n"));
    22682478                                goto access_denied;
    22692479                        }
     
    22732483                         * before using.
    22742484                         */
    2275                         tmp_pass = talloc_array(talloc_tos(), char, 128);
    2276                         if (tmp_pass == NULL) {
    2277                                 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
     2485                        tmp_pass = talloc_array(talloc_tos(), uint8_t, 0);
     2486                        if (tevent_req_nomem(tmp_pass, req)) {
    22782487                                return tevent_req_post(req, ev);
    22792488                        }
    2280                         passlen = clistr_push(cli,
    2281                                         tmp_pass,
    2282                                         pass,
    2283                                         talloc_get_size(tmp_pass),
    2284                                         STR_TERMINATE);
    2285                         if (passlen == -1) {
    2286                                 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
     2489                        tmp_pass = trans2_bytes_push_str(tmp_pass,
     2490                                                         false, /* always DOS */
     2491                                                         pass,
     2492                                                         passlen,
     2493                                                         NULL);
     2494                        if (tevent_req_nomem(tmp_pass, req)) {
    22872495                                return tevent_req_post(req, ev);
    22882496                        }
    2289                         pass = tmp_pass;
    2290                 }
    2291         }
     2497                        pass = (const char *)tmp_pass;
     2498                        passlen = talloc_get_size(tmp_pass);
     2499                }
     2500        }
     2501
     2502        tcon_flags |= TCONX_FLAG_EXTENDED_RESPONSE;
     2503        tcon_flags |= TCONX_FLAG_EXTENDED_SIGNATURES;
    22922504
    22932505        SCVAL(vwv+0, 0, 0xFF);
    22942506        SCVAL(vwv+0, 1, 0);
    22952507        SSVAL(vwv+1, 0, 0);
    2296         SSVAL(vwv+2, 0, TCONX_FLAG_EXTENDED_RESPONSE);
     2508        SSVAL(vwv+2, 0, tcon_flags);
    22972509        SSVAL(vwv+3, 0, passlen);
    22982510
     
    23072519         */
    23082520        tmp = talloc_asprintf_strupper_m(talloc_tos(), "\\\\%s\\%s",
    2309                                          cli->desthost, share);
     2521                                         smbXcli_conn_remote_name(cli->conn), share);
    23102522        if (tmp == NULL) {
    23112523                TALLOC_FREE(req);
    23122524                return NULL;
    23132525        }
    2314         bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), tmp, strlen(tmp)+1,
     2526        bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn), tmp, strlen(tmp)+1,
    23152527                                   NULL);
    23162528        TALLOC_FREE(tmp);
     
    23512563
    23522564struct tevent_req *cli_tcon_andx_send(TALLOC_CTX *mem_ctx,
    2353                                       struct event_context *ev,
     2565                                      struct tevent_context *ev,
    23542566                                      struct cli_state *cli,
    23552567                                      const char *share, const char *dev,
     
    23672579                return req;
    23682580        }
    2369         status = cli_smb_req_send(subreq);
     2581        status = smb1cli_req_chain_submit(&subreq, 1);
    23702582        if (!NT_STATUS_IS_OK(status)) {
    23712583                tevent_req_nterror(req, status);
     
    23832595        struct cli_state *cli = state->cli;
    23842596        uint8_t *in;
    2385         char *inbuf;
     2597        uint8_t *inhdr;
    23862598        uint8_t wct;
    23872599        uint16_t *vwv;
     
    23892601        uint8_t *bytes;
    23902602        NTSTATUS status;
     2603        uint16_t optional_support = 0;
    23912604
    23922605        status = cli_smb_recv(subreq, state, &in, 0, &wct, &vwv,
     
    23982611        }
    23992612
    2400         inbuf = (char *)in;
     2613        inhdr = in + NBT_HDR_SIZE;
    24012614
    24022615        if (num_bytes) {
    24032616                if (clistr_pull_talloc(cli,
    2404                                 inbuf,
    2405                                 SVAL(inbuf, smb_flg2),
     2617                                (const char *)inhdr,
     2618                                SVAL(inhdr, HDR_FLG2),
    24062619                                &cli->dev,
    24072620                                bytes,
     
    24192632        }
    24202633
    2421         if ((cli->protocol >= PROTOCOL_NT1) && (num_bytes == 3)) {
     2634        if ((smbXcli_conn_protocol(cli->conn) >= PROTOCOL_NT1) && (num_bytes == 3)) {
    24222635                /* almost certainly win95 - enable bug fixes */
    24232636                cli->win95 = True;
     
    24292642         */
    24302643
    2431         cli->dfsroot = false;
    2432 
    2433         if ((wct > 2) && (cli->protocol >= PROTOCOL_LANMAN2)) {
    2434                 cli->dfsroot = ((SVAL(vwv+2, 0) & SMB_SHARE_IN_DFS) != 0);
    2435         }
    2436 
    2437         cli->cnum = SVAL(inbuf,smb_tid);
     2644        if ((wct > 2) && (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_LANMAN2)) {
     2645                optional_support = SVAL(vwv+2, 0);
     2646        }
     2647
     2648        if (optional_support & SMB_EXTENDED_SIGNATURES) {
     2649                smb1cli_session_protect_session_key(cli->smb1.session);
     2650        }
     2651
     2652        smb1cli_tcon_set_values(state->cli->smb1.tcon,
     2653                                SVAL(inhdr, HDR_TID),
     2654                                optional_support,
     2655                                0, /* maximal_access */
     2656                                0, /* guest_maximal_access */
     2657                                NULL, /* service */
     2658                                NULL); /* fs_type */
     2659
    24382660        tevent_req_done(req);
    24392661}
     
    24482670{
    24492671        TALLOC_CTX *frame = talloc_stackframe();
    2450         struct event_context *ev;
     2672        struct tevent_context *ev;
    24512673        struct tevent_req *req;
    2452         NTSTATUS status = NT_STATUS_OK;
    2453 
    2454         if (cli_has_async_calls(cli)) {
     2674        NTSTATUS status = NT_STATUS_NO_MEMORY;
     2675
     2676        if (smbXcli_conn_has_async_calls(cli->conn)) {
    24552677                /*
    24562678                 * Can't use sync call while an async call is in flight
     
    24602682        }
    24612683
    2462         ev = event_context_init(frame);
     2684        ev = samba_tevent_context_init(frame);
    24632685        if (ev == NULL) {
    2464                 status = NT_STATUS_NO_MEMORY;
    24652686                goto fail;
    24662687        }
     
    24682689        req = cli_tcon_andx_send(frame, ev, cli, share, dev, pass, passlen);
    24692690        if (req == NULL) {
    2470                 status = NT_STATUS_NO_MEMORY;
    24712691                goto fail;
    24722692        }
    24732693
    2474         if (!tevent_req_poll(req, ev)) {
    2475                 status = map_nt_error_from_unix(errno);
     2694        if (!tevent_req_poll_ntstatus(req, ev, &status)) {
    24762695                goto fail;
    24772696        }
     
    24832702}
    24842703
     2704struct cli_tree_connect_state {
     2705        struct cli_state *cli;
     2706};
     2707
     2708static struct tevent_req *cli_raw_tcon_send(
     2709        TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct cli_state *cli,
     2710        const char *service, const char *pass, const char *dev);
     2711static NTSTATUS cli_raw_tcon_recv(struct tevent_req *req,
     2712                                  uint16_t *max_xmit, uint16_t *tid);
     2713
     2714static void cli_tree_connect_smb2_done(struct tevent_req *subreq);
     2715static void cli_tree_connect_andx_done(struct tevent_req *subreq);
     2716static void cli_tree_connect_raw_done(struct tevent_req *subreq);
     2717
     2718static struct tevent_req *cli_tree_connect_send(
     2719        TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct cli_state *cli,
     2720        const char *share, const char *dev, const char *pass, int passlen)
     2721{
     2722        struct tevent_req *req, *subreq;
     2723        struct cli_tree_connect_state *state;
     2724
     2725        req = tevent_req_create(mem_ctx, &state,
     2726                                struct cli_tree_connect_state);
     2727        if (req == NULL) {
     2728                return NULL;
     2729        }
     2730        state->cli = cli;
     2731
     2732        cli->share = talloc_strdup(cli, share);
     2733        if (tevent_req_nomem(cli->share, req)) {
     2734                return tevent_req_post(req, ev);
     2735        }
     2736
     2737        if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) {
     2738                char *unc;
     2739
     2740                cli->smb2.tcon = smbXcli_tcon_create(cli);
     2741                if (tevent_req_nomem(cli->smb2.tcon, req)) {
     2742                        return tevent_req_post(req, ev);
     2743                }
     2744
     2745                unc = talloc_asprintf(state, "\\\\%s\\%s",
     2746                                      smbXcli_conn_remote_name(cli->conn),
     2747                                      share);
     2748                if (tevent_req_nomem(unc, req)) {
     2749                        return tevent_req_post(req, ev);
     2750                }
     2751
     2752                subreq = smb2cli_tcon_send(state, ev, cli->conn, cli->timeout,
     2753                                           cli->smb2.session, cli->smb2.tcon,
     2754                                           0, /* flags */
     2755                                           unc);
     2756                if (tevent_req_nomem(subreq, req)) {
     2757                        return tevent_req_post(req, ev);
     2758                }
     2759                tevent_req_set_callback(subreq, cli_tree_connect_smb2_done,
     2760                                        req);
     2761                return req;
     2762        }
     2763
     2764        if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_LANMAN1) {
     2765                subreq = cli_tcon_andx_send(state, ev, cli, share, dev,
     2766                                            pass, passlen);
     2767                if (tevent_req_nomem(subreq, req)) {
     2768                        return tevent_req_post(req, ev);
     2769                }
     2770                tevent_req_set_callback(subreq, cli_tree_connect_andx_done,
     2771                                        req);
     2772                return req;
     2773        }
     2774
     2775        subreq = cli_raw_tcon_send(state, ev, cli, share, pass, dev);
     2776        if (tevent_req_nomem(subreq, req)) {
     2777                return tevent_req_post(req, ev);
     2778        }
     2779        tevent_req_set_callback(subreq, cli_tree_connect_raw_done, req);
     2780
     2781        return req;
     2782}
     2783
     2784static void cli_tree_connect_smb2_done(struct tevent_req *subreq)
     2785{
     2786        tevent_req_simple_finish_ntstatus(
     2787                subreq, smb2cli_tcon_recv(subreq));
     2788}
     2789
     2790static void cli_tree_connect_andx_done(struct tevent_req *subreq)
     2791{
     2792        tevent_req_simple_finish_ntstatus(
     2793                subreq, cli_tcon_andx_recv(subreq));
     2794}
     2795
     2796static void cli_tree_connect_raw_done(struct tevent_req *subreq)
     2797{
     2798        struct tevent_req *req = tevent_req_callback_data(
     2799                subreq, struct tevent_req);
     2800        struct cli_tree_connect_state *state = tevent_req_data(
     2801                req, struct cli_tree_connect_state);
     2802        NTSTATUS status;
     2803        uint16_t max_xmit = 0;
     2804        uint16_t tid = 0;
     2805
     2806        status = cli_raw_tcon_recv(subreq, &max_xmit, &tid);
     2807        if (tevent_req_nterror(req, status)) {
     2808                return;
     2809        }
     2810
     2811        smb1cli_tcon_set_values(state->cli->smb1.tcon,
     2812                                tid,
     2813                                0, /* optional_support */
     2814                                0, /* maximal_access */
     2815                                0, /* guest_maximal_access */
     2816                                NULL, /* service */
     2817                                NULL); /* fs_type */
     2818
     2819        tevent_req_done(req);
     2820}
     2821
     2822static NTSTATUS cli_tree_connect_recv(struct tevent_req *req)
     2823{
     2824        return tevent_req_simple_recv_ntstatus(req);
     2825}
     2826
     2827NTSTATUS cli_tree_connect(struct cli_state *cli, const char *share,
     2828                          const char *dev, const char *pass, int passlen)
     2829{
     2830        struct tevent_context *ev;
     2831        struct tevent_req *req;
     2832        NTSTATUS status = NT_STATUS_NO_MEMORY;
     2833
     2834        if (smbXcli_conn_has_async_calls(cli->conn)) {
     2835                return NT_STATUS_INVALID_PARAMETER;
     2836        }
     2837        ev = samba_tevent_context_init(talloc_tos());
     2838        if (ev == NULL) {
     2839                goto fail;
     2840        }
     2841        req = cli_tree_connect_send(ev, ev, cli, share, dev, pass, passlen);
     2842        if (req == NULL) {
     2843                goto fail;
     2844        }
     2845        if (!tevent_req_poll_ntstatus(req, ev, &status)) {
     2846                goto fail;
     2847        }
     2848        status = cli_tree_connect_recv(req);
     2849fail:
     2850        TALLOC_FREE(ev);
     2851        return status;
     2852}
     2853
    24852854/****************************************************************************
    24862855 Send a tree disconnect.
     
    24932862static void cli_tdis_done(struct tevent_req *subreq);
    24942863
    2495 struct tevent_req *cli_tdis_send(TALLOC_CTX *mem_ctx,
     2864static struct tevent_req *cli_tdis_send(TALLOC_CTX *mem_ctx,
    24962865                                 struct tevent_context *ev,
    24972866                                 struct cli_state *cli)
     
    25282897                return;
    25292898        }
    2530         state->cli->cnum = -1;
     2899        cli_state_set_tid(state->cli, UINT16_MAX);
    25312900        tevent_req_done(req);
    25322901}
    25332902
    2534 NTSTATUS cli_tdis_recv(struct tevent_req *req)
     2903static NTSTATUS cli_tdis_recv(struct tevent_req *req)
    25352904{
    25362905        return tevent_req_simple_recv_ntstatus(req);
     
    25432912        NTSTATUS status = NT_STATUS_NO_MEMORY;
    25442913
    2545         if (cli_has_async_calls(cli)) {
     2914        if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) {
     2915                return smb2cli_tdis(cli->conn,
     2916                                    cli->timeout,
     2917                                    cli->smb2.session,
     2918                                    cli->smb2.tcon);
     2919        }
     2920
     2921        if (smbXcli_conn_has_async_calls(cli->conn)) {
    25462922                return NT_STATUS_INVALID_PARAMETER;
    25472923        }
    2548         ev = tevent_context_init(talloc_tos());
     2924        ev = samba_tevent_context_init(talloc_tos());
    25492925        if (ev == NULL) {
    25502926                goto fail;
     
    25632939}
    25642940
    2565 /****************************************************************************
    2566  Send a negprot command.
    2567 ****************************************************************************/
    2568 
    2569 struct cli_negprot_state {
     2941struct cli_connect_sock_state {
     2942        const char **called_names;
     2943        const char **calling_names;
     2944        int *called_types;
     2945        int fd;
     2946        uint16_t port;
     2947};
     2948
     2949static void cli_connect_sock_done(struct tevent_req *subreq);
     2950
     2951/*
     2952 * Async only if we don't have to look up the name, i.e. "pss" is set with a
     2953 * nonzero address.
     2954 */
     2955
     2956static struct tevent_req *cli_connect_sock_send(
     2957        TALLOC_CTX *mem_ctx, struct tevent_context *ev,
     2958        const char *host, int name_type, const struct sockaddr_storage *pss,
     2959        const char *myname, uint16_t port)
     2960{
     2961        struct tevent_req *req, *subreq;
     2962        struct cli_connect_sock_state *state;
     2963        const char *prog;
     2964        struct sockaddr_storage *addrs;
     2965        unsigned i, num_addrs;
     2966        NTSTATUS status;
     2967
     2968        req = tevent_req_create(mem_ctx, &state,
     2969                                struct cli_connect_sock_state);
     2970        if (req == NULL) {
     2971                return NULL;
     2972        }
     2973
     2974        prog = getenv("LIBSMB_PROG");
     2975        if (prog != NULL) {
     2976                state->fd = sock_exec(prog);
     2977                if (state->fd == -1) {
     2978                        status = map_nt_error_from_unix(errno);
     2979                        tevent_req_nterror(req, status);
     2980                } else {
     2981                        state->port = 0;
     2982                        tevent_req_done(req);
     2983                }
     2984                return tevent_req_post(req, ev);
     2985        }
     2986
     2987        if ((pss == NULL) || is_zero_addr(pss)) {
     2988
     2989                /*
     2990                 * Here we cheat. resolve_name_list is not async at all. So
     2991                 * this call will only be really async if the name lookup has
     2992                 * been done externally.
     2993                 */
     2994
     2995                status = resolve_name_list(state, host, name_type,
     2996                                           &addrs, &num_addrs);
     2997                if (!NT_STATUS_IS_OK(status)) {
     2998                        tevent_req_nterror(req, status);
     2999                        return tevent_req_post(req, ev);
     3000                }
     3001        } else {
     3002                addrs = talloc_array(state, struct sockaddr_storage, 1);
     3003                if (tevent_req_nomem(addrs, req)) {
     3004                        return tevent_req_post(req, ev);
     3005                }
     3006                addrs[0] = *pss;
     3007                num_addrs = 1;
     3008        }
     3009
     3010        state->called_names = talloc_array(state, const char *, num_addrs);
     3011        if (tevent_req_nomem(state->called_names, req)) {
     3012                return tevent_req_post(req, ev);
     3013        }
     3014        state->called_types = talloc_array(state, int, num_addrs);
     3015        if (tevent_req_nomem(state->called_types, req)) {
     3016                return tevent_req_post(req, ev);
     3017        }
     3018        state->calling_names = talloc_array(state, const char *, num_addrs);
     3019        if (tevent_req_nomem(state->calling_names, req)) {
     3020                return tevent_req_post(req, ev);
     3021        }
     3022        for (i=0; i<num_addrs; i++) {
     3023                state->called_names[i] = host;
     3024                state->called_types[i] = name_type;
     3025                state->calling_names[i] = myname;
     3026        }
     3027
     3028        subreq = smbsock_any_connect_send(
     3029                state, ev, addrs, state->called_names, state->called_types,
     3030                state->calling_names, NULL, num_addrs, port);
     3031        if (tevent_req_nomem(subreq, req)) {
     3032                return tevent_req_post(req, ev);
     3033        }
     3034        tevent_req_set_callback(subreq, cli_connect_sock_done, req);
     3035        return req;
     3036}
     3037
     3038static void cli_connect_sock_done(struct tevent_req *subreq)
     3039{
     3040        struct tevent_req *req = tevent_req_callback_data(
     3041                subreq, struct tevent_req);
     3042        struct cli_connect_sock_state *state = tevent_req_data(
     3043                req, struct cli_connect_sock_state);
     3044        NTSTATUS status;
     3045
     3046        status = smbsock_any_connect_recv(subreq, &state->fd, NULL,
     3047                                          &state->port);
     3048        TALLOC_FREE(subreq);
     3049        if (tevent_req_nterror(req, status)) {
     3050                return;
     3051        }
     3052        set_socket_options(state->fd, lp_socket_options());
     3053        tevent_req_done(req);
     3054}
     3055
     3056static NTSTATUS cli_connect_sock_recv(struct tevent_req *req,
     3057                                      int *pfd, uint16_t *pport)
     3058{
     3059        struct cli_connect_sock_state *state = tevent_req_data(
     3060                req, struct cli_connect_sock_state);
     3061        NTSTATUS status;
     3062
     3063        if (tevent_req_is_nterror(req, &status)) {
     3064                return status;
     3065        }
     3066        *pfd = state->fd;
     3067        *pport = state->port;
     3068        return NT_STATUS_OK;
     3069}
     3070
     3071struct cli_connect_nb_state {
     3072        const char *desthost;
     3073        int signing_state;
     3074        int flags;
    25703075        struct cli_state *cli;
    25713076};
    25723077
    2573 static void cli_negprot_done(struct tevent_req *subreq);
    2574 
    2575 struct tevent_req *cli_negprot_send(TALLOC_CTX *mem_ctx,
    2576                                     struct event_context *ev,
    2577                                     struct cli_state *cli)
     3078static void cli_connect_nb_done(struct tevent_req *subreq);
     3079
     3080static struct tevent_req *cli_connect_nb_send(
     3081        TALLOC_CTX *mem_ctx, struct tevent_context *ev,
     3082        const char *host, const struct sockaddr_storage *dest_ss,
     3083        uint16_t port, int name_type, const char *myname,
     3084        int signing_state, int flags)
    25783085{
    25793086        struct tevent_req *req, *subreq;
    2580         struct cli_negprot_state *state;
    2581         uint8_t *bytes = NULL;
    2582         int numprots;
    2583         uint16_t cnum;
    2584 
    2585         req = tevent_req_create(mem_ctx, &state, struct cli_negprot_state);
     3087        struct cli_connect_nb_state *state;
     3088
     3089        req = tevent_req_create(mem_ctx, &state, struct cli_connect_nb_state);
    25863090        if (req == NULL) {
    25873091                return NULL;
    25883092        }
    2589         state->cli = cli;
    2590 
    2591         if (cli->protocol < PROTOCOL_NT1)
    2592                 cli->use_spnego = False;
    2593 
    2594         /* setup the protocol strings */
    2595         for (numprots=0; numprots < ARRAY_SIZE(prots); numprots++) {
    2596                 uint8_t c = 2;
    2597                 if (prots[numprots].prot > cli->protocol) {
    2598                         break;
    2599                 }
    2600                 bytes = (uint8_t *)talloc_append_blob(
    2601                         state, bytes, data_blob_const(&c, sizeof(c)));
    2602                 if (tevent_req_nomem(bytes, req)) {
     3093        state->signing_state = signing_state;
     3094        state->flags = flags;
     3095
     3096        if (host != NULL) {
     3097                char *p = strchr(host, '#');
     3098
     3099                if (p != NULL) {
     3100                        name_type = strtol(p+1, NULL, 16);
     3101                        host = talloc_strndup(state, host, p - host);
     3102                        if (tevent_req_nomem(host, req)) {
     3103                                return tevent_req_post(req, ev);
     3104                        }
     3105                }
     3106
     3107                state->desthost = host;
     3108        } else {
     3109                state->desthost = print_canonical_sockaddr(state, dest_ss);
     3110                if (tevent_req_nomem(state->desthost, req)) {
    26033111                        return tevent_req_post(req, ev);
    26043112                }
    2605                 bytes = smb_bytes_push_str(bytes, false,
    2606                                            prots[numprots].name,
    2607                                            strlen(prots[numprots].name)+1,
    2608                                            NULL);
    2609                 if (tevent_req_nomem(bytes, req)) {
    2610                         return tevent_req_post(req, ev);
    2611                 }
    2612         }
    2613 
    2614         cnum = cli->cnum;
    2615 
    2616         cli->cnum = 0;
    2617         subreq = cli_smb_send(state, ev, cli, SMBnegprot, 0, 0, NULL,
    2618                               talloc_get_size(bytes), bytes);
    2619         cli->cnum = cnum;
    2620 
     3113        }
     3114
     3115        subreq = cli_connect_sock_send(state, ev, host, name_type, dest_ss,
     3116                                       myname, port);
    26213117        if (tevent_req_nomem(subreq, req)) {
    26223118                return tevent_req_post(req, ev);
    26233119        }
    2624         tevent_req_set_callback(subreq, cli_negprot_done, req);
     3120        tevent_req_set_callback(subreq, cli_connect_nb_done, req);
    26253121        return req;
    26263122}
    26273123
    2628 static void cli_negprot_done(struct tevent_req *subreq)
     3124static void cli_connect_nb_done(struct tevent_req *subreq)
    26293125{
    26303126        struct tevent_req *req = tevent_req_callback_data(
    26313127                subreq, struct tevent_req);
    2632         struct cli_negprot_state *state = tevent_req_data(
    2633                 req, struct cli_negprot_state);
    2634         struct cli_state *cli = state->cli;
    2635         uint8_t wct;
    2636         uint16_t *vwv;
    2637         uint32_t num_bytes;
    2638         uint8_t *bytes;
    2639         NTSTATUS status;
    2640         uint16_t protnum;
    2641         uint8_t *inbuf;
    2642 
    2643         status = cli_smb_recv(subreq, state, &inbuf, 1, &wct, &vwv,
    2644                               &num_bytes, &bytes);
     3128        struct cli_connect_nb_state *state = tevent_req_data(
     3129                req, struct cli_connect_nb_state);
     3130        NTSTATUS status;
     3131        int fd = 0;
     3132        uint16_t port;
     3133
     3134        status = cli_connect_sock_recv(subreq, &fd, &port);
    26453135        TALLOC_FREE(subreq);
    2646         if (!NT_STATUS_IS_OK(status)) {
    2647                 tevent_req_nterror(req, status);
    2648                 return;
    2649         }
    2650 
    2651         protnum = SVAL(vwv, 0);
    2652 
    2653         if ((protnum >= ARRAY_SIZE(prots))
    2654             || (prots[protnum].prot > cli->protocol)) {
    2655                 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
    2656                 return;
    2657         }
    2658 
    2659         cli->protocol = prots[protnum].prot;
    2660 
    2661         if ((cli->protocol < PROTOCOL_NT1) &&
    2662             client_is_signing_mandatory(cli)) {
    2663                 DEBUG(0,("cli_negprot: SMB signing is mandatory and the selected protocol level doesn't support it.\n"));
    2664                 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
    2665                 return;
    2666         }
    2667 
    2668         if (cli->protocol >= PROTOCOL_NT1) {   
    2669                 struct timespec ts;
    2670                 bool negotiated_smb_signing = false;
    2671                 DATA_BLOB blob = data_blob_null;
    2672 
    2673                 if (wct != 0x11) {
    2674                         tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
    2675                         return;
    2676                 }
    2677 
    2678                 /* NT protocol */
    2679                 cli->sec_mode = CVAL(vwv + 1, 0);
    2680                 cli->max_mux = SVAL(vwv + 1, 1);
    2681                 cli->max_xmit = IVAL(vwv + 3, 1);
    2682                 cli->sesskey = IVAL(vwv + 7, 1);
    2683                 cli->serverzone = SVALS(vwv + 15, 1);
    2684                 cli->serverzone *= 60;
    2685                 /* this time arrives in real GMT */
    2686                 ts = interpret_long_date(((char *)(vwv+11))+1);
    2687                 cli->servertime = ts.tv_sec;
    2688                 cli->secblob = data_blob(bytes, num_bytes);
    2689                 cli->capabilities = IVAL(vwv + 9, 1);
    2690                 if (cli->capabilities & CAP_RAW_MODE) {
    2691                         cli->readbraw_supported = True;
    2692                         cli->writebraw_supported = True;     
    2693                 }
    2694                 /* work out if they sent us a workgroup */
    2695                 if (!(cli->capabilities & CAP_EXTENDED_SECURITY) &&
    2696                     smb_buflen(inbuf) > 8) {
    2697                         blob = data_blob_const(bytes + 8, num_bytes - 8);
    2698                 }
    2699 
    2700                 if (blob.length > 0) {
    2701                         ssize_t ret;
    2702                         char *server_domain = NULL;
    2703 
    2704                         ret = clistr_pull_talloc(cli,
    2705                                                  (const char *)inbuf,
    2706                                                  SVAL(inbuf, smb_flg2),
    2707                                                  &server_domain,
    2708                                                  (char *)blob.data,
    2709                                                  blob.length,
    2710                                                  STR_TERMINATE|
    2711                                                  STR_UNICODE|
    2712                                                  STR_NOALIGN);
    2713                         if (ret == -1) {
    2714                                 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
    2715                                 return;
    2716                         }
    2717                         if (server_domain) {
    2718                                 cli->server_domain = server_domain;
    2719                         }
    2720                 }
    2721 
    2722                 /*
    2723                  * As signing is slow we only turn it on if either the client or
    2724                  * the server require it. JRA.
    2725                  */
    2726 
    2727                 if (cli->sec_mode & NEGOTIATE_SECURITY_SIGNATURES_REQUIRED) {
    2728                         /* Fail if server says signing is mandatory and we don't want to support it. */
    2729                         if (!client_is_signing_allowed(cli)) {
    2730                                 DEBUG(0,("cli_negprot: SMB signing is mandatory and we have disabled it.\n"));
    2731                                 tevent_req_nterror(req,
    2732                                                    NT_STATUS_ACCESS_DENIED);
    2733                                 return;
    2734                         }
    2735                         negotiated_smb_signing = true;
    2736                 } else if (client_is_signing_mandatory(cli) && client_is_signing_allowed(cli)) {
    2737                         /* Fail if client says signing is mandatory and the server doesn't support it. */
    2738                         if (!(cli->sec_mode & NEGOTIATE_SECURITY_SIGNATURES_ENABLED)) {
    2739                                 DEBUG(1,("cli_negprot: SMB signing is mandatory and the server doesn't support it.\n"));
    2740                                 tevent_req_nterror(req,
    2741                                                    NT_STATUS_ACCESS_DENIED);
    2742                                 return;
    2743                         }
    2744                         negotiated_smb_signing = true;
    2745                 } else if (cli->sec_mode & NEGOTIATE_SECURITY_SIGNATURES_ENABLED) {
    2746                         negotiated_smb_signing = true;
    2747                 }
    2748 
    2749                 if (negotiated_smb_signing) {
    2750                         cli_set_signing_negotiated(cli);
    2751                 }
    2752 
    2753                 if (cli->capabilities & (CAP_LARGE_READX|CAP_LARGE_WRITEX)) {
    2754                         SAFE_FREE(cli->outbuf);
    2755                         SAFE_FREE(cli->inbuf);
    2756                         cli->outbuf = (char *)SMB_MALLOC(CLI_SAMBA_MAX_LARGE_READX_SIZE+LARGE_WRITEX_HDR_SIZE+SAFETY_MARGIN);
    2757                         cli->inbuf = (char *)SMB_MALLOC(CLI_SAMBA_MAX_LARGE_READX_SIZE+LARGE_WRITEX_HDR_SIZE+SAFETY_MARGIN);
    2758                         if (!cli->outbuf || !cli->inbuf) {
    2759                                 tevent_req_nterror(req,
    2760                                                 NT_STATUS_NO_MEMORY);
    2761                                 return;
    2762                         }
    2763                         cli->bufsize = CLI_SAMBA_MAX_LARGE_READX_SIZE + LARGE_WRITEX_HDR_SIZE;
    2764                 }
    2765 
    2766         } else if (cli->protocol >= PROTOCOL_LANMAN1) {
    2767                 if (wct != 0x0D) {
    2768                         tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
    2769                         return;
    2770                 }
    2771 
    2772                 cli->use_spnego = False;
    2773                 cli->sec_mode = SVAL(vwv + 1, 0);
    2774                 cli->max_xmit = SVAL(vwv + 2, 0);
    2775                 cli->max_mux = SVAL(vwv + 3, 0);
    2776                 cli->sesskey = IVAL(vwv + 6, 0);
    2777                 cli->serverzone = SVALS(vwv + 10, 0);
    2778                 cli->serverzone *= 60;
    2779                 /* this time is converted to GMT by make_unix_date */
    2780                 cli->servertime = make_unix_date(
    2781                         (char *)(vwv + 8), cli->serverzone);
    2782                 cli->readbraw_supported = ((SVAL(vwv + 5, 0) & 0x1) != 0);
    2783                 cli->writebraw_supported = ((SVAL(vwv + 5, 0) & 0x2) != 0);
    2784                 cli->secblob = data_blob(bytes, num_bytes);
    2785         } else {
    2786                 /* the old core protocol */
    2787                 cli->use_spnego = False;
    2788                 cli->sec_mode = 0;
    2789                 cli->serverzone = get_time_zone(time(NULL));
    2790         }
    2791 
    2792         cli->max_xmit = MIN(cli->max_xmit, CLI_BUFFER_SIZE);
    2793 
    2794         /* a way to force ascii SMB */
    2795         if (getenv("CLI_FORCE_ASCII"))
    2796                 cli->capabilities &= ~CAP_UNICODE;
    2797 
     3136        if (tevent_req_nterror(req, status)) {
     3137                return;
     3138        }
     3139
     3140        state->cli = cli_state_create(state, fd, state->desthost, NULL,
     3141                                      state->signing_state, state->flags);
     3142        if (tevent_req_nomem(state->cli, req)) {
     3143                close(fd);
     3144                return;
     3145        }
    27983146        tevent_req_done(req);
    27993147}
    28003148
    2801 NTSTATUS cli_negprot_recv(struct tevent_req *req)
    2802 {
    2803         return tevent_req_simple_recv_ntstatus(req);
    2804 }
    2805 
    2806 NTSTATUS cli_negprot(struct cli_state *cli)
    2807 {
    2808         TALLOC_CTX *frame = talloc_stackframe();
    2809         struct event_context *ev;
     3149static NTSTATUS cli_connect_nb_recv(struct tevent_req *req,
     3150                                    struct cli_state **pcli)
     3151{
     3152        struct cli_connect_nb_state *state = tevent_req_data(
     3153                req, struct cli_connect_nb_state);
     3154        NTSTATUS status;
     3155
     3156        if (tevent_req_is_nterror(req, &status)) {
     3157                return status;
     3158        }
     3159        *pcli = talloc_move(NULL, &state->cli);
     3160        return NT_STATUS_OK;
     3161}
     3162
     3163NTSTATUS cli_connect_nb(const char *host, const struct sockaddr_storage *dest_ss,
     3164                        uint16_t port, int name_type, const char *myname,
     3165                        int signing_state, int flags, struct cli_state **pcli)
     3166{
     3167        struct tevent_context *ev;
    28103168        struct tevent_req *req;
    2811         NTSTATUS status = NT_STATUS_OK;
    2812 
    2813         if (cli_has_async_calls(cli)) {
    2814                 /*
    2815                  * Can't use sync call while an async call is in flight
    2816                  */
    2817                 status = NT_STATUS_INVALID_PARAMETER;
     3169        NTSTATUS status = NT_STATUS_NO_MEMORY;
     3170
     3171        ev = samba_tevent_context_init(talloc_tos());
     3172        if (ev == NULL) {
    28183173                goto fail;
    28193174        }
    2820 
    2821         ev = event_context_init(frame);
    2822         if (ev == NULL) {
    2823                 status = NT_STATUS_NO_MEMORY;
     3175        req = cli_connect_nb_send(ev, ev, host, dest_ss, port, name_type,
     3176                                  myname, signing_state, flags);
     3177        if (req == NULL) {
    28243178                goto fail;
    28253179        }
    2826 
    2827         req = cli_negprot_send(frame, ev, cli);
    2828         if (req == NULL) {
    2829                 status = NT_STATUS_NO_MEMORY;
     3180        if (!tevent_req_set_endtime(req, ev, timeval_current_ofs(20, 0))) {
    28303181                goto fail;
    28313182        }
    2832 
    2833         if (!tevent_req_poll(req, ev)) {
    2834                 status = map_nt_error_from_unix(errno);
     3183        if (!tevent_req_poll_ntstatus(req, ev, &status)) {
    28353184                goto fail;
    28363185        }
    2837 
    2838         status = cli_negprot_recv(req);
    2839  fail:
    2840         TALLOC_FREE(frame);
    2841         return status;
    2842 }
    2843 
    2844 /****************************************************************************
    2845  Send a session request. See rfc1002.txt 4.3 and 4.3.2.
    2846 ****************************************************************************/
    2847 
    2848 bool cli_session_request(struct cli_state *cli,
    2849                          struct nmb_name *calling, struct nmb_name *called)
    2850 {
    2851         char *p;
    2852         int len = 4;
    2853         int namelen = 0;
    2854         char *tmp;
    2855 
    2856         /* 445 doesn't have session request */
    2857         if (cli->port == 445)
    2858                 return True;
    2859 
    2860         memcpy(&(cli->calling), calling, sizeof(*calling));
    2861         memcpy(&(cli->called ), called , sizeof(*called ));
    2862 
    2863         /* put in the destination name */
    2864 
    2865         tmp = name_mangle(talloc_tos(), cli->called.name,
    2866                           cli->called.name_type);
    2867         if (tmp == NULL) {
    2868                 return false;
    2869         }
    2870 
    2871         p = cli->outbuf+len;
    2872         namelen = name_len((unsigned char *)tmp, talloc_get_size(tmp));
    2873         if (namelen > 0) {
    2874                 memcpy(p, tmp, namelen);
    2875                 len += namelen;
    2876         }
    2877         TALLOC_FREE(tmp);
    2878 
    2879         /* and my name */
    2880 
    2881         tmp = name_mangle(talloc_tos(), cli->calling.name,
    2882                           cli->calling.name_type);
    2883         if (tmp == NULL) {
    2884                 return false;
    2885         }
    2886 
    2887         p = cli->outbuf+len;
    2888         namelen = name_len((unsigned char *)tmp, talloc_get_size(tmp));
    2889         if (namelen > 0) {
    2890                 memcpy(p, tmp, namelen);
    2891                 len += namelen;
    2892         }
    2893         TALLOC_FREE(tmp);
    2894 
    2895         /* send a session request (RFC 1002) */
    2896         /* setup the packet length
    2897          * Remove four bytes from the length count, since the length
    2898          * field in the NBT Session Service header counts the number
    2899          * of bytes which follow.  The cli_send_smb() function knows
    2900          * about this and accounts for those four bytes.
    2901          * CRH.
    2902          */
    2903         len -= 4;
    2904         _smb_setlen(cli->outbuf,len);
    2905         SCVAL(cli->outbuf,0,0x81);
    2906 
    2907         cli_send_smb(cli);
    2908         DEBUG(5,("Sent session request\n"));
    2909 
    2910         if (!cli_receive_smb(cli))
    2911                 return False;
    2912 
    2913         if (CVAL(cli->inbuf,0) == 0x84) {
    2914                 /* C. Hoch  9/14/95 Start */
    2915                 /* For information, here is the response structure.
    2916                  * We do the byte-twiddling to for portability.
    2917                 struct RetargetResponse{
    2918                 unsigned char type;
    2919                 unsigned char flags;
    2920                 int16 length;
    2921                 int32 ip_addr;
    2922                 int16 port;
    2923                 };
    2924                 */
    2925                 uint16_t port = (CVAL(cli->inbuf,8)<<8)+CVAL(cli->inbuf,9);
    2926                 struct in_addr dest_ip;
    2927                 NTSTATUS status;
    2928 
    2929                 /* SESSION RETARGET */
    2930                 putip((char *)&dest_ip,cli->inbuf+4);
    2931                 in_addr_to_sockaddr_storage(&cli->dest_ss, dest_ip);
    2932 
    2933                 status = open_socket_out(&cli->dest_ss, port,
    2934                                          LONG_CONNECT_TIMEOUT, &cli->fd);
    2935                 if (!NT_STATUS_IS_OK(status)) {
    2936                         return False;
    2937                 }
    2938 
    2939                 DEBUG(3,("Retargeted\n"));
    2940 
    2941                 set_socket_options(cli->fd, lp_socket_options());
    2942 
    2943                 /* Try again */
    2944                 {
    2945                         static int depth;
    2946                         bool ret;
    2947                         if (depth > 4) {
    2948                                 DEBUG(0,("Retarget recursion - failing\n"));
    2949                                 return False;
    2950                         }
    2951                         depth++;
    2952                         ret = cli_session_request(cli, calling, called);
    2953                         depth--;
    2954                         return ret;
    2955                 }
    2956         } /* C. Hoch 9/14/95 End */
    2957 
    2958         if (CVAL(cli->inbuf,0) != 0x82) {
    2959                 /* This is the wrong place to put the error... JRA. */
    2960                 cli->rap_error = CVAL(cli->inbuf,4);
    2961                 return False;
    2962         }
    2963         return(True);
    2964 }
    2965 
    2966 struct fd_struct {
    2967         int fd;
    2968 };
    2969 
    2970 static void smb_sock_connected(struct tevent_req *req)
    2971 {
    2972         struct fd_struct *pfd = tevent_req_callback_data(
    2973                 req, struct fd_struct);
    2974         int fd;
    2975         NTSTATUS status;
    2976 
    2977         status = open_socket_out_defer_recv(req, &fd);
    2978         if (NT_STATUS_IS_OK(status)) {
    2979                 pfd->fd = fd;
    2980         }
    2981 }
    2982 
    2983 static NTSTATUS open_smb_socket(const struct sockaddr_storage *pss,
    2984                                 uint16_t *port, int timeout, int *pfd)
    2985 {
    2986         struct event_context *ev;
    2987         struct tevent_req *r139, *r445;
    2988         struct fd_struct *fd139, *fd445;
    2989         NTSTATUS status = NT_STATUS_NO_MEMORY;
    2990 
    2991         if (*port != 0) {
    2992                 return open_socket_out(pss, *port, timeout, pfd);
    2993         }
    2994 
    2995         ev = event_context_init(talloc_tos());
    2996         if (ev == NULL) {
    2997                 return NT_STATUS_NO_MEMORY;
    2998         }
    2999 
    3000         fd139 = talloc(ev, struct fd_struct);
    3001         if (fd139 == NULL) {
    3002                 goto done;
    3003         }
    3004         fd139->fd = -1;
    3005 
    3006         fd445 = talloc(ev, struct fd_struct);
    3007         if (fd445 == NULL) {
    3008                 goto done;
    3009         }
    3010         fd445->fd = -1;
    3011 
    3012         r445 = open_socket_out_defer_send(ev, ev, timeval_set(0, 0),
    3013                                           pss, 445, timeout);
    3014         r139 = open_socket_out_defer_send(ev, ev, timeval_set(0, 3000),
    3015                                           pss, 139, timeout);
    3016         if ((r445 == NULL) || (r139 == NULL)) {
    3017                 goto done;
    3018         }
    3019         tevent_req_set_callback(r445, smb_sock_connected, fd445);
    3020         tevent_req_set_callback(r139, smb_sock_connected, fd139);
    3021 
    3022         while ((fd445->fd == -1) && (fd139->fd == -1)
    3023                && (tevent_req_is_in_progress(r139)
    3024                    || tevent_req_is_in_progress(r445))) {
    3025                 event_loop_once(ev);
    3026         }
    3027 
    3028         if ((fd139->fd != -1) && (fd445->fd != -1)) {
    3029                 close(fd139->fd);
    3030                 fd139->fd = -1;
    3031         }
    3032 
    3033         if (fd445->fd != -1) {
    3034                 *port = 445;
    3035                 *pfd = fd445->fd;
    3036                 status = NT_STATUS_OK;
    3037                 goto done;
    3038         }
    3039         if (fd139->fd != -1) {
    3040                 *port = 139;
    3041                 *pfd = fd139->fd;
    3042                 status = NT_STATUS_OK;
    3043                 goto done;
    3044         }
    3045 
    3046         status = open_socket_out_defer_recv(r445, &fd445->fd);
    3047  done:
     3186        status = cli_connect_nb_recv(req, pcli);
     3187fail:
    30483188        TALLOC_FREE(ev);
    30493189        return status;
    30503190}
    30513191
    3052 /****************************************************************************
    3053  Open the client sockets.
    3054 ****************************************************************************/
    3055 
    3056 NTSTATUS cli_connect(struct cli_state *cli,
    3057                 const char *host,
    3058                 struct sockaddr_storage *dest_ss)
    3059 
    3060 {
    3061         int name_type = 0x20;
    3062         TALLOC_CTX *frame = talloc_stackframe();
    3063         unsigned int num_addrs = 0;
    3064         unsigned int i = 0;
    3065         struct sockaddr_storage *ss_arr = NULL;
    3066         char *p = NULL;
    3067 
    3068         /* reasonable default hostname */
    3069         if (!host) {
    3070                 host = STAR_SMBSERVER;
    3071         }
    3072 
    3073         cli->desthost = talloc_strdup(cli, host);
    3074         if (cli->desthost == NULL) {
    3075                 return NT_STATUS_NO_MEMORY;
    3076         }
    3077 
    3078         /* allow hostnames of the form NAME#xx and do a netbios lookup */
    3079         if ((p = strchr(cli->desthost, '#'))) {
    3080                 name_type = strtol(p+1, NULL, 16);
    3081                 *p = 0;
    3082         }
    3083 
    3084         if (!dest_ss || is_zero_addr(dest_ss)) {
    3085                 NTSTATUS status =resolve_name_list(frame,
    3086                                         cli->desthost,
    3087                                         name_type,
    3088                                         &ss_arr,
    3089                                         &num_addrs);
    3090                 if (!NT_STATUS_IS_OK(status)) {
    3091                         TALLOC_FREE(frame);
    3092                         return NT_STATUS_BAD_NETWORK_NAME;
    3093                 }
    3094         } else {
    3095                 num_addrs = 1;
    3096                 ss_arr = TALLOC_P(frame, struct sockaddr_storage);
    3097                 if (!ss_arr) {
    3098                         TALLOC_FREE(frame);
    3099                         return NT_STATUS_NO_MEMORY;
    3100                 }
    3101                 *ss_arr = *dest_ss;
    3102         }
    3103 
    3104         for (i = 0; i < num_addrs; i++) {
    3105                 cli->dest_ss = ss_arr[i];
    3106                 if (getenv("LIBSMB_PROG")) {
    3107                         cli->fd = sock_exec(getenv("LIBSMB_PROG"));
    3108                 } else {
    3109                         uint16_t port = cli->port;
    3110                         NTSTATUS status;
    3111                         status = open_smb_socket(&cli->dest_ss, &port,
    3112                                                  cli->timeout, &cli->fd);
    3113                         if (NT_STATUS_IS_OK(status)) {
    3114                                 cli->port = port;
    3115                         }
    3116                 }
    3117                 if (cli->fd == -1) {
    3118                         char addr[INET6_ADDRSTRLEN];
    3119                         print_sockaddr(addr, sizeof(addr), &ss_arr[i]);
    3120                         DEBUG(2,("Error connecting to %s (%s)\n",
    3121                                  dest_ss?addr:host,strerror(errno)));
    3122                 } else {
    3123                         /* Exit from loop on first connection. */
    3124                         break;
    3125                 }
    3126         }
    3127 
    3128         if (cli->fd == -1) {
    3129                 TALLOC_FREE(frame);
    3130                 return map_nt_error_from_unix(errno);
    3131         }
    3132 
    3133         if (dest_ss) {
    3134                 *dest_ss = cli->dest_ss;
    3135         }
    3136 
    3137         set_socket_options(cli->fd, lp_socket_options());
    3138 
    3139         TALLOC_FREE(frame);
    3140         return NT_STATUS_OK;
    3141 }
     3192struct cli_start_connection_state {
     3193        struct tevent_context *ev;
     3194        struct cli_state *cli;
     3195        int min_protocol;
     3196        int max_protocol;
     3197};
     3198
     3199static void cli_start_connection_connected(struct tevent_req *subreq);
     3200static void cli_start_connection_done(struct tevent_req *subreq);
    31423201
    31433202/**
     
    31483207   @param port (optional) The destination port (0 for default)
    31493208*/
     3209
     3210static struct tevent_req *cli_start_connection_send(
     3211        TALLOC_CTX *mem_ctx, struct tevent_context *ev,
     3212        const char *my_name, const char *dest_host,
     3213        const struct sockaddr_storage *dest_ss, int port,
     3214        int signing_state, int flags)
     3215{
     3216        struct tevent_req *req, *subreq;
     3217        struct cli_start_connection_state *state;
     3218
     3219        req = tevent_req_create(mem_ctx, &state,
     3220                                struct cli_start_connection_state);
     3221        if (req == NULL) {
     3222                return NULL;
     3223        }
     3224        state->ev = ev;
     3225
     3226        if (signing_state == SMB_SIGNING_IPC_DEFAULT) {
     3227                state->min_protocol = lp_client_ipc_min_protocol();
     3228                state->max_protocol = lp_client_ipc_max_protocol();
     3229        } else {
     3230                state->min_protocol = lp_client_min_protocol();
     3231                state->max_protocol = lp_client_max_protocol();
     3232        }
     3233
     3234        subreq = cli_connect_nb_send(state, ev, dest_host, dest_ss, port,
     3235                                     0x20, my_name, signing_state, flags);
     3236        if (tevent_req_nomem(subreq, req)) {
     3237                return tevent_req_post(req, ev);
     3238        }
     3239        tevent_req_set_callback(subreq, cli_start_connection_connected, req);
     3240        return req;
     3241}
     3242
     3243static void cli_start_connection_connected(struct tevent_req *subreq)
     3244{
     3245        struct tevent_req *req = tevent_req_callback_data(
     3246                subreq, struct tevent_req);
     3247        struct cli_start_connection_state *state = tevent_req_data(
     3248                req, struct cli_start_connection_state);
     3249        NTSTATUS status;
     3250
     3251        status = cli_connect_nb_recv(subreq, &state->cli);
     3252        TALLOC_FREE(subreq);
     3253        if (tevent_req_nterror(req, status)) {
     3254                return;
     3255        }
     3256
     3257        subreq = smbXcli_negprot_send(state, state->ev, state->cli->conn,
     3258                                      state->cli->timeout,
     3259                                      state->min_protocol,
     3260                                      state->max_protocol);
     3261        if (tevent_req_nomem(subreq, req)) {
     3262                return;
     3263        }
     3264        tevent_req_set_callback(subreq, cli_start_connection_done, req);
     3265}
     3266
     3267static void cli_start_connection_done(struct tevent_req *subreq)
     3268{
     3269        struct tevent_req *req = tevent_req_callback_data(
     3270                subreq, struct tevent_req);
     3271        struct cli_start_connection_state *state = tevent_req_data(
     3272                req, struct cli_start_connection_state);
     3273        NTSTATUS status;
     3274
     3275        status = smbXcli_negprot_recv(subreq);
     3276        TALLOC_FREE(subreq);
     3277        if (tevent_req_nterror(req, status)) {
     3278                return;
     3279        }
     3280
     3281        if (smbXcli_conn_protocol(state->cli->conn) >= PROTOCOL_SMB2_02) {
     3282                /* Ensure we ask for some initial credits. */
     3283                smb2cli_conn_set_max_credits(state->cli->conn,
     3284                                             DEFAULT_SMB2_MAX_CREDITS);
     3285        }
     3286
     3287        tevent_req_done(req);
     3288}
     3289
     3290static NTSTATUS cli_start_connection_recv(struct tevent_req *req,
     3291                                          struct cli_state **output_cli)
     3292{
     3293        struct cli_start_connection_state *state = tevent_req_data(
     3294                req, struct cli_start_connection_state);
     3295        NTSTATUS status;
     3296
     3297        if (tevent_req_is_nterror(req, &status)) {
     3298                return status;
     3299        }
     3300        *output_cli = state->cli;
     3301
     3302        return NT_STATUS_OK;
     3303}
     3304
    31503305NTSTATUS cli_start_connection(struct cli_state **output_cli,
    31513306                              const char *my_name,
    31523307                              const char *dest_host,
    3153                               struct sockaddr_storage *dest_ss, int port,
     3308                              const struct sockaddr_storage *dest_ss, int port,
    31543309                              int signing_state, int flags)
    31553310{
    3156         NTSTATUS nt_status;
    3157         struct nmb_name calling;
    3158         struct nmb_name called;
    3159         struct cli_state *cli;
    3160         struct sockaddr_storage ss;
    3161 
    3162         if (!my_name)
    3163                 my_name = global_myname();
    3164 
    3165         if (!(cli = cli_initialise_ex(signing_state))) {
    3166                 return NT_STATUS_NO_MEMORY;
    3167         }
    3168 
    3169         make_nmb_name(&calling, my_name, 0x0);
    3170         make_nmb_name(&called , dest_host, 0x20);
    3171 
    3172         cli_set_port(cli, port);
    3173         cli_set_timeout(cli, 10000); /* 10 seconds. */
    3174 
    3175         if (dest_ss) {
    3176                 ss = *dest_ss;
    3177         } else {
    3178                 zero_sockaddr(&ss);
    3179         }
    3180 
    3181 again:
    3182 
    3183         DEBUG(3,("Connecting to host=%s\n", dest_host));
    3184 
    3185         nt_status = cli_connect(cli, dest_host, &ss);
    3186         if (!NT_STATUS_IS_OK(nt_status)) {
    3187                 char addr[INET6_ADDRSTRLEN];
    3188                 print_sockaddr(addr, sizeof(addr), &ss);
    3189                 DEBUG(1,("cli_start_connection: failed to connect to %s (%s). Error %s\n",
    3190                          nmb_namestr(&called), addr, nt_errstr(nt_status) ));
    3191                 cli_shutdown(cli);
    3192                 return nt_status;
    3193         }
    3194 
    3195         if (!cli_session_request(cli, &calling, &called)) {
    3196                 char *p;
    3197                 DEBUG(1,("session request to %s failed (%s)\n",
    3198                          called.name, cli_errstr(cli)));
    3199                 if ((p=strchr(called.name, '.')) && !is_ipaddress(called.name)) {
    3200                         *p = 0;
    3201                         goto again;
    3202                 }
    3203                 if (strcmp(called.name, STAR_SMBSERVER)) {
    3204                         make_nmb_name(&called , STAR_SMBSERVER, 0x20);
    3205                         goto again;
    3206                 }
    3207                 return NT_STATUS_BAD_NETWORK_NAME;
    3208         }
    3209 
    3210         if (flags & CLI_FULL_CONNECTION_DONT_SPNEGO)
    3211                 cli->use_spnego = False;
    3212         else if (flags & CLI_FULL_CONNECTION_USE_KERBEROS)
    3213                 cli->use_kerberos = True;
    3214 
    3215         if ((flags & CLI_FULL_CONNECTION_FALLBACK_AFTER_KERBEROS) &&
    3216              cli->use_kerberos) {
    3217                 cli->fallback_after_kerberos = true;
    3218         }
    3219         if (flags & CLI_FULL_CONNECTION_USE_CCACHE) {
    3220                 cli->use_ccache = true;
    3221         }
    3222 
    3223         nt_status = cli_negprot(cli);
    3224         if (!NT_STATUS_IS_OK(nt_status)) {
    3225                 DEBUG(1, ("failed negprot: %s\n", nt_errstr(nt_status)));
    3226                 cli_shutdown(cli);
    3227                 return nt_status;
    3228         }
    3229 
    3230         *output_cli = cli;
    3231         return NT_STATUS_OK;
    3232 }
    3233 
     3311        struct tevent_context *ev;
     3312        struct tevent_req *req;
     3313        NTSTATUS status = NT_STATUS_NO_MEMORY;
     3314
     3315        ev = samba_tevent_context_init(talloc_tos());
     3316        if (ev == NULL) {
     3317                goto fail;
     3318        }
     3319        req = cli_start_connection_send(ev, ev, my_name, dest_host, dest_ss,
     3320                                        port, signing_state, flags);
     3321        if (req == NULL) {
     3322                goto fail;
     3323        }
     3324        if (!tevent_req_poll_ntstatus(req, ev, &status)) {
     3325                goto fail;
     3326        }
     3327        status = cli_start_connection_recv(req, output_cli);
     3328fail:
     3329        TALLOC_FREE(ev);
     3330        return status;
     3331}
    32343332
    32353333/**
     
    32463344*/
    32473345
    3248 NTSTATUS cli_full_connection(struct cli_state **output_cli,
    3249                              const char *my_name,
    3250                              const char *dest_host,
    3251                              struct sockaddr_storage *dest_ss, int port,
     3346struct cli_full_connection_state {
     3347        struct tevent_context *ev;
     3348        const char *service;
     3349        const char *service_type;
     3350        const char *user;
     3351        const char *domain;
     3352        const char *password;
     3353        int pw_len;
     3354        int flags;
     3355        struct cli_state *cli;
     3356};
     3357
     3358static int cli_full_connection_state_destructor(
     3359        struct cli_full_connection_state *s);
     3360static void cli_full_connection_started(struct tevent_req *subreq);
     3361static void cli_full_connection_sess_set_up(struct tevent_req *subreq);
     3362static void cli_full_connection_done(struct tevent_req *subreq);
     3363
     3364struct tevent_req *cli_full_connection_send(
     3365        TALLOC_CTX *mem_ctx, struct tevent_context *ev,
     3366        const char *my_name, const char *dest_host,
     3367        const struct sockaddr_storage *dest_ss, int port,
     3368        const char *service, const char *service_type,
     3369        const char *user, const char *domain,
     3370        const char *password, int flags, int signing_state)
     3371{
     3372        struct tevent_req *req, *subreq;
     3373        struct cli_full_connection_state *state;
     3374
     3375        req = tevent_req_create(mem_ctx, &state,
     3376                                struct cli_full_connection_state);
     3377        if (req == NULL) {
     3378                return NULL;
     3379        }
     3380        talloc_set_destructor(state, cli_full_connection_state_destructor);
     3381
     3382        state->ev = ev;
     3383        state->service = service;
     3384        state->service_type = service_type;
     3385        state->user = user;
     3386        state->domain = domain;
     3387        state->password = password;
     3388        state->flags = flags;
     3389
     3390        state->pw_len = state->password ? strlen(state->password)+1 : 0;
     3391        if (state->password == NULL) {
     3392                state->password = "";
     3393        }
     3394
     3395        subreq = cli_start_connection_send(
     3396                state, ev, my_name, dest_host, dest_ss, port,
     3397                signing_state, flags);
     3398        if (tevent_req_nomem(subreq, req)) {
     3399                return tevent_req_post(req, ev);
     3400        }
     3401        tevent_req_set_callback(subreq, cli_full_connection_started, req);
     3402        return req;
     3403}
     3404
     3405static int cli_full_connection_state_destructor(
     3406        struct cli_full_connection_state *s)
     3407{
     3408        if (s->cli != NULL) {
     3409                cli_shutdown(s->cli);
     3410                s->cli = NULL;
     3411        }
     3412        return 0;
     3413}
     3414
     3415static void cli_full_connection_started(struct tevent_req *subreq)
     3416{
     3417        struct tevent_req *req = tevent_req_callback_data(
     3418                subreq, struct tevent_req);
     3419        struct cli_full_connection_state *state = tevent_req_data(
     3420                req, struct cli_full_connection_state);
     3421        NTSTATUS status;
     3422
     3423        status = cli_start_connection_recv(subreq, &state->cli);
     3424        TALLOC_FREE(subreq);
     3425        if (tevent_req_nterror(req, status)) {
     3426                return;
     3427        }
     3428        subreq = cli_session_setup_send(
     3429                state, state->ev, state->cli, state->user,
     3430                state->password, state->pw_len, state->password, state->pw_len,
     3431                state->domain);
     3432        if (tevent_req_nomem(subreq, req)) {
     3433                return;
     3434        }
     3435        tevent_req_set_callback(subreq, cli_full_connection_sess_set_up, req);
     3436}
     3437
     3438static void cli_full_connection_sess_set_up(struct tevent_req *subreq)
     3439{
     3440        struct tevent_req *req = tevent_req_callback_data(
     3441                subreq, struct tevent_req);
     3442        struct cli_full_connection_state *state = tevent_req_data(
     3443                req, struct cli_full_connection_state);
     3444        NTSTATUS status;
     3445
     3446        status = cli_session_setup_recv(subreq);
     3447        TALLOC_FREE(subreq);
     3448
     3449        if (!NT_STATUS_IS_OK(status) &&
     3450            (state->flags & CLI_FULL_CONNECTION_ANONYMOUS_FALLBACK)) {
     3451
     3452                state->flags &= ~CLI_FULL_CONNECTION_ANONYMOUS_FALLBACK;
     3453
     3454                subreq = cli_session_setup_send(
     3455                        state, state->ev, state->cli, "", "", 0, "", 0,
     3456                        state->domain);
     3457                if (tevent_req_nomem(subreq, req)) {
     3458                        return;
     3459                }
     3460                tevent_req_set_callback(
     3461                        subreq, cli_full_connection_sess_set_up, req);
     3462                return;
     3463        }
     3464
     3465        if (tevent_req_nterror(req, status)) {
     3466                return;
     3467        }
     3468
     3469        if (state->service != NULL) {
     3470                subreq = cli_tree_connect_send(
     3471                        state, state->ev, state->cli,
     3472                        state->service, state->service_type,
     3473                        state->password, state->pw_len);
     3474                if (tevent_req_nomem(subreq, req)) {
     3475                        return;
     3476                }
     3477                tevent_req_set_callback(subreq, cli_full_connection_done, req);
     3478                return;
     3479        }
     3480
     3481        tevent_req_done(req);
     3482}
     3483
     3484static void cli_full_connection_done(struct tevent_req *subreq)
     3485{
     3486        struct tevent_req *req = tevent_req_callback_data(
     3487                subreq, struct tevent_req);
     3488        NTSTATUS status;
     3489
     3490        status = cli_tree_connect_recv(subreq);
     3491        TALLOC_FREE(subreq);
     3492        if (tevent_req_nterror(req, status)) {
     3493                return;
     3494        }
     3495
     3496        tevent_req_done(req);
     3497}
     3498
     3499NTSTATUS cli_full_connection_recv(struct tevent_req *req,
     3500                                  struct cli_state **output_cli)
     3501{
     3502        struct cli_full_connection_state *state = tevent_req_data(
     3503                req, struct cli_full_connection_state);
     3504        NTSTATUS status;
     3505
     3506        if (tevent_req_is_nterror(req, &status)) {
     3507                return status;
     3508        }
     3509        *output_cli = state->cli;
     3510        talloc_set_destructor(state, NULL);
     3511        return NT_STATUS_OK;
     3512}
     3513
     3514NTSTATUS cli_full_connection(struct cli_state **output_cli,
     3515                             const char *my_name,
     3516                             const char *dest_host,
     3517                             const struct sockaddr_storage *dest_ss, int port,
    32523518                             const char *service, const char *service_type,
    3253                              const char *user, const char *domain, 
     3519                             const char *user, const char *domain,
    32543520                             const char *password, int flags,
    32553521                             int signing_state)
    32563522{
    3257         NTSTATUS nt_status;
    3258         struct cli_state *cli = NULL;
    3259         int pw_len = password ? strlen(password)+1 : 0;
    3260 
    3261         *output_cli = NULL;
    3262 
    3263         if (password == NULL) {
    3264                 password = "";
    3265         }
    3266 
    3267         nt_status = cli_start_connection(&cli, my_name, dest_host,
    3268                                          dest_ss, port, signing_state,
    3269                                          flags);
    3270 
    3271         if (!NT_STATUS_IS_OK(nt_status)) {
    3272                 return nt_status;
    3273         }
    3274 
    3275         cli->use_oplocks = ((flags & CLI_FULL_CONNECTION_OPLOCKS) != 0);
    3276         cli->use_level_II_oplocks =
    3277                 ((flags & CLI_FULL_CONNECTION_LEVEL_II_OPLOCKS) != 0);
    3278 
    3279         nt_status = cli_session_setup(cli, user, password, pw_len, password,
    3280                                       pw_len, domain);
    3281         if (!NT_STATUS_IS_OK(nt_status)) {
    3282 
    3283                 if (!(flags & CLI_FULL_CONNECTION_ANONYMOUS_FALLBACK)) {
    3284                         DEBUG(1,("failed session setup with %s\n",
    3285                                  nt_errstr(nt_status)));
    3286                         cli_shutdown(cli);
    3287                         return nt_status;
    3288                 }
    3289 
    3290                 nt_status = cli_session_setup(cli, "", "", 0, "", 0, domain);
    3291                 if (!NT_STATUS_IS_OK(nt_status)) {
    3292                         DEBUG(1,("anonymous failed session setup with %s\n",
    3293                                  nt_errstr(nt_status)));
    3294                         cli_shutdown(cli);
    3295                         return nt_status;
    3296                 }
    3297         }
    3298 
    3299         if (service) {
    3300                 nt_status = cli_tcon_andx(cli, service, service_type, password,
    3301                                           pw_len);
    3302                 if (!NT_STATUS_IS_OK(nt_status)) {
    3303                         DEBUG(1,("failed tcon_X with %s\n", nt_errstr(nt_status)));
    3304                         cli_shutdown(cli);
    3305                         if (NT_STATUS_IS_OK(nt_status)) {
    3306                                 nt_status = NT_STATUS_UNSUCCESSFUL;
    3307                         }
    3308                         return nt_status;
    3309                 }
    3310         }
    3311 
    3312         nt_status = cli_init_creds(cli, user, domain, password);
    3313         if (!NT_STATUS_IS_OK(nt_status)) {
    3314                 cli_shutdown(cli);
    3315                 return nt_status;
    3316         }
    3317 
    3318         *output_cli = cli;
    3319         return NT_STATUS_OK;
    3320 }
    3321 
    3322 /****************************************************************************
    3323  Attempt a NetBIOS session request, falling back to *SMBSERVER if needed.
    3324 ****************************************************************************/
    3325 
    3326 bool attempt_netbios_session_request(struct cli_state **ppcli, const char *srchost, const char *desthost,
    3327                                      struct sockaddr_storage *pdest_ss)
    3328 {
    3329         struct nmb_name calling, called;
    3330 
    3331         make_nmb_name(&calling, srchost, 0x0);
    3332 
    3333         /*
    3334          * If the called name is an IP address
    3335          * then use *SMBSERVER immediately.
    3336          */
    3337 
    3338         if(is_ipaddress(desthost)) {
    3339                 make_nmb_name(&called, STAR_SMBSERVER, 0x20);
    3340         } else {
    3341                 make_nmb_name(&called, desthost, 0x20);
    3342         }
    3343 
    3344         if (!cli_session_request(*ppcli, &calling, &called)) {
    3345                 NTSTATUS status;
    3346                 struct nmb_name smbservername;
    3347 
    3348                 make_nmb_name(&smbservername, STAR_SMBSERVER, 0x20);
    3349 
    3350                 /*
    3351                  * If the name wasn't *SMBSERVER then
    3352                  * try with *SMBSERVER if the first name fails.
    3353                  */
    3354 
    3355                 if (nmb_name_equal(&called, &smbservername)) {
    3356 
    3357                         /*
    3358                          * The name used was *SMBSERVER, don't bother with another name.
    3359                          */
    3360 
    3361                         DEBUG(0,("attempt_netbios_session_request: %s rejected the session for name *SMBSERVER \
    3362 with error %s.\n", desthost, cli_errstr(*ppcli) ));
    3363                         return False;
    3364                 }
    3365 
    3366                 /* Try again... */
    3367                 cli_shutdown(*ppcli);
    3368 
    3369                 *ppcli = cli_initialise();
    3370                 if (!*ppcli) {
    3371                         /* Out of memory... */
    3372                         return False;
    3373                 }
    3374 
    3375                 status = cli_connect(*ppcli, desthost, pdest_ss);
    3376                 if (!NT_STATUS_IS_OK(status) ||
    3377                                 !cli_session_request(*ppcli, &calling, &smbservername)) {
    3378                         DEBUG(0,("attempt_netbios_session_request: %s rejected the session for \
    3379 name *SMBSERVER with error %s\n", desthost, cli_errstr(*ppcli) ));
    3380                         return False;
    3381                 }
    3382         }
    3383 
    3384         return True;
     3523        struct tevent_context *ev;
     3524        struct tevent_req *req;
     3525        NTSTATUS status = NT_STATUS_NO_MEMORY;
     3526
     3527        ev = samba_tevent_context_init(talloc_tos());
     3528        if (ev == NULL) {
     3529                goto fail;
     3530        }
     3531        req = cli_full_connection_send(
     3532                ev, ev, my_name, dest_host, dest_ss, port, service,
     3533                service_type, user, domain, password, flags, signing_state);
     3534        if (req == NULL) {
     3535                goto fail;
     3536        }
     3537        if (!tevent_req_poll_ntstatus(req, ev, &status)) {
     3538                goto fail;
     3539        }
     3540        status = cli_full_connection_recv(req, output_cli);
     3541 fail:
     3542        TALLOC_FREE(ev);
     3543        return status;
    33853544}
    33863545
     
    33883547 Send an old style tcon.
    33893548****************************************************************************/
    3390 NTSTATUS cli_raw_tcon(struct cli_state *cli,
    3391                       const char *service, const char *pass, const char *dev,
    3392                       uint16 *max_xmit, uint16 *tid)
    3393 {
    3394         struct tevent_req *req;
     3549struct cli_raw_tcon_state {
    33953550        uint16_t *ret_vwv;
     3551};
     3552
     3553static void cli_raw_tcon_done(struct tevent_req *subreq);
     3554
     3555static struct tevent_req *cli_raw_tcon_send(
     3556        TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct cli_state *cli,
     3557        const char *service, const char *pass, const char *dev)
     3558{
     3559        struct tevent_req *req, *subreq;
     3560        struct cli_raw_tcon_state *state;
    33963561        uint8_t *bytes;
    3397         NTSTATUS status;
     3562
     3563        req = tevent_req_create(mem_ctx, &state, struct cli_raw_tcon_state);
     3564        if (req == NULL) {
     3565                return NULL;
     3566        }
    33983567
    33993568        if (!lp_client_plaintext_auth() && (*pass)) {
    3400                 DEBUG(1, ("Server requested plaintext password but 'client "
    3401                           "plaintext auth' is disabled\n"));
    3402                 return NT_STATUS_ACCESS_DENIED;
    3403         }
    3404 
    3405         bytes = talloc_array(talloc_tos(), uint8_t, 0);
     3569                DEBUG(1, ("Server requested PLAINTEXT password but 'client plaintext auth = no'"
     3570                          " or 'client ntlmv2 auth = yes'\n"));
     3571                tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
     3572                return tevent_req_post(req, ev);
     3573        }
     3574
     3575        bytes = talloc_array(state, uint8_t, 0);
    34063576        bytes = smb_bytes_push_bytes(bytes, 4, NULL, 0);
    3407         bytes = smb_bytes_push_str(bytes, cli_ucs2(cli),
     3577        bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn),
    34083578                                   service, strlen(service)+1, NULL);
    34093579        bytes = smb_bytes_push_bytes(bytes, 4, NULL, 0);
    3410         bytes = smb_bytes_push_str(bytes, cli_ucs2(cli),
     3580        bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn),
    34113581                                   pass, strlen(pass)+1, NULL);
    34123582        bytes = smb_bytes_push_bytes(bytes, 4, NULL, 0);
    3413         bytes = smb_bytes_push_str(bytes, cli_ucs2(cli),
     3583        bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn),
    34143584                                   dev, strlen(dev)+1, NULL);
    34153585
    3416         status = cli_smb(talloc_tos(), cli, SMBtcon, 0, 0, NULL,
    3417                          talloc_get_size(bytes), bytes, &req,
    3418                          2, NULL, &ret_vwv, NULL, NULL);
    3419         if (!NT_STATUS_IS_OK(status)) {
     3586        if (tevent_req_nomem(bytes, req)) {
     3587                return tevent_req_post(req, ev);
     3588        }
     3589
     3590        subreq = cli_smb_send(state, ev, cli, SMBtcon, 0, 0, NULL,
     3591                              talloc_get_size(bytes), bytes);
     3592        if (tevent_req_nomem(subreq, req)) {
     3593                return tevent_req_post(req, ev);
     3594        }
     3595        tevent_req_set_callback(subreq, cli_raw_tcon_done, req);
     3596        return req;
     3597}
     3598
     3599static void cli_raw_tcon_done(struct tevent_req *subreq)
     3600{
     3601        struct tevent_req *req = tevent_req_callback_data(
     3602                subreq, struct tevent_req);
     3603        struct cli_raw_tcon_state *state = tevent_req_data(
     3604                req, struct cli_raw_tcon_state);
     3605        NTSTATUS status;
     3606
     3607        status = cli_smb_recv(subreq, state, NULL, 2, NULL, &state->ret_vwv,
     3608                              NULL, NULL);
     3609        TALLOC_FREE(subreq);
     3610        if (tevent_req_nterror(req, status)) {
     3611                return;
     3612        }
     3613        tevent_req_done(req);
     3614}
     3615
     3616static NTSTATUS cli_raw_tcon_recv(struct tevent_req *req,
     3617                                  uint16_t *max_xmit, uint16_t *tid)
     3618{
     3619        struct cli_raw_tcon_state *state = tevent_req_data(
     3620                req, struct cli_raw_tcon_state);
     3621        NTSTATUS status;
     3622
     3623        if (tevent_req_is_nterror(req, &status)) {
    34203624                return status;
    34213625        }
    3422 
    3423         *max_xmit = SVAL(ret_vwv + 0, 0);
    3424         *tid = SVAL(ret_vwv + 1, 0);
    3425 
     3626        *max_xmit = SVAL(state->ret_vwv + 0, 0);
     3627        *tid = SVAL(state->ret_vwv + 1, 0);
    34263628        return NT_STATUS_OK;
     3629}
     3630
     3631NTSTATUS cli_raw_tcon(struct cli_state *cli,
     3632                      const char *service, const char *pass, const char *dev,
     3633                      uint16_t *max_xmit, uint16_t *tid)
     3634{
     3635        struct tevent_context *ev;
     3636        struct tevent_req *req;
     3637        NTSTATUS status = NT_STATUS_NO_MEMORY;
     3638
     3639        ev = samba_tevent_context_init(talloc_tos());
     3640        if (ev == NULL) {
     3641                goto fail;
     3642        }
     3643        req = cli_raw_tcon_send(ev, ev, cli, service, pass, dev);
     3644        if (req == NULL) {
     3645                goto fail;
     3646        }
     3647        if (!tevent_req_poll_ntstatus(req, ev, &status)) {
     3648                goto fail;
     3649        }
     3650        status = cli_raw_tcon_recv(req, max_xmit, tid);
     3651fail:
     3652        TALLOC_FREE(ev);
     3653        return status;
    34273654}
    34283655
     
    34463673                                        user_info->password ? user_info->password : "",
    34473674                                        flags,
    3448                                         Undefined);
     3675                                        SMB_SIGNING_DEFAULT);
    34493676
    34503677        if (NT_STATUS_IS_OK(nt_status)) {
     
    35503777                DEBUG(99, ("No master browsers responded: %s\n",
    35513778                           nt_errstr(status)));
    3552                 return False;
     3779                return NULL;
    35533780        }
    35543781
Note: See TracChangeset for help on using the changeset viewer.