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/clientgen.c

    r740 r988  
    2222#include "libsmb/libsmb.h"
    2323#include "../lib/util/tevent_ntstatus.h"
    24 #include "smb_signing.h"
     24#include "../libcli/smb/smb_signing.h"
     25#include "../libcli/smb/smb_seal.h"
    2526#include "async_smb.h"
     27#include "../libcli/smb/smbXcli_base.h"
     28#include "../librpc/ndr/libndr.h"
     29#include "../include/client.h"
    2630
    2731/*******************************************************************
     
    5256
    5357/****************************************************************************
    54  Change the port number used to call on.
     58 Set the 'backup_intent' flag.
    5559****************************************************************************/
    5660
    57 void cli_set_port(struct cli_state *cli, int port)
    58 {
    59         cli->port = port;
    60 }
    61 
    62 /****************************************************************************
    63  convenience routine to find if we negotiated ucs2
    64 ****************************************************************************/
    65 
    66 bool cli_ucs2(struct cli_state *cli)
    67 {
    68         return ((cli->capabilities & CAP_UNICODE) != 0);
    69 }
    70 
    71 
    72 /****************************************************************************
    73  Read an smb from a fd ignoring all keepalive packets.
    74  The timeout is in milliseconds
    75 
    76  This is exactly the same as receive_smb except that it never returns
    77  a session keepalive packet (just as receive_smb used to do).
    78  receive_smb was changed to return keepalives as the oplock processing means this call
    79  should never go into a blocking read.
    80 ****************************************************************************/
    81 
    82 static ssize_t client_receive_smb(struct cli_state *cli, size_t maxlen)
    83 {
    84         size_t len;
    85 
    86         for(;;) {
    87                 NTSTATUS status;
    88 
    89                 set_smb_read_error(&cli->smb_rw_error, SMB_READ_OK);
    90 
    91                 status = receive_smb_raw(cli->fd, cli->inbuf, cli->bufsize,
    92                                         cli->timeout, maxlen, &len);
    93                 if (!NT_STATUS_IS_OK(status)) {
    94                         DEBUG(10,("client_receive_smb failed\n"));
    95                         show_msg(cli->inbuf);
    96 
    97                         if (NT_STATUS_EQUAL(status, NT_STATUS_END_OF_FILE)) {
    98                                 set_smb_read_error(&cli->smb_rw_error,
    99                                                    SMB_READ_EOF);
    100                                 return -1;
    101                         }
    102 
    103                         if (NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT)) {
    104                                 set_smb_read_error(&cli->smb_rw_error,
    105                                                    SMB_READ_TIMEOUT);
    106                                 return -1;
    107                         }
    108 
    109                         set_smb_read_error(&cli->smb_rw_error, SMB_READ_ERROR);
    110                         return -1;
    111                 }
    112 
    113                 /*
    114                  * I don't believe len can be < 0 with NT_STATUS_OK
    115                  * returned above, but this check doesn't hurt. JRA.
    116                  */
    117 
    118                 if ((ssize_t)len < 0) {
    119                         return len;
    120                 }
    121 
    122                 /* Ignore session keepalive packets. */
    123                 if(CVAL(cli->inbuf,0) != SMBkeepalive) {
    124                         break;
    125                 }
    126         }
    127 
    128         if (cli_encryption_on(cli)) {
    129                 NTSTATUS status = cli_decrypt_message(cli);
    130                 if (!NT_STATUS_IS_OK(status)) {
    131                         DEBUG(0, ("SMB decryption failed on incoming packet! Error %s\n",
    132                                 nt_errstr(status)));
    133                         cli->smb_rw_error = SMB_READ_BAD_DECRYPT;
    134                         return -1;
    135                 }
    136         }
    137 
    138         show_msg(cli->inbuf);
    139         return len;
    140 }
    141 
    142 static bool cli_state_set_seqnum(struct cli_state *cli, uint16_t mid, uint32_t seqnum)
    143 {
    144         struct cli_state_seqnum *c;
    145 
    146         for (c = cli->seqnum; c; c = c->next) {
    147                 if (c->mid == mid) {
    148                         c->seqnum = seqnum;
    149                         return true;
    150                 }
    151         }
    152 
    153         c = talloc_zero(cli, struct cli_state_seqnum);
    154         if (!c) {
    155                 return false;
    156         }
    157 
    158         c->mid = mid;
    159         c->seqnum = seqnum;
    160         c->persistent = false;
    161         DLIST_ADD_END(cli->seqnum, c, struct cli_state_seqnum *);
    162 
    163         return true;
    164 }
    165 
    166 bool cli_state_seqnum_persistent(struct cli_state *cli,
    167                                  uint16_t mid)
    168 {
    169         struct cli_state_seqnum *c;
    170 
    171         for (c = cli->seqnum; c; c = c->next) {
    172                 if (c->mid == mid) {
    173                         c->persistent = true;
    174                         return true;
    175                 }
    176         }
    177 
    178         return false;
    179 }
    180 
    181 bool cli_state_seqnum_remove(struct cli_state *cli,
    182                              uint16_t mid)
    183 {
    184         struct cli_state_seqnum *c;
    185 
    186         for (c = cli->seqnum; c; c = c->next) {
    187                 if (c->mid == mid) {
    188                         DLIST_REMOVE(cli->seqnum, c);
    189                         TALLOC_FREE(c);
    190                         return true;
    191                 }
    192         }
    193 
    194         return false;
    195 }
    196 
    197 static uint32_t cli_state_get_seqnum(struct cli_state *cli, uint16_t mid)
    198 {
    199         struct cli_state_seqnum *c;
    200 
    201         for (c = cli->seqnum; c; c = c->next) {
    202                 if (c->mid == mid) {
    203                         uint32_t seqnum = c->seqnum;
    204                         if (!c->persistent) {
    205                                 DLIST_REMOVE(cli->seqnum, c);
    206                                 TALLOC_FREE(c);
    207                         }
    208                         return seqnum;
    209                 }
    210         }
    211 
    212         return 0;
    213 }
    214 
    215 /****************************************************************************
    216  Recv an smb.
    217 ****************************************************************************/
    218 
    219 bool cli_receive_smb(struct cli_state *cli)
    220 {
    221         ssize_t len;
    222         uint16_t mid;
    223         uint32_t seqnum;
    224 
    225         /* fd == -1 causes segfaults -- Tom (tom@ninja.nl) */
    226         if (cli->fd == -1)
    227                 return false;
    228 
    229  again:
    230         len = client_receive_smb(cli, 0);
    231        
    232         if (len > 0) {
    233                 /* it might be an oplock break request */
    234                 if (!(CVAL(cli->inbuf, smb_flg) & FLAG_REPLY) &&
    235                     CVAL(cli->inbuf,smb_com) == SMBlockingX &&
    236                     SVAL(cli->inbuf,smb_vwv6) == 0 &&
    237                     SVAL(cli->inbuf,smb_vwv7) == 0) {
    238                         if (cli->oplock_handler) {
    239                                 int fnum = SVAL(cli->inbuf,smb_vwv2);
    240                                 unsigned char level = CVAL(cli->inbuf,smb_vwv3+1);
    241                                 if (!NT_STATUS_IS_OK(cli->oplock_handler(cli, fnum, level))) {
    242                                         return false;
    243                                 }
    244                         }
    245                         /* try to prevent loops */
    246                         SCVAL(cli->inbuf,smb_com,0xFF);
    247                         goto again;
    248                 }
    249         }
    250 
    251         /* If the server is not responding, note that now */
    252         if (len < 0) {
    253                 /*
    254                  * only log if the connection should still be open and not when
    255                  * the connection was closed due to a dropped ip message
    256                  */
    257                 if (cli->fd != -1) {
    258                         char addr[INET6_ADDRSTRLEN];
    259                         print_sockaddr(addr, sizeof(addr), &cli->dest_ss);
    260                         DEBUG(0, ("Receiving SMB: Server %s stopped responding\n",
    261                                 addr));
    262                         close(cli->fd);
    263                         cli->fd = -1;
    264                 }
    265                 return false;
    266         }
    267 
    268         mid = SVAL(cli->inbuf,smb_mid);
    269         seqnum = cli_state_get_seqnum(cli, mid);
    270 
    271         if (!cli_check_sign_mac(cli, cli->inbuf, seqnum+1)) {
    272                 /*
    273                  * If we get a signature failure in sessionsetup, then
    274                  * the server sometimes just reflects the sent signature
    275                  * back to us. Detect this and allow the upper layer to
    276                  * retrieve the correct Windows error message.
    277                  */
    278                 if (CVAL(cli->outbuf,smb_com) == SMBsesssetupX &&
    279                         (smb_len(cli->inbuf) > (smb_ss_field + 8 - 4)) &&
    280                         (SVAL(cli->inbuf,smb_flg2) & FLAGS2_SMB_SECURITY_SIGNATURES) &&
    281                         memcmp(&cli->outbuf[smb_ss_field],&cli->inbuf[smb_ss_field],8) == 0 &&
    282                         cli_is_error(cli)) {
    283 
    284                         /*
    285                          * Reflected signature on login error.
    286                          * Set bad sig but don't close fd.
    287                          */
    288                         cli->smb_rw_error = SMB_READ_BAD_SIG;
    289                         return true;
    290                 }
    291 
    292                 DEBUG(0, ("SMB Signature verification failed on incoming packet!\n"));
    293                 cli->smb_rw_error = SMB_READ_BAD_SIG;
    294                 close(cli->fd);
    295                 cli->fd = -1;
    296                 return false;
    297         };
    298         return true;
    299 }
    300 
    301 static ssize_t write_socket(int fd, const char *buf, size_t len)
    302 {
    303         ssize_t ret=0;
    304 
    305         DEBUG(6,("write_socket(%d,%d)\n",fd,(int)len));
    306         ret = write_data(fd,buf,len);
    307 
    308         DEBUG(6,("write_socket(%d,%d) wrote %d\n",fd,(int)len,(int)ret));
    309         if(ret <= 0)
    310                 DEBUG(0,("write_socket: Error writing %d bytes to socket %d: ERRNO = %s\n",
    311                         (int)len, fd, strerror(errno) ));
    312 
    313         return(ret);
    314 }
    315 
    316 /****************************************************************************
    317  Send an smb to a fd.
    318 ****************************************************************************/
    319 
    320 bool cli_send_smb(struct cli_state *cli)
    321 {
    322         size_t len;
    323         size_t nwritten=0;
    324         ssize_t ret;
    325         char *buf_out = cli->outbuf;
    326         bool enc_on = cli_encryption_on(cli);
    327         uint32_t seqnum;
    328 
    329         /* fd == -1 causes segfaults -- Tom (tom@ninja.nl) */
    330         if (cli->fd == -1)
    331                 return false;
    332 
    333         cli_calculate_sign_mac(cli, cli->outbuf, &seqnum);
    334 
    335         if (!cli_state_set_seqnum(cli, cli->mid, seqnum)) {
    336                 DEBUG(0,("Failed to store mid[%u]/seqnum[%u]\n",
    337                         (unsigned int)cli->mid,
    338                         (unsigned int)seqnum));
    339                 return false;
    340         }
    341 
    342         if (enc_on) {
    343                 NTSTATUS status = cli_encrypt_message(cli, cli->outbuf,
    344                                                       &buf_out);
    345                 if (!NT_STATUS_IS_OK(status)) {
    346                         close(cli->fd);
    347                         cli->fd = -1;
    348                         cli->smb_rw_error = SMB_WRITE_ERROR;
    349                         DEBUG(0,("Error in encrypting client message. Error %s\n",
    350                                 nt_errstr(status) ));
    351                         return false;
    352                 }
    353         }
    354 
    355         len = smb_len(buf_out) + 4;
    356 
    357         while (nwritten < len) {
    358                 ret = write_socket(cli->fd,buf_out+nwritten,len - nwritten);
    359                 if (ret <= 0) {
    360                         if (enc_on) {
    361                                 cli_free_enc_buffer(cli, buf_out);
    362                         }
    363                         close(cli->fd);
    364                         cli->fd = -1;
    365                         cli->smb_rw_error = SMB_WRITE_ERROR;
    366                         DEBUG(0,("Error writing %d bytes to client. %d (%s)\n",
    367                                 (int)len,(int)ret, strerror(errno) ));
    368                         return false;
    369                 }
    370                 nwritten += ret;
    371         }
    372 
    373         if (enc_on) {
    374                 cli_free_enc_buffer(cli, buf_out);
    375         }
    376 
    377         /* Increment the mid so we can tell between responses. */
    378         cli->mid++;
    379         if (!cli->mid)
    380                 cli->mid++;
    381         return true;
    382 }
    383 
    384 /****************************************************************************
    385  Setup basics in a outgoing packet.
    386 ****************************************************************************/
    387 
    388 void cli_setup_packet_buf(struct cli_state *cli, char *buf)
    389 {
    390         uint16 flags2;
    391         cli->rap_error = 0;
    392         SIVAL(buf,smb_rcls,0);
    393         SSVAL(buf,smb_pid,cli->pid);
    394         memset(buf+smb_pidhigh, 0, 12);
    395         SSVAL(buf,smb_uid,cli->vuid);
    396         SSVAL(buf,smb_mid,cli->mid);
    397 
    398         if (cli->protocol <= PROTOCOL_CORE) {
    399                 return;
    400         }
    401 
    402         if (cli->case_sensitive) {
    403                 SCVAL(buf,smb_flg,0x0);
    404         } else {
    405                 /* Default setting, case insensitive. */
    406                 SCVAL(buf,smb_flg,0x8);
    407         }
    408         flags2 = FLAGS2_LONG_PATH_COMPONENTS;
    409         if (cli->capabilities & CAP_UNICODE)
    410                 flags2 |= FLAGS2_UNICODE_STRINGS;
    411         if ((cli->capabilities & CAP_DFS) && cli->dfsroot)
    412                 flags2 |= FLAGS2_DFS_PATHNAMES;
    413         if (cli->capabilities & CAP_STATUS32)
    414                 flags2 |= FLAGS2_32_BIT_ERROR_CODES;
    415         if (cli->use_spnego)
    416                 flags2 |= FLAGS2_EXTENDED_SECURITY;
    417         SSVAL(buf,smb_flg2, flags2);
    418 }
    419 
    420 void cli_setup_packet(struct cli_state *cli)
    421 {
    422         cli_setup_packet_buf(cli, cli->outbuf);
    423 }
    424 
    425 /****************************************************************************
    426  Setup the bcc length of the packet from a pointer to the end of the data.
    427 ****************************************************************************/
    428 
    429 void cli_setup_bcc(struct cli_state *cli, void *p)
    430 {
    431         set_message_bcc(cli->outbuf, PTR_DIFF(p, smb_buf(cli->outbuf)));
    432 }
    433 
    434 /****************************************************************************
    435  Initialize Domain, user or password.
    436 ****************************************************************************/
    437 
    438 NTSTATUS cli_set_domain(struct cli_state *cli, const char *domain)
    439 {
    440         TALLOC_FREE(cli->domain);
    441         cli->domain = talloc_strdup(cli, domain ? domain : "");
    442         if (cli->domain == NULL) {
    443                 return NT_STATUS_NO_MEMORY;
    444         }
    445         return NT_STATUS_OK;
    446 }
    447 
    448 NTSTATUS cli_set_username(struct cli_state *cli, const char *username)
    449 {
    450         TALLOC_FREE(cli->user_name);
    451         cli->user_name = talloc_strdup(cli, username ? username : "");
    452         if (cli->user_name == NULL) {
    453                 return NT_STATUS_NO_MEMORY;
    454         }
    455         return NT_STATUS_OK;
    456 }
    457 
    458 NTSTATUS cli_set_password(struct cli_state *cli, const char *password)
    459 {
    460         TALLOC_FREE(cli->password);
    461 
    462         /* Password can be NULL. */
    463         if (password) {
    464                 cli->password = talloc_strdup(cli, password);
    465                 if (cli->password == NULL) {
    466                         return NT_STATUS_NO_MEMORY;
    467                 }
    468         } else {
    469                 /* Use zero NTLMSSP hashes and session key. */
    470                 cli->password = NULL;
    471         }
    472 
    473         return NT_STATUS_OK;
    474 }
    475 
    476 /****************************************************************************
    477  Initialise credentials of a client structure.
    478 ****************************************************************************/
    479 
    480 NTSTATUS cli_init_creds(struct cli_state *cli, const char *username, const char *domain, const char *password)
    481 {
    482         NTSTATUS status = cli_set_username(cli, username);
    483         if (!NT_STATUS_IS_OK(status)) {
    484                 return status;
    485         }
    486         status = cli_set_domain(cli, domain);
    487         if (!NT_STATUS_IS_OK(status)) {
    488                 return status;
    489         }
    490         DEBUG(10,("cli_init_creds: user %s domain %s\n", cli->user_name, cli->domain));
    491 
    492         return cli_set_password(cli, password);
     61bool cli_set_backup_intent(struct cli_state *cli, bool flag)
     62{
     63        bool old_state = cli->backup_intent;
     64        cli->backup_intent = flag;
     65        return old_state;
    49366}
    49467
     
    49871****************************************************************************/
    49972
    500 struct cli_state *cli_initialise_ex(int signing_state)
     73struct GUID cli_state_client_guid;
     74
     75struct cli_state *cli_state_create(TALLOC_CTX *mem_ctx,
     76                                   int fd,
     77                                   const char *remote_name,
     78                                   const char *remote_realm,
     79                                   int signing_state, int flags)
    50180{
    50281        struct cli_state *cli = NULL;
    503         bool allow_smb_signing = false;
    504         bool mandatory_signing = false;
     82        bool use_spnego = lp_client_use_spnego();
     83        bool force_dos_errors = false;
     84        bool force_ascii = false;
     85        bool use_level_II_oplocks = false;
     86        uint32_t smb1_capabilities = 0;
     87        uint32_t smb2_capabilities = 0;
     88        struct GUID client_guid;
     89
     90        if (!GUID_all_zero(&cli_state_client_guid)) {
     91                client_guid = cli_state_client_guid;
     92        } else {
     93                client_guid = GUID_random();
     94        }
    50595
    50696        /* Check the effective uid - make sure we are not setuid */
     
    510100        }
    511101
    512         cli = TALLOC_ZERO_P(NULL, struct cli_state);
     102        cli = talloc_zero(mem_ctx, struct cli_state);
    513103        if (!cli) {
    514104                return NULL;
     105        }
     106
     107        cli->server_domain = talloc_strdup(cli, "");
     108        if (!cli->server_domain) {
     109                goto error;
     110        }
     111        cli->server_os = talloc_strdup(cli, "");
     112        if (!cli->server_os) {
     113                goto error;
     114        }
     115        cli->server_type = talloc_strdup(cli, "");
     116        if (!cli->server_type) {
     117                goto error;
    515118        }
    516119
     
    519122                goto error;
    520123        }
    521         cli->port = 0;
    522         cli->fd = -1;
    523         cli->cnum = -1;
    524         cli->pid = (uint16)sys_getpid();
    525         cli->mid = 1;
    526         cli->vuid = UID_FIELD_INVALID;
    527         cli->protocol = PROTOCOL_NT1;
    528         cli->timeout = 20000; /* Timeout is in milliseconds. */
    529         cli->bufsize = CLI_BUFFER_SIZE+4;
    530         cli->max_xmit = cli->bufsize;
    531         cli->outbuf = (char *)SMB_MALLOC(cli->bufsize+SAFETY_MARGIN);
    532         cli->seqnum = 0;
    533         cli->inbuf = (char *)SMB_MALLOC(cli->bufsize+SAFETY_MARGIN);
    534         cli->oplock_handler = cli_oplock_ack;
    535         cli->case_sensitive = false;
    536         cli->smb_rw_error = SMB_READ_OK;
    537 
    538         cli->use_spnego = lp_client_use_spnego();
    539 
    540         cli->capabilities = CAP_UNICODE | CAP_STATUS32 | CAP_DFS;
     124        cli->raw_status = NT_STATUS_INTERNAL_ERROR;
     125        cli->map_dos_errors = true; /* remove this */
     126        cli->timeout = CLIENT_TIMEOUT;
    541127
    542128        /* Set the CLI_FORCE_DOSERR environment variable to test
    543129           client routines using DOS errors instead of STATUS32
    544130           ones.  This intended only as a temporary hack. */   
    545         if (getenv("CLI_FORCE_DOSERR"))
    546                 cli->force_dos_errors = true;
    547 
    548         if (lp_client_signing()) {
    549                 allow_smb_signing = true;
    550         }
    551 
    552         if (lp_client_signing() == Required) {
    553                 mandatory_signing = true;
    554         }
    555 
    556         if (signing_state != Undefined) {
    557                 allow_smb_signing = true;
    558         }
    559 
    560         if (signing_state == false) {
    561                 allow_smb_signing = false;
    562                 mandatory_signing = false;
    563         }
    564 
    565         if (signing_state == Required) {
    566                 mandatory_signing = true;
    567         }
    568 
    569         if (!cli->outbuf || !cli->inbuf)
    570                 goto error;
    571 
    572         memset(cli->outbuf, 0, cli->bufsize);
    573         memset(cli->inbuf, 0, cli->bufsize);
    574 
    575 
    576 #if defined(DEVELOPER)
    577         /* just because we over-allocate, doesn't mean it's right to use it */
    578         clobber_region(__FUNCTION__, __LINE__, cli->outbuf+cli->bufsize, SAFETY_MARGIN);
    579         clobber_region(__FUNCTION__, __LINE__, cli->inbuf+cli->bufsize, SAFETY_MARGIN);
    580 #endif
    581 
    582         /* initialise signing */
    583         cli->signing_state = smb_signing_init(cli,
    584                                               allow_smb_signing,
    585                                               mandatory_signing);
    586         if (!cli->signing_state) {
     131        if (getenv("CLI_FORCE_DOSERR")) {
     132                force_dos_errors = true;
     133        }
     134        if (flags & CLI_FULL_CONNECTION_FORCE_DOS_ERRORS) {
     135                force_dos_errors = true;
     136        }
     137
     138        if (getenv("CLI_FORCE_ASCII")) {
     139                force_ascii = true;
     140        }
     141        if (!lp_unicode()) {
     142                force_ascii = true;
     143        }
     144        if (flags & CLI_FULL_CONNECTION_FORCE_ASCII) {
     145                force_ascii = true;
     146        }
     147
     148        if (flags & CLI_FULL_CONNECTION_DONT_SPNEGO) {
     149                use_spnego = false;
     150        } else if (flags & CLI_FULL_CONNECTION_USE_KERBEROS) {
     151                cli->use_kerberos = true;
     152        }
     153        if ((flags & CLI_FULL_CONNECTION_FALLBACK_AFTER_KERBEROS) &&
     154             cli->use_kerberos) {
     155                cli->fallback_after_kerberos = true;
     156        }
     157
     158        if (flags & CLI_FULL_CONNECTION_USE_CCACHE) {
     159                cli->use_ccache = true;
     160        }
     161
     162        if (flags & CLI_FULL_CONNECTION_USE_NT_HASH) {
     163                cli->pw_nt_hash = true;
     164        }
     165
     166        if (flags & CLI_FULL_CONNECTION_OPLOCKS) {
     167                cli->use_oplocks = true;
     168        }
     169        if (flags & CLI_FULL_CONNECTION_LEVEL_II_OPLOCKS) {
     170                use_level_II_oplocks = true;
     171        }
     172
     173        if (signing_state == SMB_SIGNING_IPC_DEFAULT) {
     174                /*
     175                 * Ensure for IPC/RPC the default is to require
     176                 * signing unless explicitly turned off by the
     177                 * administrator.
     178                 */
     179                signing_state = lp_client_ipc_signing();
     180        }
     181
     182        if (signing_state == SMB_SIGNING_DEFAULT) {
     183                signing_state = lp_client_signing();
     184        }
     185
     186        smb1_capabilities = 0;
     187        smb1_capabilities |= CAP_LARGE_FILES;
     188        smb1_capabilities |= CAP_NT_SMBS | CAP_RPC_REMOTE_APIS;
     189        smb1_capabilities |= CAP_LOCK_AND_READ | CAP_NT_FIND;
     190        smb1_capabilities |= CAP_DFS | CAP_W2K_SMBS;
     191        smb1_capabilities |= CAP_LARGE_READX|CAP_LARGE_WRITEX;
     192        smb1_capabilities |= CAP_LWIO;
     193
     194        if (!force_dos_errors) {
     195                smb1_capabilities |= CAP_STATUS32;
     196        }
     197
     198        if (!force_ascii) {
     199                smb1_capabilities |= CAP_UNICODE;
     200        }
     201
     202        if (use_spnego) {
     203                smb1_capabilities |= CAP_EXTENDED_SECURITY;
     204        }
     205
     206        if (use_level_II_oplocks) {
     207                smb1_capabilities |= CAP_LEVEL_II_OPLOCKS;
     208        }
     209
     210        smb2_capabilities = SMB2_CAP_ALL;
     211
     212        if (remote_realm) {
     213                cli->remote_realm = talloc_strdup(cli, remote_realm);
     214                if (cli->remote_realm == NULL) {
     215                        goto error;
     216                }
     217        }
     218
     219        cli->conn = smbXcli_conn_create(cli, fd, remote_name,
     220                                        signing_state,
     221                                        smb1_capabilities,
     222                                        &client_guid,
     223                                        smb2_capabilities);
     224        if (cli->conn == NULL) {
    587225                goto error;
    588226        }
    589227
    590         cli->outgoing = tevent_queue_create(cli, "cli_outgoing");
    591         if (cli->outgoing == NULL) {
     228        cli->smb1.pid = (uint16_t)getpid();
     229        cli->smb1.vc_num = cli->smb1.pid;
     230        cli->smb1.tcon = smbXcli_tcon_create(cli);
     231        if (cli->smb1.tcon == NULL) {
    592232                goto error;
    593233        }
    594         cli->pending = NULL;
     234        smb1cli_tcon_set_id(cli->smb1.tcon, UINT16_MAX);
     235        cli->smb1.session = smbXcli_session_create(cli, cli->conn);
     236        if (cli->smb1.session == NULL) {
     237                goto error;
     238        }
    595239
    596240        cli->initialised = 1;
    597 
    598241        return cli;
    599242
     
    602245 error:
    603246
    604         SAFE_FREE(cli->inbuf);
    605         SAFE_FREE(cli->outbuf);
    606247        TALLOC_FREE(cli);
    607248        return NULL;
    608 }
    609 
    610 struct cli_state *cli_initialise(void)
    611 {
    612         return cli_initialise_ex(Undefined);
    613249}
    614250
     
    642278         * later.  This tree disconnect forces the peer to clean up, since the
    643279         * connection will be going away.
    644          *
    645          * Also, do not do tree disconnect when cli->smb_rw_error is SMB_DO_NOT_DO_TDIS
    646          * the only user for this so far is smbmount which passes opened connection
    647          * down to kernel's smbfs module.
    648280         */
    649         if ( (cli->cnum != (uint16)-1) && (cli->smb_rw_error != SMB_DO_NOT_DO_TDIS ) ) {
     281        if (cli_state_has_tcon(cli)) {
    650282                cli_tdis(cli);
    651283        }
    652        
    653         SAFE_FREE(cli->outbuf);
    654         SAFE_FREE(cli->inbuf);
    655 
    656         data_blob_free(&cli->secblob);
    657         data_blob_free(&cli->user_session_key);
    658 
    659         if (cli->fd != -1) {
    660                 close(cli->fd);
    661         }
    662         cli->fd = -1;
    663         cli->smb_rw_error = SMB_READ_OK;
    664 
    665         /*
    666          * Need to free pending first, they remove themselves
    667          */
    668         while (cli->pending) {
    669                 talloc_free(cli->pending[0]);
    670         }
     284
     285        smbXcli_conn_disconnect(cli->conn, NT_STATUS_OK);
     286
    671287        TALLOC_FREE(cli);
    672288}
     
    698314}
    699315
    700 /****************************************************************************
    701  Set socket options on a open connection.
    702 ****************************************************************************/
    703 
    704 void cli_sockopt(struct cli_state *cli, const char *options)
    705 {
    706         set_socket_options(cli->fd, options);
     316const char *cli_state_remote_realm(struct cli_state *cli)
     317{
     318        return cli->remote_realm;
     319}
     320
     321uint16_t cli_state_get_vc_num(struct cli_state *cli)
     322{
     323        return cli->smb1.vc_num;
    707324}
    708325
     
    711328****************************************************************************/
    712329
    713 uint16 cli_setpid(struct cli_state *cli, uint16 pid)
    714 {
    715         uint16 ret = cli->pid;
    716         cli->pid = pid;
     330uint16_t cli_setpid(struct cli_state *cli, uint16_t pid)
     331{
     332        uint16_t ret = cli->smb1.pid;
     333        cli->smb1.pid = pid;
     334        return ret;
     335}
     336
     337uint16_t cli_getpid(struct cli_state *cli)
     338{
     339        return cli->smb1.pid;
     340}
     341
     342bool cli_state_has_tcon(struct cli_state *cli)
     343{
     344        uint16_t tid = cli_state_get_tid(cli);
     345
     346        if (tid == UINT16_MAX) {
     347                return false;
     348        }
     349
     350        return true;
     351}
     352
     353uint16_t cli_state_get_tid(struct cli_state *cli)
     354{
     355        return smb1cli_tcon_current_id(cli->smb1.tcon);
     356}
     357
     358uint16_t cli_state_set_tid(struct cli_state *cli, uint16_t tid)
     359{
     360        uint16_t ret = smb1cli_tcon_current_id(cli->smb1.tcon);
     361        smb1cli_tcon_set_id(cli->smb1.tcon, tid);
     362        return ret;
     363}
     364
     365uint16_t cli_state_get_uid(struct cli_state *cli)
     366{
     367        return smb1cli_session_current_id(cli->smb1.session);
     368}
     369
     370uint16_t cli_state_set_uid(struct cli_state *cli, uint16_t uid)
     371{
     372        uint16_t ret = smb1cli_session_current_id(cli->smb1.session);
     373        smb1cli_session_set_id(cli->smb1.session, uid);
    717374        return ret;
    718375}
     
    724381bool cli_set_case_sensitive(struct cli_state *cli, bool case_sensitive)
    725382{
    726         bool ret = cli->case_sensitive;
    727         cli->case_sensitive = case_sensitive;
     383        bool ret;
     384        uint32_t fs_attrs;
     385        struct smbXcli_tcon *tcon;
     386
     387        if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) {
     388                tcon = cli->smb2.tcon;
     389        } else {
     390                tcon = cli->smb1.tcon;
     391        }
     392
     393        fs_attrs = smbXcli_tcon_get_fs_attributes(tcon);
     394        if (fs_attrs & FILE_CASE_SENSITIVE_SEARCH) {
     395                ret = true;
     396        } else {
     397                ret = false;
     398        }
     399        if (case_sensitive) {
     400                fs_attrs |= FILE_CASE_SENSITIVE_SEARCH;
     401        } else {
     402                fs_attrs &= ~FILE_CASE_SENSITIVE_SEARCH;
     403        }
     404        smbXcli_tcon_set_fs_attributes(tcon, fs_attrs);
     405
    728406        return ret;
    729407}
    730408
     409uint32_t cli_state_available_size(struct cli_state *cli, uint32_t ofs)
     410{
     411        uint32_t ret = smb1cli_conn_max_xmit(cli->conn);
     412
     413        if (ofs >= ret) {
     414                return 0;
     415        }
     416
     417        ret -= ofs;
     418
     419        return ret;
     420}
     421
     422time_t cli_state_server_time(struct cli_state *cli)
     423{
     424        NTTIME nt;
     425        time_t t;
     426
     427        nt = smbXcli_conn_server_system_time(cli->conn);
     428        t = nt_time_to_unix(nt);
     429
     430        return t;
     431}
     432
    731433struct cli_echo_state {
    732         uint16_t vwv[1];
    733         DATA_BLOB data;
    734         int num_echos;
     434        bool is_smb2;
    735435};
    736436
    737437static void cli_echo_done(struct tevent_req *subreq);
    738438
    739 struct tevent_req *cli_echo_send(TALLOC_CTX *mem_ctx, struct event_context *ev,
     439struct tevent_req *cli_echo_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev,
    740440                                 struct cli_state *cli, uint16_t num_echos,
    741441                                 DATA_BLOB data)
     
    748448                return NULL;
    749449        }
    750         SSVAL(state->vwv, 0, num_echos);
    751         state->data = data;
    752         state->num_echos = num_echos;
    753 
    754         subreq = cli_smb_send(state, ev, cli, SMBecho, 0, 1, state->vwv,
    755                               data.length, data.data);
    756         if (subreq == NULL) {
    757                 goto fail;
     450
     451        if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) {
     452                state->is_smb2 = true;
     453                subreq = smb2cli_echo_send(state, ev,
     454                                           cli->conn,
     455                                           cli->timeout);
     456        } else {
     457                subreq = smb1cli_echo_send(state, ev,
     458                                           cli->conn,
     459                                           cli->timeout,
     460                                           num_echos,
     461                                           data);
     462        }
     463        if (tevent_req_nomem(subreq, req)) {
     464                return tevent_req_post(req, ev);
    758465        }
    759466        tevent_req_set_callback(subreq, cli_echo_done, req);
     467
    760468        return req;
    761  fail:
    762         TALLOC_FREE(req);
    763         return NULL;
    764469}
    765470
     
    771476                req, struct cli_echo_state);
    772477        NTSTATUS status;
    773         uint32_t num_bytes;
    774         uint8_t *bytes;
    775         uint8_t *inbuf;
    776 
    777         status = cli_smb_recv(subreq, state, &inbuf, 0, NULL, NULL,
    778                               &num_bytes, &bytes);
     478
     479        if (state->is_smb2) {
     480                status = smb2cli_echo_recv(subreq);
     481        } else {
     482                status = smb1cli_echo_recv(subreq);
     483        }
     484        TALLOC_FREE(subreq);
    779485        if (!NT_STATUS_IS_OK(status)) {
    780486                tevent_req_nterror(req, status);
    781487                return;
    782488        }
    783         if ((num_bytes != state->data.length)
    784             || (memcmp(bytes, state->data.data, num_bytes) != 0)) {
    785                 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
    786                 return;
    787         }
    788 
    789         state->num_echos -=1;
    790         if (state->num_echos == 0) {
    791                 tevent_req_done(req);
    792                 return;
    793         }
    794 
    795         if (!cli_smb_req_set_pending(subreq)) {
    796                 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
    797                 return;
    798         }
     489
     490        tevent_req_done(req);
    799491}
    800492
     
    823515{
    824516        TALLOC_CTX *frame = talloc_stackframe();
    825         struct event_context *ev;
     517        struct tevent_context *ev;
    826518        struct tevent_req *req;
    827519        NTSTATUS status = NT_STATUS_OK;
    828520
    829         if (cli_has_async_calls(cli)) {
     521        if (smbXcli_conn_has_async_calls(cli->conn)) {
    830522                /*
    831523                 * Can't use sync call while an async call is in flight
     
    835527        }
    836528
    837         ev = event_context_init(frame);
     529        ev = samba_tevent_context_init(frame);
    838530        if (ev == NULL) {
    839531                status = NT_STATUS_NO_MEMORY;
     
    847539        }
    848540
    849         if (!tevent_req_poll(req, ev)) {
    850                 status = map_nt_error_from_unix(errno);
     541        if (!tevent_req_poll_ntstatus(req, ev, &status)) {
    851542                goto fail;
    852543        }
     
    855546 fail:
    856547        TALLOC_FREE(frame);
    857         if (!NT_STATUS_IS_OK(status)) {
    858                 cli_set_error(cli, status);
    859         }
    860548        return status;
    861549}
     
    898586        NTSTATUS status = NT_STATUS_NO_MEMORY;
    899587
    900         if (cli_has_async_calls(cli)) {
     588        if (smbXcli_conn_has_async_calls(cli->conn)) {
    901589                return NT_STATUS_INVALID_PARAMETER;
    902590        }
    903         ev = tevent_context_init(mem_ctx);
     591        ev = samba_tevent_context_init(mem_ctx);
    904592        if (ev == NULL) {
    905593                goto fail;
Note: See TracChangeset for help on using the changeset viewer.