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

Location:
vendor/current/source4/libcli/raw
Files:
1 deleted
23 edited

Legend:

Unmodified
Added
Removed
  • vendor/current/source4/libcli/raw/clioplock.c

    r414 r988  
    3131
    3232        req = smbcli_request_setup(tree, SMBlockingX, 8, 0);
     33        if (req == NULL) {
     34                return false;
     35        }
    3336
    3437        SSVAL(req->out.vwv,VWV(0),0xFF);
     
    4144        SSVAL(req->out.vwv,VWV(7),0);
    4245
    43         /* this request does not expect a reply, so tell the signing
    44            subsystem not to allocate an id for a reply */
    45         req->one_way_request = 1;
    46 
    47         ret = smbcli_request_send(req);
     46        /*
     47         * The low level code knows it is a
     48         * one way request by looking at SMBlockingX,
     49         * wct == 8 and LOCKING_ANDX_OPLOCK_RELEASE
     50         */
     51        ret = smbcli_request_send(req);
    4852
    4953        return ret;
  • vendor/current/source4/libcli/raw/clisession.c

    r414 r988  
    2424#include "libcli/raw/raw_proto.h"
    2525#include "system/filesys.h"
     26#include "../libcli/smb/smbXcli_base.h"
    2627
    2728#define SETUP_REQUEST_SESSION(cmd, wct, buflen) do { \
     
    5556        session->vuid = UID_FIELD_INVALID;
    5657        session->options = options;
    57        
     58
     59        /*
     60         * for now session->vuid is still used by the callers, but we call:
     61         * smb1cli_session_set_id(session->smbXcli, session->vuid);
     62         * before using session->smbXcli, in future we should remove
     63         * session->vuid.
     64         */
     65        session->smbXcli = smbXcli_session_create(session, transport->conn);
     66        if (session->smbXcli == NULL) {
     67                talloc_free(session);
     68                return NULL;
     69        }
     70
    5871        capabilities = transport->negotiate.capabilities;
    5972
     
    6982                flags2 |= FLAGS2_EXTENDED_SECURITY;
    7083        }
    71         if (session->transport->negotiate.sign_info.doing_signing) {
     84        if (smb1cli_conn_signing_is_active(session->transport->conn)) {
    7285                flags2 |= FLAGS2_SMB_SECURITY_SIGNATURES;
    7386        }
  • vendor/current/source4/libcli/raw/clisocket.c

    r740 r988  
    2222
    2323#include "includes.h"
     24#include "system/network.h"
     25#include "../lib/async_req/async_sock.h"
     26#include "../lib/util/tevent_ntstatus.h"
    2427#include "lib/events/events.h"
    2528#include "libcli/raw/libcliraw.h"
     
    2932#include "param/param.h"
    3033#include "libcli/raw/raw_proto.h"
     34#include "../libcli/smb/read_smb.h"
     35
     36struct smbcli_transport_connect_state {
     37        struct tevent_context *ev;
     38        struct socket_context *sock;
     39        struct tevent_req *io_req;
     40        uint8_t *request;
     41        struct iovec iov;
     42        uint8_t *response;
     43};
     44
     45static void smbcli_transport_connect_cleanup(struct tevent_req *req,
     46                                             enum tevent_req_state req_state);
     47static void smbcli_transport_connect_writev_done(struct tevent_req *subreq);
     48static void smbcli_transport_connect_read_smb_done(struct tevent_req *subreq);
     49
     50static struct tevent_req *smbcli_transport_connect_send(TALLOC_CTX *mem_ctx,
     51                                                 struct tevent_context *ev,
     52                                                 struct socket_context *sock,
     53                                                 uint16_t port,
     54                                                 uint32_t timeout_msec,
     55                                                 struct nbt_name *calling,
     56                                                 struct nbt_name *called)
     57{
     58        struct tevent_req *req;
     59        struct smbcli_transport_connect_state *state;
     60        struct tevent_req *subreq;
     61        DATA_BLOB calling_blob, called_blob;
     62        uint8_t *p;
     63        NTSTATUS status;
     64
     65        req = tevent_req_create(mem_ctx, &state,
     66                                struct smbcli_transport_connect_state);
     67        if (req == NULL) {
     68                return NULL;
     69        }
     70        state->ev = ev;
     71        state->sock = sock;
     72
     73        if (port != 139) {
     74                tevent_req_done(req);
     75                return tevent_req_post(req, ev);
     76        }
     77
     78        tevent_req_set_cleanup_fn(req, smbcli_transport_connect_cleanup);
     79
     80        status = nbt_name_to_blob(state, &calling_blob, calling);
     81        if (tevent_req_nterror(req, status)) {
     82                return tevent_req_post(req, ev);
     83        }
     84
     85        status = nbt_name_to_blob(state, &called_blob, called);
     86        if (tevent_req_nterror(req, status)) {
     87                return tevent_req_post(req, ev);
     88        }
     89
     90        state->request = talloc_array(state, uint8_t,
     91                                      NBT_HDR_SIZE +
     92                                      called_blob.length +
     93                                      calling_blob.length);
     94        if (tevent_req_nomem(state->request, req)) {
     95                return tevent_req_post(req, ev);
     96        }
     97
     98        /* put in the destination name */
     99        p = state->request + NBT_HDR_SIZE;
     100        memcpy(p, called_blob.data, called_blob.length);
     101        p += called_blob.length;
     102
     103        memcpy(p, calling_blob.data, calling_blob.length);
     104        p += calling_blob.length;
     105
     106        _smb_setlen_nbt(state->request,
     107                        PTR_DIFF(p, state->request) - NBT_HDR_SIZE);
     108        SCVAL(state->request, 0, NBSSrequest);
     109
     110        state->iov.iov_len = talloc_array_length(state->request);
     111        state->iov.iov_base = (void *)state->request;
     112
     113        subreq = writev_send(state, ev, NULL,
     114                             sock->fd,
     115                             true, /* err_on_readability */
     116                             &state->iov, 1);
     117        if (tevent_req_nomem(subreq, req)) {
     118                return tevent_req_post(req, ev);
     119        }
     120        tevent_req_set_callback(subreq,
     121                                smbcli_transport_connect_writev_done,
     122                                req);
     123        state->io_req = subreq;
     124
     125        if (timeout_msec > 0) {
     126                struct timeval endtime;
     127
     128                endtime = timeval_current_ofs_msec(timeout_msec);
     129                if (!tevent_req_set_endtime(req, ev, endtime)) {
     130                        return tevent_req_post(req, ev);
     131                }
     132        }
     133
     134        return req;
     135}
     136
     137static void smbcli_transport_connect_cleanup(struct tevent_req *req,
     138                                             enum tevent_req_state req_state)
     139{
     140        struct smbcli_transport_connect_state *state =
     141                tevent_req_data(req,
     142                struct smbcli_transport_connect_state);
     143
     144        TALLOC_FREE(state->io_req);
     145
     146        if (state->sock == NULL) {
     147                return;
     148        }
     149
     150        if (state->sock->fd == -1) {
     151                return;
     152        }
     153
     154        if (req_state == TEVENT_REQ_DONE) {
     155                /*
     156                 * we keep the socket open for the caller to use
     157                 */
     158                state->sock = NULL;
     159                return;
     160        }
     161
     162        close(state->sock->fd);
     163        state->sock->fd = -1;
     164        state->sock = NULL;
     165}
     166
     167static void smbcli_transport_connect_writev_done(struct tevent_req *subreq)
     168{
     169        struct tevent_req *req =
     170                tevent_req_callback_data(subreq,
     171                struct tevent_req);
     172        struct smbcli_transport_connect_state *state =
     173                tevent_req_data(req,
     174                struct smbcli_transport_connect_state);
     175        ssize_t ret;
     176        int err;
     177
     178        state->io_req = NULL;
     179
     180        ret = writev_recv(subreq, &err);
     181        TALLOC_FREE(subreq);
     182        if (ret == -1) {
     183                NTSTATUS status = map_nt_error_from_unix_common(err);
     184                tevent_req_nterror(req, status);
     185                return;
     186        }
     187
     188        subreq = read_smb_send(state, state->ev,
     189                               state->sock->fd);
     190        if (tevent_req_nomem(subreq, req)) {
     191                return;
     192        }
     193        tevent_req_set_callback(subreq,
     194                                smbcli_transport_connect_read_smb_done,
     195                                req);
     196        state->io_req = subreq;
     197}
     198
     199static void smbcli_transport_connect_read_smb_done(struct tevent_req *subreq)
     200{
     201        struct tevent_req *req =
     202                tevent_req_callback_data(subreq,
     203                struct tevent_req);
     204        struct smbcli_transport_connect_state *state =
     205                tevent_req_data(req,
     206                struct smbcli_transport_connect_state);
     207        ssize_t ret;
     208        int err;
     209        NTSTATUS status;
     210        uint8_t error;
     211
     212        state->io_req = NULL;
     213
     214        ret = read_smb_recv(subreq, state,
     215                            &state->response, &err);
     216        TALLOC_FREE(subreq);
     217        if (ret == -1) {
     218                status = map_nt_error_from_unix_common(err);
     219                tevent_req_nterror(req, status);
     220                return;
     221        }
     222
     223        if (ret < 4) {
     224                tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
     225                return;
     226        }
     227
     228        switch (CVAL(state->response, 0)) {
     229        case NBSSpositive:
     230                tevent_req_done(req);
     231                return;
     232
     233        case NBSSnegative:
     234                if (ret < 5) {
     235                        tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
     236                        return;
     237                }
     238
     239                error = CVAL(state->response, 4);
     240                switch (error) {
     241                case 0x80:
     242                case 0x81:
     243                        status = NT_STATUS_REMOTE_NOT_LISTENING;
     244                        break;
     245                case 0x82:
     246                        status = NT_STATUS_RESOURCE_NAME_NOT_FOUND;
     247                        break;
     248                case 0x83:
     249                        status = NT_STATUS_REMOTE_RESOURCES;
     250                        break;
     251                default:
     252                        status = NT_STATUS_INVALID_NETWORK_RESPONSE;
     253                        break;
     254                }
     255                break;
     256
     257        case NBSSretarget:
     258                DEBUG(1,("Warning: session retarget not supported\n"));
     259                status = NT_STATUS_NOT_SUPPORTED;
     260                break;
     261
     262        default:
     263                status = NT_STATUS_INVALID_NETWORK_RESPONSE;
     264                break;
     265        }
     266
     267        tevent_req_nterror(req, status);
     268}
     269
     270static NTSTATUS smbcli_transport_connect_recv(struct tevent_req *req)
     271{
     272        return tevent_req_simple_recv_ntstatus(req);
     273}
    31274
    32275struct sock_connect_state {
     
    37280        const char *socket_options;
    38281        struct smbcli_socket *result;
     282        struct socket_connect_multi_ex multi_ex;
     283        struct nbt_name calling;
     284        struct nbt_name called;
    39285};
    40286
     
    43289  if port is 0 then choose 445 then 139
    44290*/
     291
     292static struct tevent_req *smbcli_sock_establish_send(TALLOC_CTX *mem_ctx,
     293                                                     struct tevent_context *ev,
     294                                                     struct socket_context *sock,
     295                                                     struct socket_address *addr,
     296                                                     void *private_data)
     297{
     298        struct sock_connect_state *state =
     299                talloc_get_type_abort(private_data,
     300                struct sock_connect_state);
     301        uint32_t timeout_msec = 15 * 1000;
     302
     303        return smbcli_transport_connect_send(state,
     304                                             ev,
     305                                             sock,
     306                                             addr->port,
     307                                             timeout_msec,
     308                                             &state->calling,
     309                                             &state->called);
     310}
     311
     312static NTSTATUS smbcli_sock_establish_recv(struct tevent_req *req)
     313{
     314        return smbcli_transport_connect_recv(req);
     315}
    45316
    46317static void smbcli_sock_connect_recv_conn(struct composite_context *ctx);
     
    52323                                                   struct resolve_context *resolve_ctx,
    53324                                                   struct tevent_context *event_ctx,
    54                                                    const char *socket_options)
     325                                                   const char *socket_options,
     326                                                   struct nbt_name *calling,
     327                                                   struct nbt_name *called)
    55328{
    56329        struct composite_context *result, *ctx;
    57330        struct sock_connect_state *state;
     331        NTSTATUS status;
    58332        int i;
    59333
     
    85359        }
    86360
    87         ctx = socket_connect_multi_send(state, host_addr,
    88                                         state->num_ports, state->ports,
    89                                         resolve_ctx,
    90                                         state->ctx->event_ctx);
     361        state->multi_ex.private_data = state;
     362        state->multi_ex.establish_send = smbcli_sock_establish_send;
     363        state->multi_ex.establish_recv = smbcli_sock_establish_recv;
     364
     365        status = nbt_name_dup(state, calling, &state->calling);
     366        if (!NT_STATUS_IS_OK(status)) {
     367                goto failed;
     368        }
     369        status = nbt_name_dup(state, called, &state->called);
     370        if (!NT_STATUS_IS_OK(status)) {
     371                goto failed;
     372        }
     373
     374        ctx = socket_connect_multi_ex_send(state, host_addr,
     375                                           state->num_ports, state->ports,
     376                                           resolve_ctx,
     377                                           state->ctx->event_ctx,
     378                                           &state->multi_ex);
    91379        if (ctx == NULL) goto failed;
    92380        ctx->async.fn = smbcli_sock_connect_recv_conn;
     
    107395        uint16_t port;
    108396
    109         state->ctx->status = socket_connect_multi_recv(ctx, state, &sock,
    110                                                        &port);
     397        state->ctx->status = socket_connect_multi_ex_recv(ctx, state, &sock,
     398                                                          &port);
    111399        if (!composite_is_ok(state->ctx)) return;
    112400
     
    158446                             struct resolve_context *resolve_ctx,
    159447                             struct tevent_context *event_ctx,
    160                                  const char *socket_options,
     448                             const char *socket_options,
     449                             struct nbt_name *calling,
     450                             struct nbt_name *called,
    161451                             struct smbcli_socket **result)
    162452{
     
    164454                smbcli_sock_connect_send(mem_ctx, host_addr, ports, host_name,
    165455                                         resolve_ctx,
    166                                          event_ctx, socket_options);
     456                                         event_ctx, socket_options,
     457                                         calling, called);
    167458        return smbcli_sock_connect_recv(c, mem_ctx, result);
    168459}
    169 
    170 
    171 /****************************************************************************
    172  mark the socket as dead
    173 ****************************************************************************/
    174 _PUBLIC_ void smbcli_sock_dead(struct smbcli_socket *sock)
    175 {
    176         talloc_free(sock->event.fde);
    177         sock->event.fde = NULL;
    178         talloc_free(sock->sock);
    179         sock->sock = NULL;
    180 }
    181 
    182 /****************************************************************************
    183  Set socket options on a open connection.
    184 ****************************************************************************/
    185 void smbcli_sock_set_options(struct smbcli_socket *sock, const char *options)
    186 {
    187         socket_set_option(sock->sock, options, NULL);
    188 }
    189 
    190 /****************************************************************************
    191 resolve a hostname and connect
    192 ****************************************************************************/
    193 _PUBLIC_ struct smbcli_socket *smbcli_sock_connect_byname(const char *host, const char **ports,
    194                                                  TALLOC_CTX *mem_ctx,
    195                                                  struct resolve_context *resolve_ctx,
    196                                                  struct tevent_context *event_ctx,
    197                                                  const char *socket_options)
    198 {
    199         int name_type = NBT_NAME_SERVER;
    200         const char *address;
    201         NTSTATUS status;
    202         struct nbt_name nbt_name;
    203         char *name, *p;
    204         TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
    205         struct smbcli_socket *result;
    206 
    207         if (event_ctx == NULL) {
    208                 DEBUG(0, ("Invalid NULL event context passed in as parameter\n"));
    209                 return NULL;
    210         }
    211 
    212         if (tmp_ctx == NULL) {
    213                 DEBUG(0, ("talloc_new failed\n"));
    214                 return NULL;
    215         }
    216 
    217         name = talloc_strdup(tmp_ctx, host);
    218         if (name == NULL) {
    219                 DEBUG(0, ("talloc_strdup failed\n"));
    220                 talloc_free(tmp_ctx);
    221                 return NULL;
    222         }
    223 
    224         /* allow hostnames of the form NAME#xx and do a netbios lookup */
    225         if ((p = strchr(name, '#'))) {
    226                 name_type = strtol(p+1, NULL, 16);
    227                 *p = 0;
    228         }
    229 
    230         make_nbt_name(&nbt_name, host, name_type);
    231        
    232         status = resolve_name(resolve_ctx, &nbt_name, tmp_ctx, &address, event_ctx);
    233         if (!NT_STATUS_IS_OK(status)) {
    234                 talloc_free(tmp_ctx);
    235                 return NULL;
    236         }
    237 
    238         status = smbcli_sock_connect(mem_ctx, address, ports, name, resolve_ctx,
    239                                      event_ctx,
    240                                          socket_options, &result);
    241 
    242         if (!NT_STATUS_IS_OK(status)) {
    243                 DEBUG(9, ("smbcli_sock_connect failed: %s\n",
    244                           nt_errstr(status)));
    245                 talloc_free(tmp_ctx);
    246                 return NULL;
    247         }
    248 
    249         talloc_free(tmp_ctx);
    250 
    251         return result;
    252 }
  • vendor/current/source4/libcli/raw/clitransport.c

    r740 r988  
    2121
    2222#include "includes.h"
     23#include "system/network.h"
     24#include "../lib/async_req/async_sock.h"
     25#include "../lib/util/tevent_ntstatus.h"
    2326#include "libcli/raw/libcliraw.h"
    2427#include "libcli/raw/raw_proto.h"
    2528#include "lib/socket/socket.h"
    26 #include "../lib/util/dlinklist.h"
    2729#include "lib/events/events.h"
    28 #include "lib/stream/packet.h"
    2930#include "librpc/gen_ndr/ndr_nbt.h"
    3031#include "../libcli/nbt/libnbt.h"
    31 
    32 
    33 /*
    34   an event has happened on the socket
    35 */
    36 static void smbcli_transport_event_handler(struct tevent_context *ev,
    37                                            struct tevent_fd *fde,
    38                                            uint16_t flags, void *private_data)
    39 {
    40         struct smbcli_transport *transport = talloc_get_type(private_data,
    41                                                              struct smbcli_transport);
    42         if (flags & EVENT_FD_READ) {
    43                 packet_recv(transport->packet);
    44                 return;
    45         }
    46         if (flags & EVENT_FD_WRITE) {
    47                 packet_queue_run(transport->packet);
    48         }
    49 }
     32#include "../libcli/smb/smbXcli_base.h"
     33#include "../libcli/smb/read_smb.h"
    5034
    5135/*
     
    5741        return 0;
    5842}
    59 
    60 
    61 /*
    62   handle receive errors
    63 */
    64 static void smbcli_transport_error(void *private_data, NTSTATUS status)
    65 {
    66         struct smbcli_transport *transport = talloc_get_type(private_data, struct smbcli_transport);
    67         smbcli_transport_dead(transport, status);
    68 }
    69 
    70 static NTSTATUS smbcli_transport_finish_recv(void *private_data, DATA_BLOB blob);
    7143
    7244/*
     
    7951{
    8052        struct smbcli_transport *transport;
     53        uint32_t smb1_capabilities;
    8154
    8255        transport = talloc_zero(parent_ctx, struct smbcli_transport);
    8356        if (!transport) return NULL;
    8457
    85         if (primary) {
    86                 transport->socket = talloc_steal(transport, sock);
    87         } else {
    88                 transport->socket = talloc_reference(transport, sock);
    89         }
    90         transport->negotiate.protocol = PROTOCOL_NT1;
     58        transport->ev = sock->event.ctx;
    9159        transport->options = *options;
    92         transport->negotiate.max_xmit = transport->options.max_xmit;
    93 
    94         /* setup the stream -> packet parser */
    95         transport->packet = packet_init(transport);
    96         if (transport->packet == NULL) {
    97                 talloc_free(transport);
     60
     61        if (transport->options.max_protocol == PROTOCOL_DEFAULT) {
     62                transport->options.max_protocol = PROTOCOL_NT1;
     63        }
     64
     65        if (transport->options.max_protocol > PROTOCOL_NT1) {
     66                transport->options.max_protocol = PROTOCOL_NT1;
     67        }
     68
     69        TALLOC_FREE(sock->event.fde);
     70        TALLOC_FREE(sock->event.te);
     71
     72        smb1_capabilities = 0;
     73        smb1_capabilities |= CAP_LARGE_FILES;
     74        smb1_capabilities |= CAP_NT_SMBS | CAP_RPC_REMOTE_APIS;
     75        smb1_capabilities |= CAP_LOCK_AND_READ | CAP_NT_FIND;
     76        smb1_capabilities |= CAP_DFS | CAP_W2K_SMBS;
     77        smb1_capabilities |= CAP_LARGE_READX|CAP_LARGE_WRITEX;
     78        smb1_capabilities |= CAP_LWIO;
     79
     80        if (options->ntstatus_support) {
     81                smb1_capabilities |= CAP_STATUS32;
     82        }
     83
     84        if (options->unicode) {
     85                smb1_capabilities |= CAP_UNICODE;
     86        }
     87
     88        if (options->use_spnego) {
     89                smb1_capabilities |= CAP_EXTENDED_SECURITY;
     90        }
     91
     92        if (options->use_level2_oplocks) {
     93                smb1_capabilities |= CAP_LEVEL_II_OPLOCKS;
     94        }
     95
     96        transport->conn = smbXcli_conn_create(transport,
     97                                              sock->sock->fd,
     98                                              sock->hostname,
     99                                              options->signing,
     100                                              smb1_capabilities,
     101                                              NULL, /* client_guid */
     102                                              0); /* smb2_capabilities */
     103        if (transport->conn == NULL) {
     104                TALLOC_FREE(sock);
     105                TALLOC_FREE(transport);
    98106                return NULL;
    99107        }
    100         packet_set_private(transport->packet, transport);
    101         packet_set_socket(transport->packet, transport->socket->sock);
    102         packet_set_callback(transport->packet, smbcli_transport_finish_recv);
    103         packet_set_full_request(transport->packet, packet_full_request_nbt);
    104         packet_set_error_handler(transport->packet, smbcli_transport_error);
    105         packet_set_event_context(transport->packet, transport->socket->event.ctx);
    106         packet_set_nofree(transport->packet);
    107         packet_set_initial_read(transport->packet, 4);
    108 
    109         smbcli_init_signing(transport);
    110 
    111         ZERO_STRUCT(transport->called);
    112 
    113         /* take over event handling from the socket layer - it only
    114            handles events up until we are connected */
    115         talloc_free(transport->socket->event.fde);
    116         transport->socket->event.fde = event_add_fd(transport->socket->event.ctx,
    117                                                     transport->socket->sock,
    118                                                     socket_get_fd(transport->socket->sock),
    119                                                     EVENT_FD_READ,
    120                                                     smbcli_transport_event_handler,
    121                                                     transport);
    122 
    123         packet_set_fde(transport->packet, transport->socket->event.fde);
    124         packet_set_serialise(transport->packet);
     108        sock->sock->fd = -1;
     109        TALLOC_FREE(sock);
     110
    125111        talloc_set_destructor(transport, transport_destructor);
    126112
     
    133119void smbcli_transport_dead(struct smbcli_transport *transport, NTSTATUS status)
    134120{
    135         smbcli_sock_dead(transport->socket);
    136 
    137121        if (NT_STATUS_EQUAL(NT_STATUS_UNSUCCESSFUL, status)) {
    138122                status = NT_STATUS_UNEXPECTED_NETWORK_ERROR;
    139123        }
    140 
    141         /* kill only the first pending receive - this is so that if
    142          that async function frees the connection we don't die trying
    143          to use old memory. The caller has to cope with only one
    144          network error */
    145         if (transport->pending_recv) {
    146                 struct smbcli_request *req = transport->pending_recv;
    147                 req->state = SMBCLI_REQUEST_ERROR;
    148                 req->status = status;
    149                 DLIST_REMOVE(transport->pending_recv, req);
    150                 if (req->async.fn) {
    151                         req->async.fn(req);
    152                 }
    153         }
    154 }
    155 
    156 
    157 /*
    158   send a session request
    159 */
    160 struct smbcli_request *smbcli_transport_connect_send(struct smbcli_transport *transport,
    161                                                      struct nbt_name *calling,
    162                                                      struct nbt_name *called)
    163 {
    164         uint8_t *p;
    165         struct smbcli_request *req;
    166         DATA_BLOB calling_blob, called_blob;
    167         TALLOC_CTX *tmp_ctx = talloc_new(transport);
    168         NTSTATUS status;
    169 
    170         status = nbt_name_dup(transport, called, &transport->called);
    171         if (!NT_STATUS_IS_OK(status)) goto failed;
    172        
    173         status = nbt_name_to_blob(tmp_ctx, &calling_blob, calling);
    174         if (!NT_STATUS_IS_OK(status)) goto failed;
    175 
    176         status = nbt_name_to_blob(tmp_ctx, &called_blob, called);
    177         if (!NT_STATUS_IS_OK(status)) goto failed;
    178 
    179         /* allocate output buffer */
    180         req = smbcli_request_setup_nonsmb(transport,
    181                                           NBT_HDR_SIZE +
    182                                           calling_blob.length + called_blob.length);
    183         if (req == NULL) goto failed;
    184 
    185         /* put in the destination name */
    186         p = req->out.buffer + NBT_HDR_SIZE;
    187         memcpy(p, called_blob.data, called_blob.length);
    188         p += called_blob.length;
    189 
    190         memcpy(p, calling_blob.data, calling_blob.length);
    191         p += calling_blob.length;
    192 
    193         _smb_setlen(req->out.buffer, PTR_DIFF(p, req->out.buffer) - NBT_HDR_SIZE);
    194         SCVAL(req->out.buffer,0,0x81);
    195 
    196         if (!smbcli_request_send(req)) {
    197                 smbcli_request_destroy(req);
    198                 goto failed;
    199         }
    200 
    201         talloc_free(tmp_ctx);
    202         return req;
    203 
    204 failed:
    205         talloc_free(tmp_ctx);
    206         return NULL;
    207 }
    208 
    209 /*
    210   map a session request error to a NTSTATUS
    211  */
    212 static NTSTATUS map_session_refused_error(uint8_t error)
    213 {
    214         switch (error) {
    215         case 0x80:
    216         case 0x81:
    217                 return NT_STATUS_REMOTE_NOT_LISTENING;
    218         case 0x82:
    219                 return NT_STATUS_RESOURCE_NAME_NOT_FOUND;
    220         case 0x83:
    221                 return NT_STATUS_REMOTE_RESOURCES;
    222         }
    223         return NT_STATUS_UNEXPECTED_IO_ERROR;
    224 }
    225 
    226 
    227 /*
    228   finish a smbcli_transport_connect()
    229 */
    230 NTSTATUS smbcli_transport_connect_recv(struct smbcli_request *req)
    231 {
    232         NTSTATUS status;
    233 
    234         if (!smbcli_request_receive(req)) {
    235                 smbcli_request_destroy(req);
    236                 return NT_STATUS_UNEXPECTED_NETWORK_ERROR;
    237         }
    238 
    239         switch (CVAL(req->in.buffer,0)) {
    240         case 0x82:
    241                 status = NT_STATUS_OK;
    242                 break;
    243         case 0x83:
    244                 status = map_session_refused_error(CVAL(req->in.buffer,4));
    245                 break;
    246         case 0x84:
    247                 DEBUG(1,("Warning: session retarget not supported\n"));
    248                 status = NT_STATUS_NOT_SUPPORTED;
    249                 break;
    250         default:
    251                 status = NT_STATUS_UNEXPECTED_IO_ERROR;
    252                 break;
    253         }
    254 
    255         smbcli_request_destroy(req);
    256         return status;
    257 }
    258 
    259 
    260 /*
    261   send a session request (if needed)
    262 */
    263 bool smbcli_transport_connect(struct smbcli_transport *transport,
    264                               struct nbt_name *calling,
    265                               struct nbt_name *called)
    266 {
    267         struct smbcli_request *req;
    268         NTSTATUS status;
    269 
    270         if (transport->socket->port == 445) {
    271                 return true;
    272         }
    273 
    274         req = smbcli_transport_connect_send(transport,
    275                                             calling, called);
    276         status = smbcli_transport_connect_recv(req);
    277         return NT_STATUS_IS_OK(status);
    278 }
    279 
    280 /****************************************************************************
    281 get next mid in sequence
    282 ****************************************************************************/
    283 uint16_t smbcli_transport_next_mid(struct smbcli_transport *transport)
    284 {
    285         uint16_t mid;
    286         struct smbcli_request *req;
    287 
    288         mid = transport->next_mid;
    289 
    290 again:
    291         /* now check to see if this mid is being used by one of the
    292            pending requests. This is quite efficient because the list is
    293            usually very short */
    294 
    295         /* the zero mid is reserved for requests that don't have a mid */
    296         if (mid == 0) mid = 1;
    297 
    298         for (req=transport->pending_recv; req; req=req->next) {
    299                 if (req->mid == mid) {
    300                         mid++;
    301                         goto again;
    302                 }
    303         }
    304 
    305         transport->next_mid = mid+1;
    306         return mid;
     124        if (NT_STATUS_IS_OK(status)) {
     125                status = NT_STATUS_LOCAL_DISCONNECT;
     126        }
     127
     128        smbXcli_conn_disconnect(transport->conn, status);
    307129}
    308130
     
    312134        struct smbcli_transport *transport = talloc_get_type(private_data,
    313135                                                             struct smbcli_transport);
    314         struct timeval next = timeval_add(&t, 0, transport->idle.period);
    315         transport->socket->event.te = event_add_timed(transport->socket->event.ctx,
    316                                                       transport,
    317                                                       next,
    318                                                       idle_handler, transport);
     136        struct timeval next;
     137
    319138        transport->idle.func(transport, transport->idle.private_data);
     139
     140        next = timeval_current_ofs_usec(transport->idle.period);
     141
     142        transport->idle.te = tevent_add_timer(transport->ev,
     143                                              transport,
     144                                              next,
     145                                              idle_handler,
     146                                              transport);
    320147}
    321148
     
    329156                                   void *private_data)
    330157{
     158        TALLOC_FREE(transport->idle.te);
     159
    331160        transport->idle.func = idle_func;
    332161        transport->idle.private_data = private_data;
    333162        transport->idle.period = period;
    334163
    335         if (transport->socket->event.te != NULL) {
    336                 talloc_free(transport->socket->event.te);
    337         }
    338 
    339         transport->socket->event.te = event_add_timed(transport->socket->event.ctx,
    340                                                       transport,
    341                                                       timeval_current_ofs(0, period),
    342                                                       idle_handler, transport);
    343 }
    344 
    345 /*
    346   we have a full request in our receive buffer - match it to a pending request
    347   and process
    348  */
    349 static NTSTATUS smbcli_transport_finish_recv(void *private_data, DATA_BLOB blob)
    350 {
    351         struct smbcli_transport *transport = talloc_get_type(private_data,
    352                                                              struct smbcli_transport);
    353         uint8_t *buffer, *hdr, *vwv;
    354         int len;
    355         uint16_t wct=0, mid = 0, op = 0;
    356         struct smbcli_request *req = NULL;
    357 
    358         buffer = blob.data;
    359         len = blob.length;
    360 
    361         hdr = buffer+NBT_HDR_SIZE;
    362         vwv = hdr + HDR_VWV;
    363 
    364         /* see if it could be an oplock break request */
    365         if (smbcli_handle_oplock_break(transport, len, hdr, vwv)) {
    366                 talloc_free(buffer);
    367                 return NT_STATUS_OK;
    368         }
    369 
    370         /* at this point we need to check for a readbraw reply, as
    371            these can be any length */
    372         if (transport->readbraw_pending) {
    373                 transport->readbraw_pending = 0;
    374 
    375                 /* it must match the first entry in the pending queue
    376                    as the client is not allowed to have outstanding
    377                    readbraw requests */
    378                 req = transport->pending_recv;
    379                 if (!req) goto error;
    380 
    381                 req->in.buffer = buffer;
    382                 talloc_steal(req, buffer);
    383                 req->in.size = len;
    384                 req->in.allocated = req->in.size;
    385                 goto async;
    386         }
    387 
    388         if (len >= MIN_SMB_SIZE) {
    389                 /* extract the mid for matching to pending requests */
    390                 mid = SVAL(hdr, HDR_MID);
    391                 wct = CVAL(hdr, HDR_WCT);
    392                 op  = CVAL(hdr, HDR_COM);
    393         }
    394 
    395         /* match the incoming request against the list of pending requests */
    396         for (req=transport->pending_recv; req; req=req->next) {
    397                 if (req->mid == mid) break;
    398         }
    399 
    400         /* see if it's a ntcancel reply for the current MID */
    401         req = smbcli_handle_ntcancel_reply(req, len, hdr);
    402 
    403         if (!req) {
    404                 DEBUG(1,("Discarding unmatched reply with mid %d op %d\n", mid, op));
    405                 goto error;
    406         }
    407 
    408         /* fill in the 'in' portion of the matching request */
    409         req->in.buffer = buffer;
    410         talloc_steal(req, buffer);
    411         req->in.size = len;
    412         req->in.allocated = req->in.size;
    413 
    414         /* handle NBT session replies */
    415         if (req->in.size >= 4 && req->in.buffer[0] != 0) {
    416                 req->status = NT_STATUS_OK;
    417                 goto async;
    418         }
    419 
    420         /* handle non-SMB replies */
    421         if (req->in.size < NBT_HDR_SIZE + MIN_SMB_SIZE) {
    422                 req->state = SMBCLI_REQUEST_ERROR;
    423                 goto error;
    424         }
    425 
    426         if (req->in.size < NBT_HDR_SIZE + MIN_SMB_SIZE + VWV(wct)) {
    427                 DEBUG(2,("bad reply size for mid %d\n", mid));
    428                 req->status = NT_STATUS_UNSUCCESSFUL;
    429                 req->state = SMBCLI_REQUEST_ERROR;
    430                 goto error;
    431         }
    432 
    433         req->in.hdr = hdr;
    434         req->in.vwv = vwv;
    435         req->in.wct = wct;
    436         if (req->in.size >= NBT_HDR_SIZE + MIN_SMB_SIZE + VWV(wct)) {
    437                 req->in.data = req->in.vwv + VWV(wct) + 2;
    438                 req->in.data_size = SVAL(req->in.vwv, VWV(wct));
    439                 if (req->in.size < NBT_HDR_SIZE + MIN_SMB_SIZE + VWV(wct) + req->in.data_size) {
    440                         DEBUG(3,("bad data size for mid %d\n", mid));
    441                         /* blergh - w2k3 gives a bogus data size values in some
    442                            openX replies */
    443                         req->in.data_size = req->in.size - (NBT_HDR_SIZE + MIN_SMB_SIZE + VWV(wct));
    444                 }
    445         }
    446         req->in.ptr = req->in.data;
    447         req->flags2 = SVAL(req->in.hdr, HDR_FLG2);
    448 
    449         smb_setup_bufinfo(req);
    450 
    451         if (!(req->flags2 & FLAGS2_32_BIT_ERROR_CODES)) {
    452                 int eclass = CVAL(req->in.hdr,HDR_RCLS);
    453                 int code = SVAL(req->in.hdr,HDR_ERR);
    454                 if (eclass == 0 && code == 0) {
    455                         transport->error.e.nt_status = NT_STATUS_OK;
    456                 } else {
    457                         transport->error.e.nt_status = NT_STATUS_DOS(eclass, code);
    458                 }
    459         } else {
    460                 transport->error.e.nt_status = NT_STATUS(IVAL(req->in.hdr, HDR_RCLS));
    461         }
    462 
    463         req->status = transport->error.e.nt_status;
    464         if (NT_STATUS_IS_OK(req->status)) {
    465                 transport->error.etype = ETYPE_NONE;
    466         } else {
    467                 transport->error.etype = ETYPE_SMB;
    468         }
    469 
    470         if (!smbcli_request_check_sign_mac(req)) {
    471                 transport->error.etype = ETYPE_SOCKET;
    472                 transport->error.e.socket_error = SOCKET_READ_BAD_SIG;
    473                 req->state = SMBCLI_REQUEST_ERROR;
    474                 req->status = NT_STATUS_ACCESS_DENIED;
    475                 goto error;
    476         };
    477 
    478 async:
    479         /* if this request has an async handler then call that to
    480            notify that the reply has been received. This might destroy
    481            the request so it must happen last */
    482 
    483         req->state = SMBCLI_REQUEST_DONE;
    484 
    485         if (req->recv_helper.fn) {
    486                 /*
    487                  * let the recv helper decide in
    488                  * what state the request really is
    489                  */
    490                 req->state = req->recv_helper.fn(req);
    491 
    492                 /* if more parts are needed, wait for them */
    493                 if (req->state <= SMBCLI_REQUEST_RECV) {
    494                         return NT_STATUS_OK;
    495                 }
    496         }
    497         DLIST_REMOVE(transport->pending_recv, req);
    498         if (req->async.fn) {
    499                 req->async.fn(req);
    500         }
    501         return NT_STATUS_OK;
    502 
    503 error:
    504         if (req) {
    505                 DLIST_REMOVE(transport->pending_recv, req);
    506                 req->state = SMBCLI_REQUEST_ERROR;
    507                 if (req->async.fn) {
    508                         req->async.fn(req);
    509                 }
    510         } else {
    511                 talloc_free(buffer);
    512         }
    513         return NT_STATUS_OK;
     164        transport->idle.te = tevent_add_timer(transport->ev,
     165                                              transport,
     166                                              timeval_current_ofs_usec(period),
     167                                              idle_handler,
     168                                              transport);
    514169}
    515170
     
    520175_PUBLIC_ bool smbcli_transport_process(struct smbcli_transport *transport)
    521176{
    522         NTSTATUS status;
    523         size_t npending;
    524 
    525         packet_queue_run(transport->packet);
    526         if (transport->socket->sock == NULL) {
     177        struct tevent_req *subreq = NULL;
     178        int ret;
     179
     180        if (!smbXcli_conn_is_connected(transport->conn)) {
    527181                return false;
    528182        }
    529183
    530         status = socket_pending(transport->socket->sock, &npending);
    531         if (NT_STATUS_IS_OK(status) && npending > 0) {
    532                 packet_recv(transport->packet);
    533         }
    534         if (transport->socket->sock == NULL) {
     184        if (!smbXcli_conn_has_async_calls(transport->conn)) {
     185                return true;
     186        }
     187
     188        /*
     189         * do not block for more than 500 micro seconds
     190         */
     191        subreq = tevent_wakeup_send(transport,
     192                                    transport->ev,
     193                                    timeval_current_ofs_usec(500));
     194        if (subreq == NULL) {
    535195                return false;
    536196        }
     197
     198        ret = tevent_loop_once(transport->ev);
     199        if (ret != 0) {
     200                return false;
     201        }
     202
     203        TALLOC_FREE(subreq);
     204
     205        if (!smbXcli_conn_is_connected(transport->conn)) {
     206                return false;
     207        }
     208
    537209        return true;
    538210}
    539211
    540 /*
    541   handle timeouts of individual smb requests
    542 */
    543 static void smbcli_timeout_handler(struct tevent_context *ev, struct tevent_timer *te,
    544                                    struct timeval t, void *private_data)
    545 {
    546         struct smbcli_request *req = talloc_get_type(private_data, struct smbcli_request);
    547 
    548         if (req->state == SMBCLI_REQUEST_RECV) {
    549                 DLIST_REMOVE(req->transport->pending_recv, req);
    550         }
    551         req->status = NT_STATUS_IO_TIMEOUT;
    552         req->state = SMBCLI_REQUEST_ERROR;
    553         if (req->async.fn) {
    554                 req->async.fn(req);
    555         }
    556 }
    557 
    558 
    559 /*
    560   destroy a request
    561 */
    562 static int smbcli_request_destructor(struct smbcli_request *req)
    563 {
    564         if (req->state == SMBCLI_REQUEST_RECV) {
    565                 DLIST_REMOVE(req->transport->pending_recv, req);
    566         }
    567         return 0;
    568 }
    569 
     212static void smbcli_transport_break_handler(struct tevent_req *subreq);
     213static void smbcli_request_done(struct tevent_req *subreq);
     214
     215struct tevent_req *smbcli_transport_setup_subreq(struct smbcli_request *req)
     216{
     217        struct smbcli_transport *transport = req->transport;
     218        uint8_t smb_command;
     219        uint8_t additional_flags;
     220        uint8_t clear_flags;
     221        uint16_t additional_flags2;
     222        uint16_t clear_flags2;
     223        uint32_t pid;
     224        struct smbXcli_tcon *tcon = NULL;
     225        struct smbXcli_session *session = NULL;
     226        uint32_t timeout_msec = transport->options.request_timeout * 1000;
     227        struct iovec *bytes_iov = NULL;
     228        struct tevent_req *subreq = NULL;
     229
     230        smb_command = SVAL(req->out.hdr, HDR_COM);
     231        additional_flags = CVAL(req->out.hdr, HDR_FLG);
     232        additional_flags2 = SVAL(req->out.hdr, HDR_FLG2);
     233        pid  = SVAL(req->out.hdr, HDR_PID);
     234        pid |= SVAL(req->out.hdr, HDR_PIDHIGH)<<16;
     235
     236        clear_flags = ~additional_flags;
     237        clear_flags2 = ~additional_flags2;
     238
     239        if (req->session) {
     240                session = req->session->smbXcli;
     241        }
     242
     243        if (req->tree) {
     244                tcon = req->tree->smbXcli;
     245        }
     246
     247        bytes_iov = talloc(req, struct iovec);
     248        if (bytes_iov == NULL) {
     249                return NULL;
     250        }
     251        bytes_iov->iov_base = (void *)req->out.data;
     252        bytes_iov->iov_len = req->out.data_size;
     253
     254        subreq = smb1cli_req_create(req,
     255                                    transport->ev,
     256                                    transport->conn,
     257                                    smb_command,
     258                                    additional_flags,
     259                                    clear_flags,
     260                                    additional_flags2,
     261                                    clear_flags2,
     262                                    timeout_msec,
     263                                    pid,
     264                                    tcon,
     265                                    session,
     266                                    req->out.wct,
     267                                    (uint16_t *)req->out.vwv,
     268                                    1, bytes_iov);
     269        if (subreq == NULL) {
     270                return NULL;
     271        }
     272
     273        ZERO_STRUCT(req->out);
     274
     275        return subreq;
     276}
    570277
    571278/*
     
    574281void smbcli_transport_send(struct smbcli_request *req)
    575282{
    576         DATA_BLOB blob;
     283        struct smbcli_transport *transport = req->transport;
    577284        NTSTATUS status;
    578 
    579         /* check if the transport is dead */
    580         if (req->transport->socket->sock == NULL) {
     285        bool need_pending_break = false;
     286        struct tevent_req *subreq = NULL;
     287        size_t i;
     288        size_t num_subreqs = 0;
     289
     290        if (transport->oplock.handler) {
     291                need_pending_break = true;
     292        }
     293
     294        if (transport->break_subreq) {
     295                need_pending_break = false;
     296        }
     297
     298        if (need_pending_break) {
     299                subreq = smb1cli_req_create(transport,
     300                                            transport->ev,
     301                                            transport->conn,
     302                                            0, /* smb_command */
     303                                            0, /* additional_flags */
     304                                            0, /* clear_flags */
     305                                            0, /* additional_flags2 */
     306                                            0, /* clear_flags2 */
     307                                            0, /* timeout_msec */
     308                                            0, /* pid */
     309                                            NULL, /* tcon */
     310                                            NULL, /* session */
     311                                            0, /* wct */
     312                                            NULL, /* vwv */
     313                                            0, /* iov_count */
     314                                            NULL); /* bytes_iov */
     315                if (subreq != NULL) {
     316                        smb1cli_req_set_mid(subreq, 0xFFFF);
     317                        smbXcli_req_set_pending(subreq);
     318                        tevent_req_set_callback(subreq,
     319                                                smbcli_transport_break_handler,
     320                                                transport);
     321                        transport->break_subreq = subreq;
     322                        subreq = NULL;
     323                }
     324        }
     325
     326        subreq = smbcli_transport_setup_subreq(req);
     327        if (subreq == NULL) {
    581328                req->state = SMBCLI_REQUEST_ERROR;
    582                 req->status = NT_STATUS_NET_WRITE_FAULT;
     329                req->status = NT_STATUS_NO_MEMORY;
    583330                return;
    584331        }
    585332
    586         blob = data_blob_const(req->out.buffer, req->out.size);
    587         status = packet_send(req->transport->packet, blob);
     333        for (i = 0; i < ARRAY_SIZE(req->subreqs); i++) {
     334                if (req->subreqs[i] == NULL) {
     335                        req->subreqs[i] = subreq;
     336                        subreq = NULL;
     337                }
     338                if (req->subreqs[i] == NULL) {
     339                        break;
     340                }
     341
     342                if (!tevent_req_is_in_progress(req->subreqs[i])) {
     343                        req->state = SMBCLI_REQUEST_ERROR;
     344                        req->status = NT_STATUS_INTERNAL_ERROR;
     345                        return;
     346                }
     347        }
     348        num_subreqs = i;
     349
     350        req->state = SMBCLI_REQUEST_RECV;
     351        tevent_req_set_callback(req->subreqs[0], smbcli_request_done, req);
     352
     353        status = smb1cli_req_chain_submit(req->subreqs, num_subreqs);
    588354        if (!NT_STATUS_IS_OK(status)) {
     355                req->status = status;
    589356                req->state = SMBCLI_REQUEST_ERROR;
    590                 req->status = status;
     357                smbXcli_conn_disconnect(transport->conn, status);
     358        }
     359}
     360
     361static void smbcli_request_done(struct tevent_req *subreq)
     362{
     363        struct smbcli_request *req =
     364                tevent_req_callback_data(subreq,
     365                struct smbcli_request);
     366        struct smbcli_transport *transport = req->transport;
     367        ssize_t len;
     368        size_t i;
     369        uint8_t *hdr = NULL;
     370        uint8_t wct = 0;
     371        uint16_t *vwv = NULL;
     372        uint32_t num_bytes = 0;
     373        uint8_t *bytes = NULL;
     374        struct iovec *recv_iov = NULL;
     375        uint8_t *inbuf = NULL;
     376
     377        req->status = smb1cli_req_recv(req->subreqs[0], req,
     378                                       &recv_iov,
     379                                       &hdr,
     380                                       &wct,
     381                                       &vwv,
     382                                       NULL, /* pvwv_offset */
     383                                       &num_bytes,
     384                                       &bytes,
     385                                       NULL, /* pbytes_offset */
     386                                       &inbuf,
     387                                       NULL, 0); /* expected */
     388        TALLOC_FREE(req->subreqs[0]);
     389        if (!NT_STATUS_IS_OK(req->status)) {
     390                if (recv_iov == NULL) {
     391                        req->state = SMBCLI_REQUEST_ERROR;
     392                        transport->error.e.nt_status = req->status;
     393                        transport->error.etype = ETYPE_SOCKET;
     394                        if (req->async.fn) {
     395                                req->async.fn(req);
     396                        }
     397                        return;
     398                }
     399        }
     400
     401        /*
     402         * For SMBreadBraw hdr is NULL
     403         */
     404        len = recv_iov[0].iov_len;
     405        for (i=1; hdr != NULL && i < 3; i++) {
     406                uint8_t *p = recv_iov[i-1].iov_base;
     407                uint8_t *c1 = recv_iov[i].iov_base;
     408                uint8_t *c2 = p + recv_iov[i-1].iov_len;
     409
     410                len += recv_iov[i].iov_len;
     411
     412                c2 += i;
     413                len += i;
     414
     415                if (recv_iov[i].iov_len == 0) {
     416                        continue;
     417                }
     418
     419                if (c1 != c2) {
     420                        req->state = SMBCLI_REQUEST_ERROR;
     421                        req->status = NT_STATUS_INTERNAL_ERROR;
     422                        transport->error.e.nt_status = req->status;
     423                        transport->error.etype = ETYPE_SMB;
     424                        if (req->async.fn) {
     425                                req->async.fn(req);
     426                        }
     427                        return;
     428                }
     429        }
     430
     431        /* fill in the 'in' portion of the matching request */
     432        req->in.buffer = inbuf;
     433        req->in.size = NBT_HDR_SIZE + len;
     434        req->in.allocated = req->in.size;
     435
     436        req->in.hdr = hdr;
     437        req->in.vwv = (uint8_t *)vwv;
     438        req->in.wct = wct;
     439        req->in.data = bytes;
     440        req->in.data_size = num_bytes;
     441        req->in.ptr = req->in.data;
     442        if (hdr != NULL) {
     443                req->flags2 = SVAL(req->in.hdr, HDR_FLG2);
     444        }
     445
     446        smb_setup_bufinfo(req);
     447
     448        transport->error.e.nt_status = req->status;
     449        if (NT_STATUS_IS_OK(req->status)) {
     450                transport->error.etype = ETYPE_NONE;
     451        } else {
     452                transport->error.etype = ETYPE_SMB;
     453        }
     454
     455        req->state = SMBCLI_REQUEST_DONE;
     456        if (req->async.fn) {
     457                req->async.fn(req);
     458        }
     459}
     460
     461static void smbcli_transport_break_handler(struct tevent_req *subreq)
     462{
     463        struct smbcli_transport *transport =
     464                tevent_req_callback_data(subreq,
     465                struct smbcli_transport);
     466        NTSTATUS status;
     467        struct iovec *recv_iov = NULL;
     468        uint8_t *hdr = NULL;
     469        uint16_t *vwv = NULL;
     470        const struct smb1cli_req_expected_response expected[] = {
     471        {
     472                .status = NT_STATUS_OK,
     473                .wct = 8,
     474        }
     475        };
     476        uint16_t tid;
     477        uint16_t fnum;
     478        uint8_t level;
     479
     480        transport->break_subreq = NULL;
     481
     482        status = smb1cli_req_recv(subreq, transport,
     483                                  &recv_iov,
     484                                  &hdr,
     485                                  NULL, /* pwct */
     486                                  &vwv,
     487                                  NULL, /* pvwv_offset */
     488                                  NULL, /* pnum_bytes */
     489                                  NULL, /* pbytes */
     490                                  NULL, /* pbytes_offset */
     491                                  NULL, /* pinbuf */
     492                                  expected,
     493                                  ARRAY_SIZE(expected));
     494        TALLOC_FREE(subreq);
     495        if (!NT_STATUS_IS_OK(status)) {
     496                TALLOC_FREE(recv_iov);
     497                smbcli_transport_dead(transport, status);
    591498                return;
    592499        }
    593500
    594         packet_queue_run(req->transport->packet);
    595         if (req->transport->socket->sock == NULL) {
    596                 req->state = SMBCLI_REQUEST_ERROR;
    597                 req->status = NT_STATUS_NET_WRITE_FAULT;
    598                 return;
    599         }
    600 
    601         if (req->one_way_request) {
    602                 req->state = SMBCLI_REQUEST_DONE;
    603                 smbcli_request_destroy(req);
    604                 return;
    605         }
    606 
    607         req->state = SMBCLI_REQUEST_RECV;
    608         DLIST_ADD(req->transport->pending_recv, req);
    609 
    610         /* add a timeout */
    611         if (req->transport->options.request_timeout) {
    612                 event_add_timed(req->transport->socket->event.ctx, req,
    613                                 timeval_current_ofs(req->transport->options.request_timeout, 0),
    614                                 smbcli_timeout_handler, req);
    615         }
    616 
    617         talloc_set_destructor(req, smbcli_request_destructor);
     501        /*
     502         * Setup the subreq to handle the
     503         * next incoming SMB2 Break.
     504         */
     505        subreq = smb1cli_req_create(transport,
     506                                    transport->ev,
     507                                    transport->conn,
     508                                    0, /* smb_command */
     509                                    0, /* additional_flags */
     510                                    0, /* clear_flags */
     511                                    0, /* additional_flags2 */
     512                                    0, /* clear_flags2 */
     513                                    0, /* timeout_msec */
     514                                    0, /* pid */
     515                                    NULL, /* tcon */
     516                                    NULL, /* session */
     517                                    0, /* wct */
     518                                    NULL, /* vwv */
     519                                    0, /* iov_count */
     520                                    NULL); /* bytes_iov */
     521        if (subreq != NULL) {
     522                smb1cli_req_set_mid(subreq, 0xFFFF);
     523                smbXcli_req_set_pending(subreq);
     524                tevent_req_set_callback(subreq,
     525                                        smbcli_transport_break_handler,
     526                                        transport);
     527                transport->break_subreq = subreq;
     528        }
     529
     530        tid = SVAL(hdr, HDR_TID);
     531        fnum = SVAL(vwv+2, 0);
     532        level = CVAL(vwv+3, 1);
     533
     534        TALLOC_FREE(recv_iov);
     535
     536        if (transport->oplock.handler) {
     537                transport->oplock.handler(transport, tid, fnum, level,
     538                                          transport->oplock.private_data);
     539        } else {
     540                DEBUG(5,("Got SMB oplock break with no handler\n"));
     541        }
     542
    618543}
    619544
  • vendor/current/source4/libcli/raw/clitree.c

    r740 r988  
    2525#include "libcli/raw/raw_proto.h"
    2626#include "libcli/smb_composite/smb_composite.h"
     27#include "../libcli/smb/smbXcli_base.h"
    2728
    2829#define SETUP_REQUEST_TREE(cmd, wct, buflen) do { \
     
    5051        }
    5152
     53        tree->smbXcli = smbXcli_tcon_create(tree);
     54        if (tree->smbXcli == NULL) {
     55                talloc_free(tree);
     56                return NULL;
     57        }
    5258
    5359        return tree;
     
    116122                ZERO_STRUCT(parms->tconx.out);
    117123                parms->tconx.out.tid = SVAL(req->in.hdr, HDR_TID);
    118                 if (req->in.wct >= 4) {
    119                         parms->tconx.out.options = SVAL(req->in.vwv, VWV(3));
     124                if (req->in.wct >= 3) {
     125                        parms->tconx.out.options = SVAL(req->in.vwv, VWV(2));
     126                }
     127                if (req->in.wct >= 7) {
     128                        parms->tconx.out.max_access = IVAL(req->in.vwv, VWV(3));
     129                        parms->tconx.out.guest_max_access = IVAL(req->in.vwv, VWV(5));
    120130                }
    121131
     
    159169        if (!tree) return NT_STATUS_OK;
    160170        req = smbcli_request_setup(tree, SMBtdis, 0, 0);
     171        if (req == NULL) {
     172                return NT_STATUS_NO_MEMORY;
     173        }
    161174
    162175        if (smbcli_request_send(req)) {
  • vendor/current/source4/libcli/raw/interfaces.h

    r740 r988  
    2323#define __LIBCLI_RAW_INTERFACES_H__
    2424
    25 #include "libcli/raw/smb.h"
     25#include "source4/libcli/raw/smb.h"
    2626#include "../libcli/smb/smb_common.h"
    2727#include "librpc/gen_ndr/misc.h" /* for struct GUID */
     28#include "librpc/gen_ndr/smb2_lease_struct.h"
    2829
    2930/* this structure is just a wrapper for a string, the only reason we
     
    5556};
    5657
    57 /*
    58   SMB2 lease structure (per MS-SMB2 2.2.13)
    59 */
    60 struct smb2_lease_key {
    61         uint64_t data[2];
    62 };
    63 
    64 struct smb2_lease {
    65         struct smb2_lease_key lease_key;
    66         uint32_t lease_state;
    67         uint32_t lease_flags; /* should be 0 */
    68         uint64_t lease_duration; /* should be 0 */
    69 };
    70 
    7158struct smb2_lease_break {
    7259        struct smb2_lease current_lease;
     60        uint16_t new_epoch; /* only for v2 leases */
    7361        uint32_t break_flags;
    7462        uint32_t new_lease_state;
     
    284272                struct {
    285273                        uint16_t options;
     274                        uint32_t max_access;
     275                        uint32_t guest_max_access;
    286276                        char *dev_type;
    287277                        char *fs_type;
     
    925915        RAW_SFILEINFO_UNIX_BASIC              = SMB_SFILEINFO_UNIX_BASIC,
    926916        RAW_SFILEINFO_UNIX_INFO2              = SMB_SFILEINFO_UNIX_INFO2,
    927         RAW_SFILEINFO_UNIX_LINK               = SMB_SFILEINFO_UNIX_LINK,
    928         RAW_SFILEINFO_UNIX_HLINK              = SMB_SFILEINFO_UNIX_HLINK,
     917        RAW_SFILEINFO_UNIX_LINK               = SMB_SET_FILE_UNIX_LINK,
     918        RAW_SFILEINFO_UNIX_HLINK              = SMB_SET_FILE_UNIX_HLINK,
    929919        RAW_SFILEINFO_BASIC_INFORMATION       = SMB_SFILEINFO_BASIC_INFORMATION,
    930920        RAW_SFILEINFO_RENAME_INFORMATION      = SMB_SFILEINFO_RENAME_INFORMATION,
     
    11411131        } unix_link, unix_hlink;
    11421132
    1143         /* RAW_FILEINFO_SET_SEC_DESC */
     1133        /* RAW_SFILEINFO_SEC_DESC */
    11441134        struct {
    11451135                enum smb_setfileinfo_level level;
     
    11781168                   RAW_QFS_QUOTA_INFORMATION              = SMB_QFS_QUOTA_INFORMATION,
    11791169                   RAW_QFS_FULL_SIZE_INFORMATION          = SMB_QFS_FULL_SIZE_INFORMATION,
    1180                    RAW_QFS_OBJECTID_INFORMATION           = SMB_QFS_OBJECTID_INFORMATION};
     1170                   RAW_QFS_OBJECTID_INFORMATION           = SMB_QFS_OBJECTID_INFORMATION,
     1171                   RAW_QFS_SECTOR_SIZE_INFORMATION        = SMB_QFS_SECTOR_SIZE_INFORMATION,
     1172};
    11811173
    11821174
     
    13421334                } out;
    13431335        } objectid_information;
    1344 };
    1345 
    1346 
     1336
     1337        /* trans2 RAW_QFS_SECTOR_SIZE_INFORMATION interface */
     1338        struct {
     1339                enum smb_fsinfo_level level;
     1340                struct smb2_handle handle; /* only for smb2 */
     1341
     1342                struct {
     1343                        uint32_t logical_bytes_per_sector;
     1344                        uint32_t phys_bytes_per_sector_atomic;
     1345                        uint32_t phys_bytes_per_sector_perf;
     1346                        uint32_t fs_effective_phys_bytes_per_sector_atomic;
     1347                        uint32_t flags;
     1348                        uint32_t byte_off_sector_align;
     1349                        uint32_t byte_off_partition_align;
     1350                } out;
     1351        } sector_size_info;
     1352};
     1353
     1354
     1355enum smb_setfsinfo_level {
     1356                RAW_SETFS_UNIX_INFO                      = SMB_SET_CIFS_UNIX_INFO};
     1357
     1358union smb_setfsinfo {
     1359        /* generic interface */
     1360        struct {
     1361                enum smb_setfsinfo_level level;
     1362        } generic;
     1363
     1364        /* TRANS2 RAW_QFS_UNIX_INFO interface */
     1365        struct {
     1366                enum smb_setfsinfo_level level;
     1367
     1368                struct {
     1369                        uint16_t major_version;
     1370                        uint16_t minor_version;
     1371                        uint64_t capability;
     1372                } in;
     1373        } unix_info;
     1374};
    13471375
    13481376enum smb_open_level {
     
    17101738                        bool   durable_open;
    17111739                        struct smb2_handle *durable_handle;
     1740
     1741                        /* data for durable handle v2 */
     1742                        bool durable_open_v2;
     1743                        struct GUID create_guid;
     1744                        bool persistent_open;
     1745                        uint32_t timeout;
     1746                        struct smb2_handle *durable_handle_v2;
     1747
    17121748                        bool   query_maximal_access;
    17131749                        NTTIME timewarp;
    17141750                        bool   query_on_disk_id;
    17151751                        struct smb2_lease *lease_request;
    1716                        
     1752                        struct smb2_lease *lease_request_v2;
     1753
     1754                        struct GUID *app_instance_id;
     1755
    17171756                        /* and any additional blobs the caller wants */
    17181757                        struct smb2_create_blobs blobs;
     
    17421781                        uint8_t on_disk_id[32];
    17431782                        struct smb2_lease lease_response;
     1783                        struct smb2_lease lease_response_v2;
     1784                        bool durable_open;
     1785
     1786                        /* durable handle v2 */
     1787                        bool durable_open_v2;
     1788                        bool persistent_open;
     1789                        uint32_t timeout;
    17441790
    17451791                        /* tagged blobs in the reply */
     
    17831829                        uint16_t compaction_mode;
    17841830                        uint32_t nread;
     1831                        uint16_t flags2;
     1832                        uint16_t data_offset;
    17851833                } out;
    17861834        } readx, generic;
     
    27112759                uint32_t  ea_size;
    27122760                uint64_t file_id;
     2761                uint8_t short_name_buf[24];
    27132762                struct smb_wire_string short_name;
    27142763                struct smb_wire_string name;
  • vendor/current/source4/libcli/raw/libcliraw.h

    r740 r988  
    2323#define __LIBCLI_RAW_H__
    2424
     25#include "../libcli/smb/smb_common.h"
    2526#include "libcli/raw/request.h"
    2627#include "librpc/gen_ndr/nbt.h"
     28#include "libcli/raw/interfaces.h"
    2729
    2830struct smbcli_tree;  /* forward declare */
     
    5254
    5355        uint8_t sec_mode;               /* security mode returned by negprot */
    54         uint8_t key_len;
    55         DATA_BLOB server_guid;      /* server_guid */
    5656        DATA_BLOB secblob;      /* cryptkey or negTokenInit blob */
    5757        uint32_t sesskey;
    58        
    59         struct smb_signing_context sign_info;
    6058
    6159        /* capabilities that the server reported */
     
    6462        int server_zone;
    6563        time_t server_time;
     64
    6665        unsigned int readbraw_supported:1;
    6766        unsigned int writebraw_supported:1;
    6867        unsigned int lockread_supported:1;
    69 
    70         char *server_domain;
    7168};
    7269       
     
    9996        unsigned int unicode:1;
    10097        unsigned int ntstatus_support:1;
     98        int min_protocol;
    10199        int max_protocol;
    102100        uint32_t max_xmit;
    103101        uint16_t max_mux;
    104102        int request_timeout;
    105         enum smb_signing_state signing;
     103        enum smb_signing_setting signing;
     104        uint32_t smb2_capabilities;
     105        struct GUID client_guid;
    106106};
    107107
    108108/* this is the context for the client transport layer */
    109109struct smbcli_transport {
    110         /* socket level info */
    111         struct smbcli_socket *socket;
    112 
    113         /* the next mid to be allocated - needed for signing and
    114            request matching */
    115         uint16_t next_mid;
    116        
     110        struct tevent_context *ev; /* TODO: remove this !!! */
     111        struct smbXcli_conn *conn;
     112
    117113        /* negotiated protocol information */
    118114        struct smbcli_negotiate negotiate;
     
    121117        struct smbcli_options options;
    122118
    123         /* is a readbraw pending? we need to handle that case
    124            specially on receiving packets */
    125         unsigned int readbraw_pending:1;
    126        
    127119        /* an idle function - if this is defined then it will be
    128120           called once every period microseconds while we are waiting
     
    132124                void *private_data;
    133125                unsigned int period;
     126                struct tevent_timer *te;
    134127        } idle;
    135128
     
    155148                void *private_data;
    156149        } oplock;
    157 
    158         /* a list of async requests that are pending for receive on this connection */
    159         struct smbcli_request *pending_recv;
    160 
    161         /* remember the called name - some sub-protocols require us to
    162            know the server name */
    163         struct nbt_name called;
    164 
    165         /* context of the stream -> packet parser */
    166         struct packet_context *packet;
     150        struct tevent_req *break_subreq;
    167151};
    168152
     
    176160        /* after a session setup the server provides us with
    177161           a vuid identifying the security context */
     162        struct smbXcli_session *smbXcli;
    178163        uint16_t vuid;
    179164
     
    184169           the user to control these for torture testing */
    185170        uint16_t flags2;
    186 
    187         DATA_BLOB user_session_key;
    188171
    189172        /* the spnego context if we use extented security */
     
    207190        struct smbcli_session *session;
    208191
     192        struct smbXcli_tcon *smbXcli;
    209193        uint16_t tid;                   /* tree id, aka cnum */
    210194        char *device;
     
    225209 * This will allow requests to be multi-threaded. */
    226210struct smbcli_request {
    227         /* allow a request to be part of a list of requests */
    228         struct smbcli_request *next, *prev;
     211        /* smbXcli_req */
     212        struct tevent_req *subreqs[2];
    229213
    230214        /* each request is in one of 4 possible states */
     
    237221        struct smbcli_tree *tree;
    238222
    239         /* a receive helper, smbcli_transport_finish_recv will not call
    240            req->async.fn callback handler unless the recv_helper returns
    241            a value > SMBCLI_REQUEST_RECV. */
    242         struct {
    243                 enum smbcli_request_state (*fn)(struct smbcli_request *);
    244                 void *private_data;
    245         } recv_helper;
    246 
    247223        /* the flags2 from the SMB request, in raw form (host byte
    248224           order). Used to parse strings */
     
    252228           or code detecting error. */
    253229        NTSTATUS status;
    254        
    255         /* the sequence number of this packet - used for signing */
    256         unsigned int seq_num;
    257 
    258         /* list of ntcancel request for this requests */
    259         struct smbcli_request *ntcancel;
    260 
    261         /* set if this is a one-way request, meaning we are not
    262            expecting a reply from the server. */
    263         unsigned int one_way_request:1;
    264 
    265         /* set this when the request should only increment the signing
    266            counter by one */
    267         unsigned int sign_single_increment:1;
    268230
    269231        /* the caller wants to do the signing check */
     
    273235        bool do_not_free;
    274236
    275         /* the mid of this packet - used to match replies */
    276         uint16_t mid;
    277 
    278237        struct smb_request_buffer in;
    279238        struct smb_request_buffer out;
     239
     240        struct smb_trans2 trans2;
     241        struct smb_nttrans nttrans;
    280242
    281243        /* information on what to do with a reply when it is received
     
    304266      goto failed; \
    305267}
    306 
    307 #include "libcli/raw/interfaces.h"
    308268
    309269NTSTATUS smb_raw_read_recv(struct smbcli_request *req, union smb_read *parms);
     
    316276NTSTATUS smbcli_request_destroy(struct smbcli_request *req);
    317277struct smbcli_request *smb_raw_write_send(struct smbcli_tree *tree, union smb_write *parms);
     278NTSTATUS smb_raw_write_recv(struct smbcli_request *req, union smb_write *parms);
    318279struct smbcli_request *smb_raw_close_send(struct smbcli_tree *tree, union smb_close *parms);
    319280NTSTATUS smb_raw_open_recv(struct smbcli_request *req, TALLOC_CTX *mem_ctx, union smb_open *parms);
     
    323284const char *smbcli_errstr(struct smbcli_tree *tree);
    324285NTSTATUS smb_raw_fsinfo(struct smbcli_tree *tree, TALLOC_CTX *mem_ctx, union smb_fsinfo *fsinfo);
     286NTSTATUS smb_raw_setfsinfo(struct smbcli_tree *tree, TALLOC_CTX *mem_ctx, union smb_setfsinfo *set_fsinfo);
    325287NTSTATUS smb_raw_pathinfo(struct smbcli_tree *tree, TALLOC_CTX *mem_ctx, union smb_fileinfo *parms);
    326288NTSTATUS smb_raw_shadow_data(struct smbcli_tree *tree, TALLOC_CTX *mem_ctx, struct smb_shadow_copy *info);
     
    376338                       struct smb_trans2 *parms);
    377339
    378 struct smbcli_socket *smbcli_sock_connect_byname(const char *host, const char **ports,
    379                                                  TALLOC_CTX *mem_ctx,
    380                                                  struct resolve_context *resolve_ctx,
    381                                                  struct tevent_context *event_ctx,
    382                                                  const char *socket_options);
    383 void smbcli_sock_dead(struct smbcli_socket *sock);
    384 
    385340#endif /* __LIBCLI_RAW__H__ */
  • vendor/current/source4/libcli/raw/raweas.c

    r740 r988  
    244244                }
    245245
     246                if (ofs + next_ofs < ofs) {
     247                        return NT_STATUS_INVALID_PARAMETER;
     248                }
     249
    246250                ofs += next_ofs;
    247 
    248                 if (ofs+4 > blob->length) {
     251                if (ofs+4 > blob->length || ofs+4 < ofs) {
    249252                        return NT_STATUS_INVALID_PARAMETER;
    250253                }
  • vendor/current/source4/libcli/raw/rawfile.c

    r740 r988  
    2929        if (!req) return NULL; \
    3030} while (0)
    31 
    32 /**
    33  Return a string representing a CIFS attribute for a file.
    34 **/
    35 char *attrib_string(TALLOC_CTX *mem_ctx, uint32_t attrib)
    36 {
    37         int i, len;
    38         const struct {
    39                 char c;
    40                 uint16_t attr;
    41         } attr_strs[] = {
    42                 {'V', FILE_ATTRIBUTE_VOLUME},
    43                 {'D', FILE_ATTRIBUTE_DIRECTORY},
    44                 {'A', FILE_ATTRIBUTE_ARCHIVE},
    45                 {'H', FILE_ATTRIBUTE_HIDDEN},
    46                 {'S', FILE_ATTRIBUTE_SYSTEM},
    47                 {'N', FILE_ATTRIBUTE_NORMAL},
    48                 {'R', FILE_ATTRIBUTE_READONLY},
    49                 {'d', FILE_ATTRIBUTE_DEVICE},
    50                 {'t', FILE_ATTRIBUTE_TEMPORARY},
    51                 {'s', FILE_ATTRIBUTE_SPARSE},
    52                 {'r', FILE_ATTRIBUTE_REPARSE_POINT},
    53                 {'c', FILE_ATTRIBUTE_COMPRESSED},
    54                 {'o', FILE_ATTRIBUTE_OFFLINE},
    55                 {'n', FILE_ATTRIBUTE_NONINDEXED},
    56                 {'e', FILE_ATTRIBUTE_ENCRYPTED}
    57         };
    58         char *ret;
    59 
    60         ret = talloc_array(mem_ctx, char, ARRAY_SIZE(attr_strs)+1);
    61         if (!ret) {
    62                 return NULL;
    63         }
    64 
    65         for (len=i=0; i<ARRAY_SIZE(attr_strs); i++) {
    66                 if (attrib & attr_strs[i].attr) {
    67                         ret[len++] = attr_strs[i].c;
    68                 }
    69         }
    70 
    71         ret[len] = 0;
    72 
    73         talloc_set_name_const(ret, ret);
    74 
    75         return ret;
    76 }
    7731
    7832/****************************************************************************
     
    951905        }
    952906        case RAW_LOCK_SMB2:
     907        case RAW_LOCK_SMB2_BREAK:
    953908                return NULL;
    954909        }
     
    979934        struct smbcli_request *req;
    980935
    981         SETUP_REQUEST(SMBchkpth, 0, 0);
     936        SETUP_REQUEST(SMBcheckpath, 0, 0);
    982937
    983938        smbcli_req_append_ascii4(req, parms->chkpath.in.path, STR_TERMINATE);
  • vendor/current/source4/libcli/raw/rawfileinfo.c

    r740 r988  
    5252                bool ret;
    5353                void *vstr;
     54                size_t converted_size = 0;
     55
    5456                io->streams =
    5557                        talloc_realloc(mem_ctx, io->streams, struct stream_struct, n+1);
     
    6567                ret = convert_string_talloc(io->streams,
    6668                                             CH_UTF16, CH_UNIX,
    67                                              blob.data+ofs+24, nlen, &vstr, NULL, false);
     69                                             blob.data+ofs+24, nlen, &vstr, &converted_size);
    6870                if (!ret) {
    6971                        return NT_STATUS_ILLEGAL_CHARACTER;
  • vendor/current/source4/libcli/raw/rawfsinfo.c

    r740 r988  
    3434
    3535        req = smbcli_request_setup(tree, SMBdskattr, 0, 0);
     36        if (req == NULL) {
     37                return NULL;
     38        }
    3639
    3740        if (!smbcli_request_send(req)) {
     
    224227                }
    225228                break;
     229
     230        case RAW_QFS_SECTOR_SIZE_INFORMATION:
     231                QFS_CHECK_SIZE(28);
     232                fsinfo->sector_size_info.out.logical_bytes_per_sector
     233                                                        = IVAL(blob.data,  0);
     234                fsinfo->sector_size_info.out.phys_bytes_per_sector_atomic
     235                                                        = IVAL(blob.data,  4);
     236                fsinfo->sector_size_info.out.phys_bytes_per_sector_perf
     237                                                        = IVAL(blob.data,  8);
     238                fsinfo->sector_size_info.out.fs_effective_phys_bytes_per_sector_atomic
     239                                                        = IVAL(blob.data, 12);
     240                fsinfo->sector_size_info.out.flags      = IVAL(blob.data, 16);
     241                fsinfo->sector_size_info.out.byte_off_sector_align
     242                                                        = IVAL(blob.data, 20);
     243                fsinfo->sector_size_info.out.byte_off_partition_align
     244                                                        = IVAL(blob.data, 24);
     245                break;
    226246        }
    227247               
     
    317337                return smb_raw_fsinfo_passthru_parse(blob, mem_ctx,
    318338                                                     RAW_QFS_OBJECTID_INFORMATION, fsinfo);
     339
     340        case RAW_QFS_SECTOR_SIZE_INFORMATION:
     341                return smb_raw_fsinfo_passthru_parse(blob, mem_ctx,
     342                                RAW_QFS_SECTOR_SIZE_INFORMATION, fsinfo);
    319343        }
    320344
     
    333357        return smb_raw_fsinfo_recv(req, mem_ctx, fsinfo);
    334358}
     359
     360/****************************************************************************
     361 Set FSInfo raw interface (async recv)
     362****************************************************************************/
     363static NTSTATUS smb_raw_setfsinfo_recv(struct smbcli_request *req,
     364                             TALLOC_CTX *mem_ctx,
     365                             union smb_setfsinfo *set_fsinfo)
     366{
     367        DATA_BLOB blob = data_blob_null;
     368        NTSTATUS status;
     369
     370        if (set_fsinfo->generic.level != RAW_SETFS_UNIX_INFO) {
     371                return NT_STATUS_INVALID_PARAMETER;
     372        }
     373
     374        status = smb_raw_qfsinfo_blob_recv(req, mem_ctx, &blob);
     375        data_blob_free(&blob);
     376        return status;
     377}
     378
     379/****************************************************************************
     380 Set FSInfo raw interface (async send)
     381****************************************************************************/
     382static struct smbcli_request *smb_raw_setfsinfo_send(struct smbcli_tree *tree,
     383                                                TALLOC_CTX *mem_ctx,
     384                                                union smb_setfsinfo *set_fsinfo)
     385{
     386        struct smb_trans2 tp;
     387        uint16_t info_level;
     388        uint16_t setup = TRANSACT2_SETFSINFO;
     389
     390        if (set_fsinfo->generic.level != RAW_SETFS_UNIX_INFO) {
     391                return NULL;
     392        }
     393        tp.in.max_setup = 0;
     394        tp.in.flags = 0;
     395        tp.in.timeout = 0;
     396        tp.in.setup_count = 1;
     397        tp.in.max_param = 0;
     398        tp.in.max_data = 0xFFFF;
     399        tp.in.setup = &setup;
     400        tp.in.timeout = 0;
     401
     402        tp.in.params = data_blob_talloc(mem_ctx, NULL, 4);
     403        if (!tp.in.params.data) {
     404                return NULL;
     405        }
     406        info_level = (uint16_t)set_fsinfo->generic.level;
     407        SSVAL(tp.in.params.data, 0, 0);
     408        SSVAL(tp.in.params.data, 2, info_level);
     409
     410        tp.in.data = data_blob_talloc(mem_ctx, NULL, 12);
     411        if (!tp.in.data.data) {
     412                return NULL;
     413        }
     414
     415        SSVAL(tp.in.data.data, 0, set_fsinfo->unix_info.in.major_version);
     416        SSVAL(tp.in.data.data, 2, set_fsinfo->unix_info.in.minor_version);
     417        SBVAL(tp.in.data.data, 4, set_fsinfo->unix_info.in.capability);
     418
     419        return smb_raw_trans2_send(tree, &tp);
     420}
     421
     422/****************************************************************************
     423 Set FSInfo raw interface (sync interface)
     424****************************************************************************/
     425_PUBLIC_ NTSTATUS smb_raw_setfsinfo(struct smbcli_tree *tree,
     426                        TALLOC_CTX *mem_ctx,
     427                        union smb_setfsinfo *set_fsinfo)
     428{
     429        struct smbcli_request *req = smb_raw_setfsinfo_send(tree, mem_ctx, set_fsinfo);
     430        return smb_raw_setfsinfo_recv(req, mem_ctx, set_fsinfo);
     431}
  • vendor/current/source4/libcli/raw/rawnegotiate.c

    r740 r988  
    2222
    2323#include "includes.h"
     24#include <tevent.h>
     25#include "system/time.h"
    2426#include "libcli/raw/libcliraw.h"
    2527#include "libcli/raw/raw_proto.h"
    26 #include "system/time.h"
     28#include "../libcli/smb/smbXcli_base.h"
     29#include "../lib/util/tevent_ntstatus.h"
    2730
    28 static const struct {
    29         enum protocol_types prot;
    30         const char *name;
    31 } prots[] = {
    32         {PROTOCOL_CORE,"PC NETWORK PROGRAM 1.0"},
    33         {PROTOCOL_COREPLUS,"MICROSOFT NETWORKS 1.03"},
    34         {PROTOCOL_LANMAN1,"MICROSOFT NETWORKS 3.0"},
    35         {PROTOCOL_LANMAN1,"LANMAN1.0"},
    36         {PROTOCOL_LANMAN1,"Windows for Workgroups 3.1a"},
    37         {PROTOCOL_LANMAN2,"LM1.2X002"},
    38         {PROTOCOL_LANMAN2,"DOS LANMAN2.1"},
    39         {PROTOCOL_LANMAN2,"LANMAN2.1"},
    40         {PROTOCOL_LANMAN2,"Samba"},
    41         {PROTOCOL_NT1,"NT LANMAN 1.0"},
    42         {PROTOCOL_NT1,"NT LM 0.12"},
    43 #if 0
    44         /* we don't yet handle chaining a SMB transport onto SMB2 */
    45         {PROTOCOL_SMB2,"SMB 2.002"},
    46 #endif
     31struct smb_raw_negotiate_state {
     32        struct smbcli_transport *transport;
    4733};
    4834
    49 /*
    50   Send a negprot command.
    51 */
    52 struct smbcli_request *smb_raw_negotiate_send(struct smbcli_transport *transport,
    53                                               bool unicode,
    54                                               int maxprotocol)
     35static void smb_raw_negotiate_done(struct tevent_req *subreq);
     36
     37struct tevent_req *smb_raw_negotiate_send(TALLOC_CTX *mem_ctx,
     38                                          struct tevent_context *ev,
     39                                          struct smbcli_transport *transport,
     40                                          int minprotocol,
     41                                          int maxprotocol)
    5542{
    56         struct smbcli_request *req;
    57         int i;
    58         uint16_t flags2 = 0;
     43        struct tevent_req *req;
     44        struct smb_raw_negotiate_state *state;
     45        struct tevent_req *subreq;
     46        uint32_t timeout_msec = transport->options.request_timeout * 1000;
    5947
    60         req = smbcli_request_setup_transport(transport, SMBnegprot, 0, 0);
    61         if (!req) {
     48        req = tevent_req_create(mem_ctx, &state,
     49                                struct smb_raw_negotiate_state);;
     50        if (req == NULL) {
    6251                return NULL;
    6352        }
     53        state->transport = transport;
    6454
    65         flags2 |= FLAGS2_32_BIT_ERROR_CODES;
    66         if (unicode) {
    67                 flags2 |= FLAGS2_UNICODE_STRINGS;
    68         }
    69         flags2 |= FLAGS2_EXTENDED_ATTRIBUTES;
    70         flags2 |= FLAGS2_LONG_PATH_COMPONENTS;
    71         flags2 |= FLAGS2_IS_LONG_NAME;
    72 
    73         if (transport->options.use_spnego) {
    74                 flags2 |= FLAGS2_EXTENDED_SECURITY;
     55        if (maxprotocol > PROTOCOL_NT1) {
     56                maxprotocol = PROTOCOL_NT1;
    7557        }
    7658
    77         SSVAL(req->out.hdr,HDR_FLG2, flags2);
     59        subreq = smbXcli_negprot_send(state, ev,
     60                                      transport->conn,
     61                                      timeout_msec,
     62                                      minprotocol,
     63                                      maxprotocol);
     64        if (tevent_req_nomem(subreq, req)) {
     65                return tevent_req_post(req, ev);
     66        }
     67        tevent_req_set_callback(subreq, smb_raw_negotiate_done, req);
    7868
    79         /* setup the protocol strings */
    80         for (i=0; i < ARRAY_SIZE(prots) && prots[i].prot <= maxprotocol; i++) {
    81                 smbcli_req_append_bytes(req, (const uint8_t *)"\2", 1);
    82                 smbcli_req_append_string(req, prots[i].name, STR_TERMINATE | STR_ASCII);
     69        return req;
     70}
     71
     72static void smb_raw_negotiate_done(struct tevent_req *subreq)
     73{
     74        struct tevent_req *req =
     75                tevent_req_callback_data(subreq,
     76                struct tevent_req);
     77        struct smb_raw_negotiate_state *state =
     78                tevent_req_data(req,
     79                struct smb_raw_negotiate_state);
     80        struct smbcli_negotiate *n = &state->transport->negotiate;
     81        struct smbXcli_conn *c = state->transport->conn;
     82        NTSTATUS status;
     83        NTTIME ntt;
     84
     85        status = smbXcli_negprot_recv(subreq);
     86        TALLOC_FREE(subreq);
     87        if (tevent_req_nterror(req, status)) {
     88                return;
    8389        }
    8490
    85         if (!smbcli_request_send(req)) {
    86                 smbcli_request_destroy(req);
    87                 return NULL;
     91        n->protocol = smbXcli_conn_protocol(c);
     92
     93        n->sec_mode = smb1cli_conn_server_security_mode(c);
     94        n->max_mux  = smbXcli_conn_max_requests(c);
     95        n->max_xmit = smb1cli_conn_max_xmit(c);
     96        n->sesskey  = smb1cli_conn_server_session_key(c);
     97        n->capabilities = smb1cli_conn_capabilities(c);;
     98
     99        /* this time arrives in real GMT */
     100        ntt = smbXcli_conn_server_system_time(c);
     101        n->server_time = nt_time_to_unix(ntt);
     102        n->server_zone = smb1cli_conn_server_time_zone(c);
     103
     104        if (n->capabilities & CAP_EXTENDED_SECURITY) {
     105                const DATA_BLOB *b = smbXcli_conn_server_gss_blob(c);
     106                if (b) {
     107                        n->secblob = *b;
     108                }
     109        } else {
     110                const uint8_t *p = smb1cli_conn_server_challenge(c);
     111                if (p) {
     112                        n->secblob = data_blob_const(p, 8);
     113                }
    88114        }
    89115
    90         return req;
     116        n->readbraw_supported = smb1cli_conn_server_readbraw(c);
     117        n->readbraw_supported = smb1cli_conn_server_writebraw(c);
     118        n->lockread_supported = smb1cli_conn_server_lockread(c);
     119
     120        tevent_req_done(req);
    91121}
    92122
     
    94124 Send a negprot command.
    95125*/
    96 NTSTATUS smb_raw_negotiate_recv(struct smbcli_request *req)
     126NTSTATUS smb_raw_negotiate_recv(struct tevent_req *req)
    97127{
    98         struct smbcli_transport *transport = req->transport;
    99         int protocol;
    100 
    101         if (!smbcli_request_receive(req) ||
    102             smbcli_request_is_error(req)) {
    103                 return smbcli_request_destroy(req);
    104         }
    105 
    106         SMBCLI_CHECK_MIN_WCT(req, 1);
    107 
    108         protocol = SVALS(req->in.vwv, VWV(0));
    109 
    110         if (protocol >= ARRAY_SIZE(prots) || protocol < 0) {
    111                 req->status = NT_STATUS_UNSUCCESSFUL;
    112                 return smbcli_request_destroy(req);
    113         }
    114 
    115         transport->negotiate.protocol = prots[protocol].prot;
    116 
    117         if (transport->negotiate.protocol >= PROTOCOL_NT1) {
    118                 NTTIME ntt;
    119 
    120                 /* NT protocol */
    121                 SMBCLI_CHECK_WCT(req, 17);
    122                 transport->negotiate.sec_mode = CVAL(req->in.vwv,VWV(1));
    123                 transport->negotiate.max_mux  = SVAL(req->in.vwv,VWV(1)+1);
    124                 transport->negotiate.max_xmit = IVAL(req->in.vwv,VWV(3)+1);
    125                 transport->negotiate.sesskey  = IVAL(req->in.vwv,VWV(7)+1);
    126                 transport->negotiate.capabilities = IVAL(req->in.vwv,VWV(9)+1);
    127 
    128                 /* this time arrives in real GMT */
    129                 ntt = smbcli_pull_nttime(req->in.vwv, VWV(11)+1);
    130                 transport->negotiate.server_time = nt_time_to_unix(ntt);               
    131                 transport->negotiate.server_zone = SVALS(req->in.vwv,VWV(15)+1) * 60;
    132                 transport->negotiate.key_len = CVAL(req->in.vwv,VWV(16)+1);
    133 
    134                 if (transport->negotiate.capabilities & CAP_EXTENDED_SECURITY) {
    135                         if (req->in.data_size < 16) {
    136                                 goto failed;
    137                         }
    138                         transport->negotiate.server_guid = smbcli_req_pull_blob(&req->in.bufinfo, transport, req->in.data, 16);
    139                         transport->negotiate.secblob = smbcli_req_pull_blob(&req->in.bufinfo, transport, req->in.data + 16, req->in.data_size - 16);
    140                 } else {
    141                         if (req->in.data_size < (transport->negotiate.key_len)) {
    142                                 goto failed;
    143                         }
    144                         transport->negotiate.secblob = smbcli_req_pull_blob(&req->in.bufinfo, transport, req->in.data, transport->negotiate.key_len);
    145                         smbcli_req_pull_string(&req->in.bufinfo, transport, &transport->negotiate.server_domain,
    146                                             req->in.data+transport->negotiate.key_len,
    147                                             req->in.data_size-transport->negotiate.key_len, STR_UNICODE|STR_NOALIGN);
    148                         /* here comes the server name */
    149                 }
    150 
    151                 if (transport->negotiate.capabilities & CAP_RAW_MODE) {
    152                         transport->negotiate.readbraw_supported = true;
    153                         transport->negotiate.writebraw_supported = true;
    154                 }
    155 
    156                 if (transport->negotiate.capabilities & CAP_LOCK_AND_READ)
    157                         transport->negotiate.lockread_supported = true;
    158         } else if (transport->negotiate.protocol >= PROTOCOL_LANMAN1) {
    159                 SMBCLI_CHECK_WCT(req, 13);
    160                 transport->negotiate.sec_mode = SVAL(req->in.vwv,VWV(1));
    161                 transport->negotiate.max_xmit = SVAL(req->in.vwv,VWV(2));
    162                 transport->negotiate.sesskey =  IVAL(req->in.vwv,VWV(6));
    163                 transport->negotiate.server_zone = SVALS(req->in.vwv,VWV(10)) * 60;
    164                
    165                 /* this time is converted to GMT by raw_pull_dos_date */
    166                 transport->negotiate.server_time = raw_pull_dos_date(transport,
    167                                                                      req->in.vwv+VWV(8));
    168                 if ((SVAL(req->in.vwv,VWV(5)) & 0x1)) {
    169                         transport->negotiate.readbraw_supported = 1;
    170                 }
    171                 if ((SVAL(req->in.vwv,VWV(5)) & 0x2)) {
    172                         transport->negotiate.writebraw_supported = 1;
    173                 }
    174                 transport->negotiate.secblob = smbcli_req_pull_blob(&req->in.bufinfo, transport,
    175                                                                  req->in.data, req->in.data_size);
    176         } else {
    177                 /* the old core protocol */
    178                 transport->negotiate.sec_mode = 0;
    179                 transport->negotiate.server_time = time(NULL);
    180                 transport->negotiate.max_xmit = transport->options.max_xmit;
    181                 transport->negotiate.server_zone = get_time_zone(transport->negotiate.server_time);
    182         }
    183 
    184         /* a way to force ascii SMB */
    185         if (!transport->options.unicode) {
    186                 transport->negotiate.capabilities &= ~CAP_UNICODE;
    187         }
    188 
    189         if (!transport->options.ntstatus_support) {
    190                 transport->negotiate.capabilities &= ~CAP_STATUS32;
    191         }
    192 
    193         if (!transport->options.use_level2_oplocks) {
    194                 transport->negotiate.capabilities &= ~CAP_LEVEL_II_OPLOCKS;
    195         }
    196 
    197 failed:
    198         return smbcli_request_destroy(req);
     128        return tevent_req_simple_recv_ntstatus(req);
    199129}
    200130
     
    203133 Send a negprot command (sync interface)
    204134*/
    205 NTSTATUS smb_raw_negotiate(struct smbcli_transport *transport, bool unicode, int maxprotocol)
     135NTSTATUS smb_raw_negotiate(struct smbcli_transport *transport, bool unicode,
     136                           int minprotocol, int maxprotocol)
    206137{
    207         struct smbcli_request *req = smb_raw_negotiate_send(transport, unicode, maxprotocol);
    208         return smb_raw_negotiate_recv(req);
     138        NTSTATUS status = NT_STATUS_INTERNAL_ERROR;
     139        struct tevent_req *subreq = NULL;
     140        bool ok;
     141
     142        subreq = smb_raw_negotiate_send(transport,
     143                                        transport->ev,
     144                                        transport,
     145                                        minprotocol,
     146                                        maxprotocol);
     147        if (subreq == NULL) {
     148                return NT_STATUS_NO_MEMORY;
     149        }
     150
     151        ok = tevent_req_poll(subreq, transport->ev);
     152        if (!ok) {
     153                status = map_nt_error_from_unix_common(errno);
     154                goto failed;
     155        }
     156
     157        status = smb_raw_negotiate_recv(subreq);
     158
     159failed:
     160        TALLOC_FREE(subreq);
     161        return status;
    209162}
  • vendor/current/source4/libcli/raw/rawnotify.c

    r740 r988  
    1919
    2020#include "includes.h"
     21#include <tevent.h>
    2122#include "libcli/raw/libcliraw.h"
    2223#include "libcli/raw/raw_proto.h"
    23 #include "../lib/util/dlinklist.h"
    2424
    2525/****************************************************************************
     
    102102
    103103/****************************************************************************
    104   handle ntcancel replies from the server,
    105   as the MID of the real reply and the ntcancel reply is the same
    106   we need to do find out to what request the reply belongs
    107 ****************************************************************************/
    108 struct smbcli_request *smbcli_handle_ntcancel_reply(struct smbcli_request *req,
    109                                                     size_t len, const uint8_t *hdr)
    110 {
    111         struct smbcli_request *ntcancel;
    112 
    113         if (!req) return req;
    114 
    115         if (!req->ntcancel) return req;
    116 
    117         if (len >= MIN_SMB_SIZE + NBT_HDR_SIZE &&
    118             (CVAL(hdr, HDR_FLG) & FLAG_REPLY) &&
    119              CVAL(hdr,HDR_COM) == SMBntcancel) {
    120                 ntcancel = req->ntcancel;
    121                 DLIST_REMOVE(req->ntcancel, ntcancel);
    122 
    123                 /*
    124                  * TODO: untill we understand how the
    125                  *       smb_signing works for this case we
    126                  *       return NULL, to just ignore the packet
    127                  */
    128                 /*return ntcancel;*/
    129                 return NULL;
    130         }
    131 
    132         return req;
    133 }
    134 
    135 /****************************************************************************
    136104 Send a NT Cancel request - used to hurry along a pending request. Usually
    137105 used to cancel a pending change notify request
     
    140108NTSTATUS smb_raw_ntcancel(struct smbcli_request *oldreq)
    141109{
    142         struct smbcli_request *req;
     110        bool ok;
    143111
    144         req = smbcli_request_setup_transport(oldreq->transport, SMBntcancel, 0, 0);
     112        if (oldreq->subreqs[0] == NULL) {
     113                return NT_STATUS_OK;
     114        }
    145115
    146         SSVAL(req->out.hdr, HDR_MID, SVAL(oldreq->out.hdr, HDR_MID));   
    147         SSVAL(req->out.hdr, HDR_PID, SVAL(oldreq->out.hdr, HDR_PID));   
    148         SSVAL(req->out.hdr, HDR_TID, SVAL(oldreq->out.hdr, HDR_TID));   
    149         SSVAL(req->out.hdr, HDR_UID, SVAL(oldreq->out.hdr, HDR_UID));   
    150 
    151         /* this request does not expect a reply, so tell the signing
    152            subsystem not to allocate an id for a reply */
    153         req->sign_single_increment = 1;
    154         req->one_way_request = 1;
    155 
    156         /*
    157          * smbcli_request_send() free's oneway requests
    158          * but we want to keep it under oldreq->ntcancel
    159          */
    160         req->do_not_free = true;
    161         talloc_steal(oldreq, req);
    162 
    163         smbcli_request_send(req);
    164 
    165         DLIST_ADD_END(oldreq->ntcancel, req, struct smbcli_request *);
     116        ok = tevent_req_cancel(oldreq->subreqs[0]);
     117        if (!ok) {
     118                return NT_STATUS_INTERNAL_ERROR;
     119        }
    166120
    167121        return NT_STATUS_OK;
  • vendor/current/source4/libcli/raw/rawreadwrite.c

    r414 r988  
    105105        }
    106106
    107         /* the transport layer needs to know that a readbraw is pending
    108            and handle receives a little differently */
    109         if (parms->generic.level == RAW_READ_READBRAW) {
    110                 tree->session->transport->readbraw_pending = 1;
    111         }
    112 
    113107        return req;
    114108}
     
    162156                parms->readx.out.compaction_mode = SVAL(req->in.vwv, VWV(3));
    163157                parms->readx.out.nread = SVAL(req->in.vwv, VWV(5));
     158                parms->readx.out.flags2 = req->flags2;
     159                parms->readx.out.data_offset = SVAL(req->in.vwv, VWV(6));
    164160
    165161                /* handle oversize replies for non-chained readx replies with
     
    303299 raw write interface (async recv)
    304300****************************************************************************/
    305 NTSTATUS smb_raw_write_recv(struct smbcli_request *req, union smb_write *parms)
     301_PUBLIC_ NTSTATUS smb_raw_write_recv(struct smbcli_request *req, union smb_write *parms)
    306302{
    307303        if (!smbcli_request_receive(req) ||
  • vendor/current/source4/libcli/raw/rawrequest.c

    r740 r988  
    2626#include "libcli/raw/libcliraw.h"
    2727#include "libcli/raw/raw_proto.h"
    28 #include "../lib/util/dlinklist.h"
    2928#include "lib/events/events.h"
    3029#include "librpc/ndr/libndr.h"
    3130#include "librpc/gen_ndr/ndr_misc.h"
     31#include "../libcli/smb/smbXcli_base.h"
    3232
    3333/* we over allocate the data buffer to prevent too many realloc calls */
     
    6060        if (!req) return NT_STATUS_UNSUCCESSFUL;
    6161
    62         if (req->transport) {
    63                 /* remove it from the list of pending requests (a null op if
    64                    its not in the list) */
    65                 DLIST_REMOVE(req->transport->pending_recv, req);
    66         }
    67 
    6862        if (req->state == SMBCLI_REQUEST_ERROR &&
    6963            NT_STATUS_IS_OK(req->status)) {
     
    8276
    8377/*
    84   low-level function to setup a request buffer for a non-SMB packet
    85   at the transport level
    86 */
    87 struct smbcli_request *smbcli_request_setup_nonsmb(struct smbcli_transport *transport, size_t size)
     78  setup a SMB packet at transport level
     79*/
     80struct smbcli_request *smbcli_request_setup_transport(struct smbcli_transport *transport,
     81                                                      uint8_t command, unsigned int wct, unsigned int buflen)
    8882{
    8983        struct smbcli_request *req;
    90 
    91         req = talloc(transport, struct smbcli_request);
     84        size_t size;
     85
     86        size = NBT_HDR_SIZE + MIN_SMB_SIZE + wct*2 + buflen;
     87
     88        req = talloc_zero(transport, struct smbcli_request);
    9289        if (!req) {
    9390                return NULL;
    9491        }
    95         ZERO_STRUCTP(req);
    9692
    9793        /* setup the request context */
    9894        req->state = SMBCLI_REQUEST_INIT;
    9995        req->transport = transport;
    100         req->session = NULL;
    101         req->tree = NULL;
    10296        req->out.size = size;
    10397
     
    10599        req->out.allocated = req->out.size + REQ_OVER_ALLOCATION;
    106100
    107         req->out.buffer = talloc_array(req, uint8_t, req->out.allocated);
     101        req->out.buffer = talloc_zero_array(req, uint8_t, req->out.allocated);
    108102        if (!req->out.buffer) {
    109103                return NULL;
    110104        }
    111105
    112         SIVAL(req->out.buffer, 0, 0);
    113 
    114         return req;
    115 }
    116 
    117 
    118 /*
    119   setup a SMB packet at transport level
    120 */
    121 struct smbcli_request *smbcli_request_setup_transport(struct smbcli_transport *transport,
    122                                                       uint8_t command, unsigned int wct, unsigned int buflen)
    123 {
    124         struct smbcli_request *req;
    125 
    126         req = smbcli_request_setup_nonsmb(transport, NBT_HDR_SIZE + MIN_SMB_SIZE + wct*2 + buflen);
    127 
    128         if (!req) return NULL;
    129        
    130106        req->out.hdr = req->out.buffer + NBT_HDR_SIZE;
    131107        req->out.vwv = req->out.hdr + HDR_VWV;
     
    144120        SSVAL(req->out.hdr,HDR_FLG2, 0);
    145121
    146         if (command != SMBtranss && command != SMBtranss2) {
    147                 /* assign a mid */
    148                 req->mid = smbcli_transport_next_mid(transport);
    149         }
    150 
    151122        /* copy the pid, uid and mid to the request */
    152123        SSVAL(req->out.hdr, HDR_PID, 0);
    153124        SSVAL(req->out.hdr, HDR_UID, 0);
    154         SSVAL(req->out.hdr, HDR_MID, req->mid);
     125        SSVAL(req->out.hdr, HDR_MID, 0);
    155126        SSVAL(req->out.hdr, HDR_TID,0);
    156127        SSVAL(req->out.hdr, HDR_PIDHIGH,0);
     
    176147        if (!req) return NULL;
    177148
     149        smb1cli_session_set_id(session->smbXcli, session->vuid);
     150
    178151        req->session = session;
    179152
     
    197170        req = smbcli_request_setup_session(tree->session, command, wct, buflen);
    198171        if (req) {
     172                smb1cli_tcon_set_id(tree->smbXcli, tree->tid);
     173
    199174                req->tree = tree;
    200175                SSVAL(req->out.hdr,HDR_TID,tree->tid);
     
    277252                                      unsigned int wct, size_t buflen)
    278253{
    279         unsigned int new_size = 1 + (wct*2) + 2 + buflen;
    280 
    281         SSVAL(req->out.vwv, VWV(0), command);
    282         SSVAL(req->out.vwv, VWV(1), req->out.size - NBT_HDR_SIZE);
    283 
    284         smbcli_req_grow_allocation(req, req->out.data_size + new_size);
    285 
    286         req->out.vwv = req->out.buffer + req->out.size + 1;
    287         SCVAL(req->out.vwv, -1, wct);
     254        size_t wct_ofs;
     255        size_t size;
     256
     257        /*
     258         * here we only support one chained command
     259         * If someone needs longer chains, the low
     260         * level code should be used directly.
     261         */
     262        if (req->subreqs[0] != NULL) {
     263                return NT_STATUS_INVALID_PARAMETER_MIX;
     264        }
     265        if (req->subreqs[1] != NULL) {
     266                return NT_STATUS_INVALID_PARAMETER_MIX;
     267        }
     268
     269        req->subreqs[0] = smbcli_transport_setup_subreq(req);
     270        if (req->subreqs[0] == NULL) {
     271                return NT_STATUS_NO_MEMORY;
     272        }
     273
     274        wct_ofs = smb1cli_req_wct_ofs(req->subreqs, 1);
     275
     276        size = NBT_HDR_SIZE + wct_ofs + 1 + VWV(wct) + 2 + buflen;
     277
     278        req->out.size = size;
     279
     280        /* over allocate by a small amount */
     281        req->out.allocated = req->out.size + REQ_OVER_ALLOCATION;
     282
     283        req->out.buffer = talloc_zero_array(req, uint8_t, req->out.allocated);
     284        if (!req->out.buffer) {
     285                return NT_STATUS_NO_MEMORY;
     286        }
     287
     288        req->out.hdr = req->out.buffer + NBT_HDR_SIZE;
     289        req->out.vwv = req->out.hdr + wct_ofs;
     290        req->out.wct = wct;
     291        req->out.data = req->out.vwv + VWV(wct) + 2;
     292        req->out.data_size = buflen;
     293        req->out.ptr = req->out.data;
     294
     295        SCVAL(req->out.hdr, HDR_WCT, wct);
    288296        SSVAL(req->out.vwv, VWV(wct), buflen);
    289297
    290         req->out.size += new_size;
    291         req->out.data_size += new_size;
     298        memcpy(req->out.hdr, "\377SMB", 4);
     299        SCVAL(req->out.hdr,HDR_COM,command);
     300
     301        SCVAL(req->out.hdr,HDR_FLG, FLAG_CASELESS_PATHNAMES);
     302        SSVAL(req->out.hdr,HDR_FLG2, 0);
     303
     304        /* copy the pid, uid and mid to the request */
     305        SSVAL(req->out.hdr, HDR_PID, 0);
     306        SSVAL(req->out.hdr, HDR_UID, 0);
     307        SSVAL(req->out.hdr, HDR_MID, 0);
     308        SSVAL(req->out.hdr, HDR_TID,0);
     309        SSVAL(req->out.hdr, HDR_PIDHIGH,0);
     310        SIVAL(req->out.hdr, HDR_RCLS, 0);
     311        memset(req->out.hdr+HDR_SS_FIELD, 0, 10);
     312
     313        if (req->session != NULL) {
     314                SSVAL(req->out.hdr, HDR_FLG2, req->session->flags2);
     315                SSVAL(req->out.hdr, HDR_PID, req->session->pid & 0xFFFF);
     316                SSVAL(req->out.hdr, HDR_PIDHIGH, req->session->pid >> 16);
     317                SSVAL(req->out.hdr, HDR_UID, req->session->vuid);
     318        }
     319
     320        if (req->tree != NULL) {
     321                SSVAL(req->out.hdr, HDR_TID, req->tree->tid);
     322        }
    292323
    293324        return NT_STATUS_OK;
     
    295326
    296327/*
    297   aadvance to the next chained reply in a request
     328  advance to the next chained reply in a request
    298329*/
    299330NTSTATUS smbcli_chained_advance(struct smbcli_request *req)
    300331{
    301         uint8_t *buffer;
    302 
    303         if (CVAL(req->in.vwv, VWV(0)) == SMB_CHAIN_NONE) {
    304                 return NT_STATUS_NOT_FOUND;
    305         }
    306 
    307         buffer = req->in.hdr + SVAL(req->in.vwv, VWV(1));
    308 
    309         if (buffer + 3 > req->in.buffer + req->in.size) {
    310                 return NT_STATUS_BUFFER_TOO_SMALL;
    311         }
    312 
    313         req->in.vwv = buffer + 1;
    314         req->in.wct = CVAL(buffer, 0);
    315         if (buffer + 3 + req->in.wct*2 > req->in.buffer + req->in.size) {
    316                 return NT_STATUS_BUFFER_TOO_SMALL;
    317         }
    318         req->in.data = req->in.vwv + 2 + req->in.wct * 2;
    319         req->in.data_size = SVAL(req->in.vwv, VWV(req->in.wct));
    320 
    321         /* fix the bufinfo */
     332        struct smbcli_transport *transport = req->transport;
     333        uint8_t *hdr = NULL;
     334        uint8_t wct = 0;
     335        uint16_t *vwv = NULL;
     336        uint32_t num_bytes = 0;
     337        uint8_t *bytes = NULL;
     338        struct iovec *recv_iov = NULL;
     339        uint8_t *inbuf = NULL;
     340
     341        if (req->subreqs[0] != NULL) {
     342                return NT_STATUS_INVALID_PARAMETER_MIX;
     343        }
     344        if (req->subreqs[1] == NULL) {
     345                return NT_STATUS_INVALID_PARAMETER_MIX;
     346        }
     347
     348        req->status = smb1cli_req_recv(req->subreqs[1], req,
     349                                       &recv_iov,
     350                                       &hdr,
     351                                       &wct,
     352                                       &vwv,
     353                                       NULL, /* pvwv_offset */
     354                                       &num_bytes,
     355                                       &bytes,
     356                                       NULL, /* pbytes_offset */
     357                                       &inbuf,
     358                                       NULL, 0); /* expected */
     359        TALLOC_FREE(req->subreqs[1]);
     360        if (!NT_STATUS_IS_OK(req->status)) {
     361                if (recv_iov == NULL) {
     362                        req->state = SMBCLI_REQUEST_ERROR;
     363                        return req->status;
     364                }
     365        }
     366
     367        /* fill in the 'in' portion of the matching request */
     368        req->in.buffer = inbuf;
     369        req->in.size = NBT_HDR_SIZE + PTR_DIFF(bytes, hdr) + num_bytes;
     370        req->in.allocated = req->in.size;
     371
     372        req->in.hdr = hdr;
     373        req->in.vwv = (uint8_t *)vwv;
     374        req->in.wct = wct;
     375        req->in.data = bytes;
     376        req->in.data_size = num_bytes;
     377        req->in.ptr = req->in.data;
     378        req->flags2 = SVAL(req->in.hdr, HDR_FLG2);
     379
    322380        smb_setup_bufinfo(req);
    323381
    324         if (buffer + 3 + req->in.wct*2 + req->in.data_size >
    325             req->in.buffer + req->in.size) {
    326                 return NT_STATUS_BUFFER_TOO_SMALL;
    327         }
     382        transport->error.e.nt_status = req->status;
     383        if (NT_STATUS_IS_OK(req->status)) {
     384                transport->error.etype = ETYPE_NONE;
     385        } else {
     386                transport->error.etype = ETYPE_SMB;
     387        }
     388
     389        req->state = SMBCLI_REQUEST_DONE;
    328390
    329391        return NT_STATUS_OK;
     
    336398bool smbcli_request_send(struct smbcli_request *req)
    337399{
    338         if (IVAL(req->out.buffer, 0) == 0) {
    339                 _smb_setlen(req->out.buffer, req->out.size - NBT_HDR_SIZE);
    340         }
    341 
    342         smbcli_request_calculate_sign_mac(req);
    343 
    344400        smbcli_transport_send(req);
    345 
    346401        return true;
    347402}
     
    359414        /* keep receiving packets until this one is replied to */
    360415        while (req->state <= SMBCLI_REQUEST_RECV) {
    361                 if (event_loop_once(req->transport->socket->event.ctx) != 0) {
     416                if (tevent_loop_once(req->transport->ev) != 0) {
    362417                        return false;
    363418                }
     
    365420
    366421        return req->state == SMBCLI_REQUEST_DONE;
    367 }
    368 
    369 
    370 /*
    371   handle oplock break requests from the server - return true if the request was
    372   an oplock break
    373 */
    374 bool smbcli_handle_oplock_break(struct smbcli_transport *transport, unsigned int len, const uint8_t *hdr, const uint8_t *vwv)
    375 {
    376         /* we must be very fussy about what we consider an oplock break to avoid
    377            matching readbraw replies */
    378         if (len != MIN_SMB_SIZE + VWV(8) + NBT_HDR_SIZE ||
    379             (CVAL(hdr, HDR_FLG) & FLAG_REPLY) ||
    380             CVAL(hdr,HDR_COM) != SMBlockingX ||
    381             SVAL(hdr, HDR_MID) != 0xFFFF ||
    382             SVAL(vwv,VWV(6)) != 0 ||
    383             SVAL(vwv,VWV(7)) != 0) {
    384                 return false;
    385         }
    386 
    387         if (transport->oplock.handler) {
    388                 uint16_t tid = SVAL(hdr, HDR_TID);
    389                 uint16_t fnum = SVAL(vwv,VWV(2));
    390                 uint8_t level = CVAL(vwv,VWV(3)+1);
    391                 transport->oplock.handler(transport, tid, fnum, level, transport->oplock.private_data);
    392         }
    393 
    394         return true;
    395422}
    396423
     
    587614        }
    588615
    589         ret = convert_string_talloc(mem_ctx, CH_UTF16, CH_UNIX, src, src_len2, (void **)dest, &ret_size, false);
     616        ret = convert_string_talloc(mem_ctx, CH_UTF16, CH_UNIX, src, src_len2, (void **)dest, &ret_size);
    590617        if (!ret) {
    591618                *dest = NULL;
     
    630657        }
    631658
    632         ret = convert_string_talloc(mem_ctx, CH_DOS, CH_UNIX, src, src_len2, (void **)dest, &ret_size, false);
     659        ret = convert_string_talloc(mem_ctx, CH_DOS, CH_UNIX, src, src_len2, (void **)dest, &ret_size);
    633660
    634661        if (!ret) {
     
    784811        src_len2 = utf16_len_n(src, src_len);
    785812
    786         ret = convert_string_talloc(mem_ctx, CH_UTF16, CH_UNIX, src, src_len2, (void **)&dest2, &ret_size, false);
     813        ret = convert_string_talloc(mem_ctx, CH_UTF16, CH_UNIX, src, src_len2, (void **)&dest2, &ret_size);
    787814        if (!ret) {
    788815                *dest = NULL;
     
    831858        }
    832859
    833         ret = convert_string_talloc(mem_ctx, CH_DOS, CH_UNIX, src, src_len2, (void **)&dest2, &ret_size, false);
     860        ret = convert_string_talloc(mem_ctx, CH_DOS, CH_UNIX, src, src_len2, (void **)&dest2, &ret_size);
    834861
    835862        if (!ret) {
  • vendor/current/source4/libcli/raw/rawsearch.c

    r740 r988  
    457457                                     &data->id_both_directory_info.short_name,
    458458                                     68, 70, STR_LEN8BIT | STR_UNICODE);
     459                memcpy(data->id_both_directory_info.short_name_buf, blob->data + 70, 24);
    459460                data->id_both_directory_info.file_id     = BVAL(blob->data,            96);
    460461                len = smbcli_blob_pull_string(NULL, mem_ctx, blob,
  • vendor/current/source4/libcli/raw/rawsetfileinfo.c

    r740 r988  
    8080                NEED_BLOB(20);
    8181                SIVAL(blob->data, 0, parms->rename_information.in.overwrite);
     82                SIVAL(blob->data, 4, 0);
    8283                SBVAL(blob->data, 8, parms->rename_information.in.root_fid);
    8384                len = smbcli_blob_append_string(NULL, mem_ctx, blob,
     
    263264                                                    parms, blob);
    264265
    265                 /* Unhandled levels */
    266 
     266        /* Unhandled levels */
    267267        case RAW_SFILEINFO_UNIX_LINK:
    268268        case RAW_SFILEINFO_UNIX_HLINK:
    269269        case RAW_SFILEINFO_RENAME_INFORMATION_SMB2:
     270        case RAW_SFILEINFO_LINK_INFORMATION:
    270271                break;
    271272        }
  • vendor/current/source4/libcli/raw/rawshadow.c

    r414 r988  
    2323#include "libcli/raw/libcliraw.h"
    2424#include "libcli/raw/raw_proto.h"
    25 #include "libcli/raw/ioctl.h"
     25#include "../libcli/smb/smb_constants.h"
    2626
    2727/*
  • vendor/current/source4/libcli/raw/rawtrans.c

    r740 r988  
    2020
    2121#include "includes.h"
    22 #include "../lib/util/dlinklist.h"
     22#include <tevent.h>
    2323#include "libcli/raw/libcliraw.h"
    2424#include "libcli/raw/raw_proto.h"
    25 
    26 #define TORTURE_TRANS_DATA 0
    27 
    28 /*
    29   check out of bounds for incoming data
    30 */
    31 static bool raw_trans_oob(struct smbcli_request *req,
    32                           unsigned int offset, unsigned int count)
    33 {
    34         uint8_t *ptr;
    35 
    36         if (count == 0) {
    37                 return false;
    38         }
    39 
    40         ptr = req->in.hdr + offset;
    41        
    42         /* be careful with wraparound! */
    43         if ((uintptr_t)ptr < (uintptr_t)req->in.data ||
    44             (uintptr_t)ptr >= (uintptr_t)req->in.data + req->in.data_size ||
    45             count > req->in.data_size ||
    46             (uintptr_t)ptr + count > (uintptr_t)req->in.data + req->in.data_size) {
    47                 return true;
    48         }
    49         return false;   
    50 }
    51 
    52 static size_t raw_trans_space_left(struct smbcli_request *req)
    53 {
    54         if (req->transport->negotiate.max_xmit <= req->out.size) {
    55                 return 0;
    56         }
    57 
    58         return req->transport->negotiate.max_xmit - req->out.size;
    59 }
    60 
    61 struct smb_raw_trans2_recv_state {
    62         uint8_t command;
    63         uint32_t params_total;
    64         uint32_t data_total;
    65         uint32_t params_left;
    66         uint32_t data_left;
    67         bool got_first;
    68         uint32_t recvd_data;
    69         uint32_t recvd_param;
    70         struct smb_trans2 io;
    71 };
     25#include "../libcli/smb/smbXcli_base.h"
     26
     27static void smb_raw_trans_backend_done(struct tevent_req *subreq);
     28
     29static struct smbcli_request *smb_raw_trans_backend_send(struct smbcli_tree *tree,
     30                                                         struct smb_trans2 *parms,
     31                                                         uint8_t command)
     32{
     33        struct smbcli_request *req;
     34        uint8_t additional_flags;
     35        uint8_t clear_flags;
     36        uint16_t additional_flags2;
     37        uint16_t clear_flags2;
     38        uint32_t pid;
     39        struct smbXcli_tcon *tcon = NULL;
     40        struct smbXcli_session *session = NULL;
     41        const char *pipe_name = NULL;
     42        uint8_t s;
     43        uint32_t timeout_msec;
     44        uint32_t tmp;
     45
     46        tmp = parms->in.params.length + parms->in.data.length;
     47
     48        req = smbcli_request_setup(tree, command, parms->in.setup_count, tmp);
     49        if (req == NULL) {
     50                return NULL;
     51        }
     52
     53        additional_flags = CVAL(req->out.hdr, HDR_FLG);
     54        additional_flags2 = SVAL(req->out.hdr, HDR_FLG2);
     55        pid  = SVAL(req->out.hdr, HDR_PID);
     56        pid |= SVAL(req->out.hdr, HDR_PIDHIGH)<<16;
     57
     58        if (req->session) {
     59                session = req->session->smbXcli;
     60        }
     61
     62        if (req->tree) {
     63                tcon = req->tree->smbXcli;
     64        }
     65
     66        clear_flags = ~additional_flags;
     67        clear_flags2 = ~additional_flags2;
     68
     69        timeout_msec = req->transport->options.request_timeout * 1000;
     70
     71        for (s=0; s < parms->in.setup_count; s++) {
     72                SSVAL(req->out.vwv, VWV(s), parms->in.setup[s]);
     73        }
     74
     75        memcpy(req->out.data,
     76               parms->in.params.data,
     77               parms->in.params.length);
     78        memcpy(req->out.data + parms->in.params.length,
     79               parms->in.data.data,
     80               parms->in.data.length);
     81
     82        if (command == SMBtrans && parms->in.trans_name) {
     83                pipe_name = parms->in.trans_name;
     84        }
     85
     86        req->subreqs[0] = smb1cli_trans_send(req,
     87                                             req->transport->ev,
     88                                             req->transport->conn,
     89                                             command,
     90                                             additional_flags,
     91                                             clear_flags,
     92                                             additional_flags2,
     93                                             clear_flags2,
     94                                             timeout_msec,
     95                                             pid,
     96                                             tcon,
     97                                             session,
     98                                             pipe_name,
     99                                             0xFFFF, /* fid */
     100                                             0, /* function */
     101                                             parms->in.flags,
     102                                             (uint16_t *)req->out.vwv,
     103                                             parms->in.setup_count,
     104                                             parms->in.max_setup,
     105                                             req->out.data,
     106                                             parms->in.params.length,
     107                                             parms->in.max_param,
     108                                             req->out.data+
     109                                             parms->in.params.length,
     110                                             parms->in.data.length,
     111                                             parms->in.max_data);
     112        if (req->subreqs[0] == NULL) {
     113                talloc_free(req);
     114                return NULL;
     115        }
     116        tevent_req_set_callback(req->subreqs[0],
     117                                smb_raw_trans_backend_done,
     118                                req);
     119
     120        return req;
     121}
     122
     123static void smb_raw_trans_backend_done(struct tevent_req *subreq)
     124{
     125        struct smbcli_request *req =
     126                tevent_req_callback_data(subreq,
     127                struct smbcli_request);
     128        struct smbcli_transport *transport = req->transport;
     129        uint16_t *setup = NULL;
     130        uint8_t num_setup = 0;
     131        uint8_t s;
     132        uint8_t *param = NULL;
     133        uint32_t num_param = 0;
     134        uint8_t *data = NULL;
     135        uint32_t num_data = 0;
     136
     137        req->status = smb1cli_trans_recv(req->subreqs[0], req,
     138                                         &req->flags2,
     139                                         &setup,
     140                                         0, /* min_setup */
     141                                         &num_setup,
     142                                         &param,
     143                                         0, /* min_param */
     144                                         &num_param,
     145                                         &data,
     146                                         0, /* min_data */
     147                                         &num_data);
     148        TALLOC_FREE(req->subreqs[0]);
     149        if (NT_STATUS_IS_ERR(req->status)) {
     150                req->state = SMBCLI_REQUEST_ERROR;
     151                transport->error.e.nt_status = req->status;
     152                transport->error.etype = ETYPE_SMB;
     153                if (req->async.fn) {
     154                        req->async.fn(req);
     155                }
     156                return;
     157        }
     158
     159        req->trans2.out.setup_count = num_setup;
     160        req->trans2.out.setup = talloc_array(req, uint16_t, num_setup);
     161        if (req->trans2.out.setup == NULL) {
     162                req->state = SMBCLI_REQUEST_ERROR;
     163                req->status = NT_STATUS_NO_MEMORY;
     164                transport->error.e.nt_status = req->status;
     165                transport->error.etype = ETYPE_SMB;
     166                if (req->async.fn) {
     167                        req->async.fn(req);
     168                }
     169                return;
     170        }
     171        for (s = 0; s < num_setup; s++) {
     172                req->trans2.out.setup[s] = SVAL(setup, VWV(s));
     173        }
     174
     175        req->trans2.out.params.data = param;
     176        req->trans2.out.params.length = num_param;
     177
     178        req->trans2.out.data.data = data;
     179        req->trans2.out.data.length = num_data;
     180
     181        transport->error.e.nt_status = req->status;
     182        if (NT_STATUS_IS_OK(req->status)) {
     183                transport->error.etype = ETYPE_NONE;
     184        } else {
     185                transport->error.etype = ETYPE_SMB;
     186        }
     187
     188        req->state = SMBCLI_REQUEST_DONE;
     189        if (req->async.fn) {
     190                req->async.fn(req);
     191        }
     192}
     193
     194static NTSTATUS smb_raw_trans_backend_recv(struct smbcli_request *req,
     195                                           TALLOC_CTX *mem_ctx,
     196                                           struct smb_trans2 *parms)
     197{
     198        if (!smbcli_request_receive(req) ||
     199            smbcli_request_is_error(req)) {
     200                goto failed;
     201        }
     202
     203        parms->out = req->trans2.out;
     204        talloc_steal(mem_ctx, parms->out.setup);
     205        talloc_steal(mem_ctx, parms->out.params.data);
     206        talloc_steal(mem_ctx, parms->out.data.data);
     207
     208failed:
     209        return smbcli_request_destroy(req);
     210}
     211
     212_PUBLIC_ struct smbcli_request *smb_raw_trans_send(struct smbcli_tree *tree,
     213                                       struct smb_trans2 *parms)
     214{
     215        return smb_raw_trans_backend_send(tree, parms, SMBtrans);
     216}
     217
     218_PUBLIC_ NTSTATUS smb_raw_trans_recv(struct smbcli_request *req,
     219                             TALLOC_CTX *mem_ctx,
     220                             struct smb_trans2 *parms)
     221{
     222        return smb_raw_trans_backend_recv(req, mem_ctx, parms);
     223}
     224
     225_PUBLIC_ NTSTATUS smb_raw_trans(struct smbcli_tree *tree,
     226                       TALLOC_CTX *mem_ctx,
     227                       struct smb_trans2 *parms)
     228{
     229        struct smbcli_request *req;
     230        req = smb_raw_trans_send(tree, parms);
     231        if (!req) return NT_STATUS_UNSUCCESSFUL;
     232        return smb_raw_trans_recv(req, mem_ctx, parms);
     233}
     234
     235struct smbcli_request *smb_raw_trans2_send(struct smbcli_tree *tree,
     236                                       struct smb_trans2 *parms)
     237{
     238        return smb_raw_trans_backend_send(tree, parms, SMBtrans2);
     239}
    72240
    73241NTSTATUS smb_raw_trans2_recv(struct smbcli_request *req,
     
    75243                             struct smb_trans2 *parms)
    76244{
    77         struct smb_raw_trans2_recv_state *state;
    78 
    79         if (!smbcli_request_receive(req) ||
    80             smbcli_request_is_error(req)) {
    81                 goto failed;
    82         }
    83 
    84         state = talloc_get_type(req->recv_helper.private_data,
    85                                 struct smb_raw_trans2_recv_state);
    86 
    87         parms->out = state->io.out;
    88         talloc_steal(mem_ctx, parms->out.setup);
    89         talloc_steal(mem_ctx, parms->out.params.data);
    90         talloc_steal(mem_ctx, parms->out.data.data);
    91         talloc_free(state);
    92 
    93         ZERO_STRUCT(req->recv_helper);
    94 
    95 failed:
    96         return smbcli_request_destroy(req);
    97 }
    98 
    99 static enum smbcli_request_state smb_raw_trans2_ship_rest(struct smbcli_request *req,
    100                                                           struct smb_raw_trans2_recv_state *state);
    101 
    102 /*
    103  * This helper returns SMBCLI_REQUEST_RECV until all data has arrived
    104  */
    105 static enum smbcli_request_state smb_raw_trans2_recv_helper(struct smbcli_request *req)
    106 {
    107         struct smb_raw_trans2_recv_state *state = talloc_get_type(req->recv_helper.private_data,
    108                                                   struct smb_raw_trans2_recv_state);
    109         uint16_t param_count, param_ofs, param_disp;
    110         uint16_t data_count, data_ofs, data_disp;
    111         uint16_t total_data, total_param;
    112         uint8_t setup_count;
    113 
    114         /*
    115          * An NT RPC pipe call can return ERRDOS, ERRmoredata
    116          * to a trans call. This is not an error and should not
    117          * be treated as such.
    118          */
    119         if (smbcli_request_is_error(req)) {
    120                 goto failed;
    121         }
    122 
    123         if (state->params_left > 0 || state->data_left > 0) {
    124                 return smb_raw_trans2_ship_rest(req, state);
    125         }
    126 
    127         SMBCLI_CHECK_MIN_WCT(req, 10);
    128 
    129         total_data = SVAL(req->in.vwv, VWV(1));
    130         total_param = SVAL(req->in.vwv, VWV(0));
    131         setup_count = CVAL(req->in.vwv, VWV(9));
    132 
    133         param_count = SVAL(req->in.vwv, VWV(3));
    134         param_ofs   = SVAL(req->in.vwv, VWV(4));
    135         param_disp  = SVAL(req->in.vwv, VWV(5));
    136 
    137         data_count = SVAL(req->in.vwv, VWV(6));
    138         data_ofs   = SVAL(req->in.vwv, VWV(7));
    139         data_disp  = SVAL(req->in.vwv, VWV(8));
    140 
    141         if (!state->got_first) {
    142                 if (total_param > 0) {
    143                         state->io.out.params = data_blob_talloc(state, NULL, total_param);
    144                         if (!state->io.out.params.data) {
    145                                 goto nomem;
    146                         }
    147                 }
    148 
    149                 if (total_data > 0) {
    150                         state->io.out.data = data_blob_talloc(state, NULL, total_data);
    151                         if (!state->io.out.data.data) {
    152                                 goto nomem;
    153                         }
    154                 }
    155 
    156                 if (setup_count > 0) {
    157                         uint16_t i;
    158 
    159                         SMBCLI_CHECK_WCT(req, 10 + setup_count);
    160 
    161                         state->io.out.setup_count = setup_count;
    162                         state->io.out.setup = talloc_array(state, uint16_t, setup_count);
    163                         if (!state->io.out.setup) {
    164                                 goto nomem;
    165                         }
    166                         for (i=0; i < setup_count; i++) {
    167                                 state->io.out.setup[i] = SVAL(req->in.vwv, VWV(10+i));
    168                         }
    169                 }
    170 
    171                 state->got_first = true;
    172         }
    173 
    174         if (total_data > state->io.out.data.length ||
    175             total_param > state->io.out.params.length) {
    176                 /* they must *only* shrink */
    177                 DEBUG(1,("smb_raw_trans2_recv_helper: data/params expanded!\n"));
    178                 req->status = NT_STATUS_BUFFER_TOO_SMALL;
    179                 goto failed;
    180         }
    181 
    182         state->io.out.data.length = total_data;
    183         state->io.out.params.length = total_param;
    184 
    185         if (data_count + data_disp > total_data ||
    186             param_count + param_disp > total_param) {
    187                 DEBUG(1,("smb_raw_trans2_recv_helper: Buffer overflow\n"));
    188                 req->status = NT_STATUS_BUFFER_TOO_SMALL;
    189                 goto failed;
    190         }
    191 
    192         /* check the server isn't being nasty */
    193         if (raw_trans_oob(req, param_ofs, param_count) ||
    194             raw_trans_oob(req, data_ofs, data_count)) {
    195                 DEBUG(1,("smb_raw_trans2_recv_helper: out of bounds parameters!\n"));
    196                 req->status = NT_STATUS_BUFFER_TOO_SMALL;
    197                 goto failed;
    198         }
    199 
    200         if (data_count) {
    201                 memcpy(state->io.out.data.data + data_disp,
    202                        req->in.hdr + data_ofs,
    203                        data_count);
    204         }
    205 
    206         if (param_count) {
    207                 memcpy(state->io.out.params.data + param_disp,
    208                        req->in.hdr + param_ofs,
    209                        param_count);
    210         }
    211 
    212         state->recvd_param += param_count;
    213         state->recvd_data += data_count;
    214 
    215         if (state->recvd_data < total_data ||
    216             state->recvd_param < total_param) {
    217 
    218                 /* we don't need the in buffer any more */
    219                 talloc_free(req->in.buffer);
    220                 ZERO_STRUCT(req->in);
    221 
    222                 /* we still wait for more data */
    223                 DEBUG(10,("smb_raw_trans2_recv_helper: more data needed\n"));
    224                 return SMBCLI_REQUEST_RECV;
    225         }
    226 
    227         DEBUG(10,("smb_raw_trans2_recv_helper: done\n"));
    228         return SMBCLI_REQUEST_DONE;
    229 
    230 nomem:
    231         req->status = NT_STATUS_NO_MEMORY;
    232 failed:
    233         return SMBCLI_REQUEST_ERROR;
    234 }
    235 
    236 _PUBLIC_ NTSTATUS smb_raw_trans_recv(struct smbcli_request *req,
    237                              TALLOC_CTX *mem_ctx,
    238                              struct smb_trans2 *parms)
    239 {
    240         return smb_raw_trans2_recv(req, mem_ctx, parms);
    241 }
    242 
    243 
    244 /*
    245   trans/trans2 raw async interface - only BLOBs used in this interface.
    246 */
    247 struct smbcli_request *smb_raw_trans_send_backend(struct smbcli_tree *tree,
    248                                                   struct smb_trans2 *parms,
    249                                                   uint8_t command)
    250 {
    251         struct smb_raw_trans2_recv_state *state;
    252         struct smbcli_request *req;
    253         int i;
    254         int padding;
    255         size_t space_left;
    256         size_t namelen = 0;
    257         DATA_BLOB params_chunk;
    258         uint16_t ofs;
    259         uint16_t params_ofs = 0;
    260         DATA_BLOB data_chunk;
    261         uint16_t data_ofs = 0;
    262 
    263         if (parms->in.params.length > UINT16_MAX ||
    264             parms->in.data.length > UINT16_MAX) {
    265                 DEBUG(3,("Attempt to send invalid trans2 request (params %u, data %u)\n",
    266                          (unsigned)parms->in.params.length, (unsigned)parms->in.data.length));
    267                 return NULL;
    268         }
    269            
    270 
    271         if (command == SMBtrans)
    272                 padding = 1;
    273         else
    274                 padding = 3;
    275        
    276         req = smbcli_request_setup(tree, command,
    277                                    14 + parms->in.setup_count,
    278                                    padding);
    279         if (!req) {
    280                 return NULL;
    281         }
    282 
    283         state = talloc_zero(req, struct smb_raw_trans2_recv_state);
    284         if (!state) {
    285                 smbcli_request_destroy(req);
    286                 return NULL;
    287         }
    288 
    289         state->command = command;
    290 
    291         /* make sure we don't leak data via the padding */
    292         memset(req->out.data, 0, padding);
    293 
    294         /* Watch out, this changes the req->out.* pointers */
    295         if (command == SMBtrans && parms->in.trans_name) {
    296                 namelen = smbcli_req_append_string(req, parms->in.trans_name,
    297                                                 STR_TERMINATE);
    298         }
    299 
    300         ofs = PTR_DIFF(req->out.data,req->out.hdr)+padding+namelen;
    301 
    302         /* see how much bytes of the params block we can ship in the first request */
    303         space_left = raw_trans_space_left(req);
    304 
    305         params_chunk.length = MIN(parms->in.params.length, space_left);
    306         params_chunk.data = parms->in.params.data;
    307         params_ofs = ofs;
    308 
    309         state->params_left = parms->in.params.length - params_chunk.length;
    310 
    311         if (state->params_left > 0) {
    312                 /* we copy the whole params block, if needed we can optimize that latter */
    313                 state->io.in.params = data_blob_talloc(state, NULL, parms->in.params.length);
    314                 if (!state->io.in.params.data) {
    315                         smbcli_request_destroy(req);
    316                         return NULL;
    317                 }
    318                 memcpy(state->io.in.params.data,
    319                        parms->in.params.data,
    320                        parms->in.params.length);
    321         }
    322 
    323         /* see how much bytes of the data block we can ship in the first request */
    324         space_left -= params_chunk.length;
    325 
    326 #if TORTURE_TRANS_DATA
    327         if (space_left > 1) {
    328                 space_left /= 2;
    329         }
    330 #endif
    331 
    332         data_chunk.length = MIN(parms->in.data.length, space_left);
    333         data_chunk.data = parms->in.data.data;
    334         data_ofs = params_ofs + params_chunk.length;
    335 
    336         state->data_left = parms->in.data.length - data_chunk.length;
    337 
    338         if (state->data_left > 0) {
    339                 /* we copy the whole params block, if needed we can optimize that latter */
    340                 state->io.in.data = data_blob_talloc(state, NULL, parms->in.data.length);
    341                 if (!state->io.in.data.data) {
    342                         smbcli_request_destroy(req);
    343                         return NULL;
    344                 }
    345                 memcpy(state->io.in.data.data,
    346                        parms->in.data.data,
    347                        parms->in.data.length);
    348         }
    349 
    350         state->params_total = parms->in.params.length;
    351         state->data_total = parms->in.data.length;
    352 
    353         /* primary request */
    354         SSVAL(req->out.vwv,VWV(0),parms->in.params.length);
    355         SSVAL(req->out.vwv,VWV(1),parms->in.data.length);
    356         SSVAL(req->out.vwv,VWV(2),parms->in.max_param);
    357         SSVAL(req->out.vwv,VWV(3),parms->in.max_data);
    358         SCVAL(req->out.vwv,VWV(4),parms->in.max_setup);
    359         SCVAL(req->out.vwv,VWV(4)+1,0); /* reserved */
    360         SSVAL(req->out.vwv,VWV(5),parms->in.flags);
    361         SIVAL(req->out.vwv,VWV(6),parms->in.timeout);
    362         SSVAL(req->out.vwv,VWV(8),0); /* reserved */
    363         SSVAL(req->out.vwv,VWV(9),params_chunk.length);
    364         SSVAL(req->out.vwv,VWV(10),params_ofs);
    365         SSVAL(req->out.vwv,VWV(11),data_chunk.length);
    366         SSVAL(req->out.vwv,VWV(12),data_ofs);
    367         SCVAL(req->out.vwv,VWV(13),parms->in.setup_count);
    368         SCVAL(req->out.vwv,VWV(13)+1,0); /* reserved */
    369         for (i=0;i<parms->in.setup_count;i++)   {
    370                 SSVAL(req->out.vwv,VWV(14)+VWV(i),parms->in.setup[i]);
    371         }
    372         smbcli_req_append_blob(req, &params_chunk);
    373         smbcli_req_append_blob(req, &data_chunk);
    374 
    375         /* add the helper which will check that all multi-part replies are
    376            in before an async client callack will be issued */
    377         req->recv_helper.fn = smb_raw_trans2_recv_helper;
    378         req->recv_helper.private_data = state;
    379 
    380         if (!smbcli_request_send(req)) {
    381                 smbcli_request_destroy(req);
    382                 return NULL;
    383         }
    384 
    385         return req;
    386 }
    387 
    388 static enum smbcli_request_state smb_raw_trans2_ship_next(struct smbcli_request *req,
    389                                                           struct smb_raw_trans2_recv_state *state)
    390 {
    391         struct smbcli_request *req2;
    392         size_t space_left;
    393         DATA_BLOB params_chunk;
    394         uint16_t ofs;
    395         uint16_t params_ofs = 0;
    396         uint16_t params_disp = 0;
    397         DATA_BLOB data_chunk;
    398         uint16_t data_ofs = 0;
    399         uint16_t data_disp = 0;
    400         uint8_t wct;
    401 
    402         if (state->command == SMBtrans2) {
    403                 wct = 9;
    404         } else {
    405                 wct = 8;
    406         }
    407 
    408         req2 = smbcli_request_setup(req->tree, state->command+1, wct, 0);
    409         if (!req2) {
    410                 goto nomem;
    411         }
    412         req2->mid = req->mid;
    413         SSVAL(req2->out.hdr, HDR_MID, req2->mid);
    414 
    415         ofs = PTR_DIFF(req2->out.data,req2->out.hdr);
    416 
    417         /* see how much bytes of the params block we can ship in the first request */
    418         space_left = raw_trans_space_left(req2);
    419 
    420         params_disp = state->io.in.params.length - state->params_left;
    421         params_chunk.length = MIN(state->params_left, space_left);
    422         params_chunk.data = state->io.in.params.data + params_disp;
    423         params_ofs = ofs;
    424 
    425         state->params_left -= params_chunk.length;
    426 
    427         /* see how much bytes of the data block we can ship in the first request */
    428         space_left -= params_chunk.length;
    429 
    430 #if TORTURE_TRANS_DATA
    431         if (space_left > 1) {
    432                 space_left /= 2;
    433         }
    434 #endif
    435 
    436         data_disp = state->io.in.data.length - state->data_left;
    437         data_chunk.length = MIN(state->data_left, space_left);
    438         data_chunk.data = state->io.in.data.data + data_disp;
    439         data_ofs = params_ofs+params_chunk.length;
    440 
    441         state->data_left -= data_chunk.length;
    442 
    443         SSVAL(req2->out.vwv,VWV(0), state->params_total);
    444         SSVAL(req2->out.vwv,VWV(1), state->data_total);
    445         SSVAL(req2->out.vwv,VWV(2), params_chunk.length);
    446         SSVAL(req2->out.vwv,VWV(3), params_ofs);
    447         SSVAL(req2->out.vwv,VWV(4), params_disp);
    448         SSVAL(req2->out.vwv,VWV(5), data_chunk.length);
    449         SSVAL(req2->out.vwv,VWV(6), data_ofs);
    450         SSVAL(req2->out.vwv,VWV(7), data_disp);
    451         if (wct == 9) {
    452                 SSVAL(req2->out.vwv,VWV(8), 0xFFFF);
    453         }
    454 
    455         smbcli_req_append_blob(req2, &params_chunk);
    456         smbcli_req_append_blob(req2, &data_chunk);
    457 
    458         /*
    459          * it's a one way request but we need
    460          * the seq_num, so we destroy req2 by hand
    461          */
    462         if (!smbcli_request_send(req2)) {
    463                 goto failed;
    464         }
    465 
    466         req->seq_num = req2->seq_num;
    467         smbcli_request_destroy(req2);
    468 
    469         return SMBCLI_REQUEST_RECV;
    470 
    471 nomem:
    472         req->status = NT_STATUS_NO_MEMORY;
    473 failed:
    474         if (req2) {
    475                 req->status = smbcli_request_destroy(req2);
    476         }
    477         return SMBCLI_REQUEST_ERROR;
    478 }
    479 
    480 static enum smbcli_request_state smb_raw_trans2_ship_rest(struct smbcli_request *req,
    481                                                           struct smb_raw_trans2_recv_state *state)
    482 {
    483         enum smbcli_request_state ret = SMBCLI_REQUEST_ERROR;
    484 
    485         while (state->params_left > 0 || state->data_left > 0) {
    486                 ret = smb_raw_trans2_ship_next(req, state);
    487                 if (ret != SMBCLI_REQUEST_RECV) {
    488                         break;
    489                 }
    490         }
    491 
    492         return ret;
    493 }
    494 
    495 
    496 /*
    497   trans/trans2 raw async interface - only BLOBs used in this interface.
    498   note that this doesn't yet support multi-part requests
    499 */
    500 _PUBLIC_ struct smbcli_request *smb_raw_trans_send(struct smbcli_tree *tree,
    501                                        struct smb_trans2 *parms)
    502 {
    503         return smb_raw_trans_send_backend(tree, parms, SMBtrans);
    504 }
    505 
    506 struct smbcli_request *smb_raw_trans2_send(struct smbcli_tree *tree,
    507                                        struct smb_trans2 *parms)
    508 {
    509         return smb_raw_trans_send_backend(tree, parms, SMBtrans2);
    510 }
    511 
    512 /*
    513   trans2 synchronous blob interface
    514 */
     245        return smb_raw_trans_backend_recv(req, mem_ctx, parms);
     246}
     247
    515248NTSTATUS smb_raw_trans2(struct smbcli_tree *tree,
    516249                        TALLOC_CTX *mem_ctx,
     
    523256}
    524257
    525 
    526 /*
    527   trans synchronous blob interface
    528 */
    529 _PUBLIC_ NTSTATUS smb_raw_trans(struct smbcli_tree *tree,
    530                        TALLOC_CTX *mem_ctx,
    531                        struct smb_trans2 *parms)
     258static void smb_raw_nttrans_done(struct tevent_req *subreq);
     259
     260struct smbcli_request *smb_raw_nttrans_send(struct smbcli_tree *tree,
     261                                            struct smb_nttrans *parms)
    532262{
    533263        struct smbcli_request *req;
    534         req = smb_raw_trans_send(tree, parms);
    535         if (!req) return NT_STATUS_UNSUCCESSFUL;
    536         return smb_raw_trans_recv(req, mem_ctx, parms);
    537 }
    538 
    539 struct smb_raw_nttrans_recv_state {
    540         uint32_t params_total;
    541         uint32_t data_total;
    542         uint32_t params_left;
    543         uint32_t data_left;
    544         bool got_first;
    545         uint32_t recvd_data;
    546         uint32_t recvd_param;
    547         struct smb_nttrans io;
    548 };
     264        uint8_t additional_flags;
     265        uint8_t clear_flags;
     266        uint16_t additional_flags2;
     267        uint16_t clear_flags2;
     268        uint32_t pid;
     269        struct smbXcli_tcon *tcon = NULL;
     270        struct smbXcli_session *session = NULL;
     271        uint32_t timeout_msec;
     272        uint32_t tmp;
     273
     274        tmp = parms->in.params.length + parms->in.data.length;
     275
     276        req = smbcli_request_setup(tree, SMBnttrans, parms->in.setup_count, tmp);
     277        if (req == NULL) {
     278                return NULL;
     279        }
     280
     281        additional_flags = CVAL(req->out.hdr, HDR_FLG);
     282        additional_flags2 = SVAL(req->out.hdr, HDR_FLG2);
     283        pid  = SVAL(req->out.hdr, HDR_PID);
     284        pid |= SVAL(req->out.hdr, HDR_PIDHIGH)<<16;
     285
     286        if (req->session) {
     287                session = req->session->smbXcli;
     288        }
     289
     290        if (req->tree) {
     291                tcon = req->tree->smbXcli;
     292        }
     293
     294        clear_flags = ~additional_flags;
     295        clear_flags2 = ~additional_flags2;
     296
     297        timeout_msec = req->transport->options.request_timeout * 1000;
     298
     299        memcpy(req->out.vwv,
     300               parms->in.setup,
     301               parms->in.setup_count * 2);
     302
     303        memcpy(req->out.data,
     304               parms->in.params.data,
     305               parms->in.params.length);
     306        memcpy(req->out.data + parms->in.params.length,
     307               parms->in.data.data,
     308               parms->in.data.length);
     309
     310        req->subreqs[0] = smb1cli_trans_send(req,
     311                                             req->transport->ev,
     312                                             req->transport->conn,
     313                                             SMBnttrans,
     314                                             additional_flags,
     315                                             clear_flags,
     316                                             additional_flags2,
     317                                             clear_flags2,
     318                                             timeout_msec,
     319                                             pid,
     320                                             tcon,
     321                                             session,
     322                                             NULL, /* pipe_name */
     323                                             0xFFFF, /* fid */
     324                                             parms->in.function,
     325                                             0, /* flags */
     326                                             (uint16_t *)req->out.vwv,
     327                                             parms->in.setup_count,
     328                                             parms->in.max_setup,
     329                                             req->out.data,
     330                                             parms->in.params.length,
     331                                             parms->in.max_param,
     332                                             req->out.data+
     333                                             parms->in.params.length,
     334                                             parms->in.data.length,
     335                                             parms->in.max_data);
     336        if (req->subreqs[0] == NULL) {
     337                talloc_free(req);
     338                return NULL;
     339        }
     340        tevent_req_set_callback(req->subreqs[0],
     341                                smb_raw_nttrans_done,
     342                                req);
     343
     344        return req;
     345}
     346
     347static void smb_raw_nttrans_done(struct tevent_req *subreq)
     348{
     349        struct smbcli_request *req =
     350                tevent_req_callback_data(subreq,
     351                struct smbcli_request);
     352        struct smbcli_transport *transport = req->transport;
     353        uint16_t *setup = NULL;
     354        uint8_t num_setup = 0;
     355        uint8_t *param = NULL;
     356        uint32_t num_param = 0;
     357        uint8_t *data = NULL;
     358        uint32_t num_data = 0;
     359
     360        req->status = smb1cli_trans_recv(req->subreqs[0], req,
     361                                         &req->flags2,
     362                                         &setup,
     363                                         0, /* min_setup */
     364                                         &num_setup,
     365                                         &param,
     366                                         0, /* min_param */
     367                                         &num_param,
     368                                         &data,
     369                                         0, /* min_data */
     370                                         &num_data);
     371        TALLOC_FREE(req->subreqs[0]);
     372        if (NT_STATUS_IS_ERR(req->status)) {
     373                req->state = SMBCLI_REQUEST_ERROR;
     374                transport->error.e.nt_status = req->status;
     375                transport->error.etype = ETYPE_SMB;
     376                if (req->async.fn) {
     377                        req->async.fn(req);
     378                }
     379                return;
     380        }
     381
     382        req->nttrans.out.setup_count = num_setup;
     383        req->nttrans.out.setup = (uint8_t *)setup;
     384
     385        req->nttrans.out.params.data = param;
     386        req->nttrans.out.params.length = num_param;
     387
     388        req->nttrans.out.data.data = data;
     389        req->nttrans.out.data.length = num_data;
     390
     391        transport->error.e.nt_status = req->status;
     392        if (NT_STATUS_IS_OK(req->status)) {
     393                transport->error.etype = ETYPE_NONE;
     394        } else {
     395                transport->error.etype = ETYPE_SMB;
     396        }
     397
     398        req->state = SMBCLI_REQUEST_DONE;
     399        if (req->async.fn) {
     400                req->async.fn(req);
     401        }
     402}
    549403
    550404NTSTATUS smb_raw_nttrans_recv(struct smbcli_request *req,
     
    552406                              struct smb_nttrans *parms)
    553407{
    554         struct smb_raw_nttrans_recv_state *state;
    555 
    556408        if (!smbcli_request_receive(req) ||
    557409            smbcli_request_is_error(req)) {
     
    559411        }
    560412
    561         state = talloc_get_type(req->recv_helper.private_data,
    562                                 struct smb_raw_nttrans_recv_state);
    563 
    564         parms->out = state->io.out;
     413        parms->out = req->nttrans.out;
    565414        talloc_steal(mem_ctx, parms->out.setup);
    566415        talloc_steal(mem_ctx, parms->out.params.data);
    567416        talloc_steal(mem_ctx, parms->out.data.data);
    568         talloc_free(state);
    569 
    570         ZERO_STRUCT(req->recv_helper);
    571417
    572418failed:
    573419        return smbcli_request_destroy(req);
    574420}
    575 
    576 static enum smbcli_request_state smb_raw_nttrans_ship_rest(struct smbcli_request *req,
    577                                                            struct smb_raw_nttrans_recv_state *state);
    578 
    579 /*
    580  * This helper returns SMBCLI_REQUEST_RECV until all data has arrived
    581  */
    582 static enum smbcli_request_state smb_raw_nttrans_recv_helper(struct smbcli_request *req)
    583 {
    584         struct smb_raw_nttrans_recv_state *state = talloc_get_type(req->recv_helper.private_data,
    585                                                    struct smb_raw_nttrans_recv_state);
    586         uint32_t param_count, param_ofs, param_disp;
    587         uint32_t data_count, data_ofs, data_disp;
    588         uint32_t total_data, total_param;
    589         uint8_t setup_count;
    590 
    591         /*
    592          * An NT RPC pipe call can return ERRDOS, ERRmoredata
    593          * to a trans call. This is not an error and should not
    594          * be treated as such.
    595          */
    596         if (smbcli_request_is_error(req)) {
    597                 goto failed;
    598         }
    599 
    600         /* sanity check */
    601         if (CVAL(req->in.hdr, HDR_COM) != SMBnttrans) {
    602                 DEBUG(0,("smb_raw_nttrans_recv_helper: Expected %s response, got command 0x%02x\n",
    603                          "SMBnttrans",
    604                          CVAL(req->in.hdr,HDR_COM)));
    605                 req->status = NT_STATUS_INVALID_NETWORK_RESPONSE;
    606                 goto failed;
    607         }
    608 
    609         if (state->params_left > 0 || state->data_left > 0) {
    610                 return smb_raw_nttrans_ship_rest(req, state);
    611         }
    612 
    613         /* this is the first packet of the response */
    614         SMBCLI_CHECK_MIN_WCT(req, 18);
    615 
    616         total_param = IVAL(req->in.vwv, 3);
    617         total_data  = IVAL(req->in.vwv, 7);
    618         setup_count = CVAL(req->in.vwv, 35);
    619 
    620         param_count = IVAL(req->in.vwv, 11);
    621         param_ofs   = IVAL(req->in.vwv, 15);
    622         param_disp  = IVAL(req->in.vwv, 19);
    623 
    624         data_count = IVAL(req->in.vwv, 23);
    625         data_ofs   = IVAL(req->in.vwv, 27);
    626         data_disp  = IVAL(req->in.vwv, 31);
    627 
    628         if (!state->got_first) {
    629                 if (total_param > 0) {
    630                         state->io.out.params = data_blob_talloc(state, NULL, total_param);
    631                         if (!state->io.out.params.data) {
    632                                 goto nomem;
    633                         }
    634                 }
    635 
    636                 if (total_data > 0) {
    637                         state->io.out.data = data_blob_talloc(state, NULL, total_data);
    638                         if (!state->io.out.data.data) {
    639                                 goto nomem;
    640                         }
    641                 }
    642 
    643                 if (setup_count > 0) {
    644                         SMBCLI_CHECK_WCT(req, 18 + setup_count);
    645 
    646                         state->io.out.setup_count = setup_count;
    647                         state->io.out.setup = talloc_array(state, uint8_t,
    648                                                            setup_count * VWV(1));
    649                         if (!state->io.out.setup) {
    650                                 goto nomem;
    651                         }
    652                         memcpy(state->io.out.setup, (uint8_t *)req->out.vwv + VWV(18),
    653                                setup_count * VWV(1));
    654                 }
    655 
    656                 state->got_first = true;
    657         }
    658 
    659         if (total_data > state->io.out.data.length ||
    660             total_param > state->io.out.params.length) {
    661                 /* they must *only* shrink */
    662                 DEBUG(1,("smb_raw_nttrans_recv_helper: data/params expanded!\n"));
    663                 req->status = NT_STATUS_BUFFER_TOO_SMALL;
    664                 goto failed;
    665         }
    666 
    667         state->io.out.data.length = total_data;
    668         state->io.out.params.length = total_param;
    669 
    670         if (data_count + data_disp > total_data ||
    671             param_count + param_disp > total_param) {
    672                 DEBUG(1,("smb_raw_nttrans_recv_helper: Buffer overflow\n"));
    673                 req->status = NT_STATUS_BUFFER_TOO_SMALL;
    674                 goto failed;
    675         }
    676 
    677         /* check the server isn't being nasty */
    678         if (raw_trans_oob(req, param_ofs, param_count) ||
    679             raw_trans_oob(req, data_ofs, data_count)) {
    680                 DEBUG(1,("smb_raw_nttrans_recv_helper: out of bounds parameters!\n"));
    681                 req->status = NT_STATUS_BUFFER_TOO_SMALL;
    682                 goto failed;
    683         }
    684 
    685         if (data_count) {
    686                 memcpy(state->io.out.data.data + data_disp,
    687                        req->in.hdr + data_ofs,
    688                        data_count);
    689         }
    690 
    691         if (param_count) {
    692                 memcpy(state->io.out.params.data + param_disp,
    693                        req->in.hdr + param_ofs,
    694                        param_count);
    695         }
    696 
    697         state->recvd_param += param_count;
    698         state->recvd_data += data_count;
    699 
    700         if (state->recvd_data < total_data ||
    701             state->recvd_param < total_param) {
    702 
    703                 /* we don't need the in buffer any more */
    704                 talloc_free(req->in.buffer);
    705                 ZERO_STRUCT(req->in);
    706 
    707                 /* we still wait for more data */
    708                 DEBUG(10,("smb_raw_nttrans_recv_helper: more data needed\n"));
    709                 return SMBCLI_REQUEST_RECV;
    710         }
    711 
    712         DEBUG(10,("smb_raw_nttrans_recv_helper: done\n"));
    713         return SMBCLI_REQUEST_DONE;
    714 
    715 nomem:
    716         req->status = NT_STATUS_NO_MEMORY;
    717 failed:
    718         return SMBCLI_REQUEST_ERROR;
    719 }
    720 
    721 /****************************************************************************
    722  nttrans raw - only BLOBs used in this interface.
    723  at the moment we only handle a single primary request
    724 ****************************************************************************/
    725 struct smbcli_request *smb_raw_nttrans_send(struct smbcli_tree *tree,
    726                                          struct smb_nttrans *parms)
    727 {
    728         struct smbcli_request *req;
    729         struct smb_raw_nttrans_recv_state *state;
    730         uint32_t ofs;
    731         size_t space_left;
    732         DATA_BLOB params_chunk;
    733         uint32_t params_ofs;
    734         DATA_BLOB data_chunk;
    735         uint32_t data_ofs;
    736         int align = 0;
    737 
    738         /* only align if there are parameters or data */
    739         if (parms->in.params.length || parms->in.data.length) {
    740                 align = 3;
    741         }
    742        
    743         req = smbcli_request_setup(tree, SMBnttrans,
    744                                 19 + parms->in.setup_count, align);
    745         if (!req) {
    746                 return NULL;
    747         }
    748 
    749         state = talloc_zero(req, struct smb_raw_nttrans_recv_state);
    750         if (!state) {
    751                 talloc_free(req);
    752                 return NULL;
    753         }
    754 
    755         /* fill in SMB parameters */
    756 
    757         if (align != 0) {
    758                 memset(req->out.data, 0, align);
    759         }
    760 
    761         ofs = PTR_DIFF(req->out.data,req->out.hdr)+align;
    762 
    763         /* see how much bytes of the params block we can ship in the first request */
    764         space_left = raw_trans_space_left(req);
    765 
    766         params_chunk.length = MIN(parms->in.params.length, space_left);
    767         params_chunk.data = parms->in.params.data;
    768         params_ofs = ofs;
    769 
    770         state->params_left = parms->in.params.length - params_chunk.length;
    771 
    772         if (state->params_left > 0) {
    773                 /* we copy the whole params block, if needed we can optimize that latter */
    774                 state->io.in.params = data_blob_talloc(state, NULL, parms->in.params.length);
    775                 if (!state->io.in.params.data) {
    776                         smbcli_request_destroy(req);
    777                         return NULL;
    778                 }
    779                 memcpy(state->io.in.params.data,
    780                        parms->in.params.data,
    781                        parms->in.params.length);
    782         }
    783 
    784         /* see how much bytes of the data block we can ship in the first request */
    785         space_left -= params_chunk.length;
    786 
    787 #if TORTURE_TRANS_DATA
    788         if (space_left > 1) {
    789                 space_left /= 2;
    790         }
    791 #endif
    792 
    793         data_chunk.length = MIN(parms->in.data.length, space_left);
    794         data_chunk.data = parms->in.data.data;
    795         data_ofs = params_ofs + params_chunk.length;
    796 
    797         state->data_left = parms->in.data.length - data_chunk.length;
    798 
    799         if (state->data_left > 0) {
    800                 /* we copy the whole params block, if needed we can optimize that latter */
    801                 state->io.in.data = data_blob_talloc(state, NULL, parms->in.data.length);
    802                 if (!state->io.in.data.data) {
    803                         smbcli_request_destroy(req);
    804                         return NULL;
    805                 }
    806                 memcpy(state->io.in.data.data,
    807                        parms->in.data.data,
    808                        parms->in.data.length);
    809         }
    810 
    811         state->params_total = parms->in.params.length;
    812         state->data_total = parms->in.data.length;
    813 
    814         SCVAL(req->out.vwv,  0, parms->in.max_setup);
    815         SSVAL(req->out.vwv,  1, 0); /* reserved */
    816         SIVAL(req->out.vwv,  3, parms->in.params.length);
    817         SIVAL(req->out.vwv,  7, parms->in.data.length);
    818         SIVAL(req->out.vwv, 11, parms->in.max_param);
    819         SIVAL(req->out.vwv, 15, parms->in.max_data);
    820         SIVAL(req->out.vwv, 19, params_chunk.length);
    821         SIVAL(req->out.vwv, 23, params_ofs);
    822         SIVAL(req->out.vwv, 27, data_chunk.length);
    823         SIVAL(req->out.vwv, 31, data_ofs);
    824         SCVAL(req->out.vwv, 35, parms->in.setup_count);
    825         SSVAL(req->out.vwv, 36, parms->in.function);
    826         memcpy(req->out.vwv + VWV(19), parms->in.setup,
    827                sizeof(uint16_t) * parms->in.setup_count);
    828 
    829         smbcli_req_append_blob(req, &params_chunk);
    830         smbcli_req_append_blob(req, &data_chunk);
    831 
    832         /* add the helper which will check that all multi-part replies are
    833            in before an async client callack will be issued */
    834         req->recv_helper.fn = smb_raw_nttrans_recv_helper;
    835         req->recv_helper.private_data = state;
    836 
    837         if (!smbcli_request_send(req)) {
    838                 smbcli_request_destroy(req);
    839                 return NULL;
    840         }
    841 
    842         return req;
    843 }
    844 
    845 static enum smbcli_request_state smb_raw_nttrans_ship_next(struct smbcli_request *req,
    846                                                            struct smb_raw_nttrans_recv_state *state)
    847 {
    848         struct smbcli_request *req2;
    849         size_t space_left;
    850         DATA_BLOB params_chunk;
    851         uint32_t ofs;
    852         uint32_t params_ofs = 0;
    853         uint32_t params_disp = 0;
    854         DATA_BLOB data_chunk;
    855         uint32_t data_ofs = 0;
    856         uint32_t data_disp = 0;
    857 
    858         req2 = smbcli_request_setup(req->tree, SMBnttranss, 18, 0);
    859         if (!req2) {
    860                 goto nomem;
    861         }
    862         req2->mid = req->mid;
    863         SSVAL(req2->out.hdr, HDR_MID, req2->mid);
    864 
    865         ofs = PTR_DIFF(req2->out.data,req2->out.hdr);
    866 
    867         /* see how much bytes of the params block we can ship in the first request */
    868         space_left = raw_trans_space_left(req2);
    869 
    870         params_disp = state->io.in.params.length - state->params_left;
    871         params_chunk.length = MIN(state->params_left, space_left);
    872         params_chunk.data = state->io.in.params.data + params_disp;
    873         params_ofs = ofs;
    874 
    875         state->params_left -= params_chunk.length;
    876 
    877         /* see how much bytes of the data block we can ship in the first request */
    878         space_left -= params_chunk.length;
    879 
    880 #if TORTURE_TRANS_DATA
    881         if (space_left > 1) {
    882                 space_left /= 2;
    883         }
    884 #endif
    885 
    886         data_disp = state->io.in.data.length - state->data_left;
    887         data_chunk.length = MIN(state->data_left, space_left);
    888         data_chunk.data = state->io.in.data.data + data_disp;
    889         data_ofs = params_ofs+params_chunk.length;
    890 
    891         state->data_left -= data_chunk.length;
    892 
    893         SSVAL(req2->out.vwv,0, 0); /* reserved */
    894         SCVAL(req2->out.vwv,2, 0); /* reserved */
    895         SIVAL(req2->out.vwv,3, state->params_total);
    896         SIVAL(req2->out.vwv,7, state->data_total);
    897         SIVAL(req2->out.vwv,11, params_chunk.length);
    898         SIVAL(req2->out.vwv,15, params_ofs);
    899         SIVAL(req2->out.vwv,19, params_disp);
    900         SIVAL(req2->out.vwv,23, data_chunk.length);
    901         SIVAL(req2->out.vwv,27, data_ofs);
    902         SIVAL(req2->out.vwv,31, data_disp);
    903         SCVAL(req2->out.vwv,35, 0); /* reserved */
    904 
    905         smbcli_req_append_blob(req2, &params_chunk);
    906         smbcli_req_append_blob(req2, &data_chunk);
    907 
    908         /*
    909          * it's a one way request but we need
    910          * the seq_num, so we destroy req2 by hand
    911          */
    912         if (!smbcli_request_send(req2)) {
    913                 goto failed;
    914         }
    915 
    916         req->seq_num = req2->seq_num;
    917         smbcli_request_destroy(req2);
    918 
    919         return SMBCLI_REQUEST_RECV;
    920 
    921 nomem:
    922         req->status = NT_STATUS_NO_MEMORY;
    923 failed:
    924         if (req2) {
    925                 req->status = smbcli_request_destroy(req2);
    926         }
    927         return SMBCLI_REQUEST_ERROR;
    928 }
    929 
    930 static enum smbcli_request_state smb_raw_nttrans_ship_rest(struct smbcli_request *req,
    931                                                            struct smb_raw_nttrans_recv_state *state)
    932 {
    933         enum smbcli_request_state ret = SMBCLI_REQUEST_ERROR;
    934 
    935         while (state->params_left > 0 || state->data_left > 0) {
    936                 ret = smb_raw_nttrans_ship_next(req, state);
    937                 if (ret != SMBCLI_REQUEST_RECV) {
    938                         break;
    939                 }
    940         }
    941 
    942         return ret;
    943 }
    944 
    945421
    946422/****************************************************************************
  • vendor/current/source4/libcli/raw/signing.h

    r414 r988  
    2727};
    2828
    29 enum smb_signing_state {
    30         SMB_SIGNING_OFF, SMB_SIGNING_SUPPORTED,
    31         SMB_SIGNING_REQUIRED, SMB_SIGNING_AUTO};
    32 
    3329struct smb_signing_context {
    3430        enum smb_signing_engine_state signing_state;
  • vendor/current/source4/libcli/raw/smb.h

    r740 r988  
    2424*/
    2525
    26 #ifndef _SMB_H
    27 #define _SMB_H
     26#ifndef _RAW_SMB_H
     27#define _RAW_SMB_H
    2828
    2929/* deny modes */
     
    207207#define NTCREATEX_ACTION_UNKNOWN 5
    208208
    209 #define SMB_MAGIC 0x424D53FF /* 0xFF 'S' 'M' 'B' */
    210 
    211 /* the basic packet size, assuming no words or bytes. Does not include the NBT header */
    212 #define MIN_SMB_SIZE 35
    213 
    214 /* when using NBT encapsulation every packet has a 4 byte header */
    215 #define NBT_HDR_SIZE 4
    216 
    217 /* offsets into message header for common items - NOTE: These have
    218    changed from being offsets from the base of the NBT packet to the base of the SMB packet.
    219    this has reduced all these values by 4
    220 */
    221 #define HDR_COM 4
    222 #define HDR_RCLS 5
    223 #define HDR_REH 6
    224 #define HDR_ERR 7
    225 #define HDR_FLG 9
    226 #define HDR_FLG2 10
    227 #define HDR_PIDHIGH 12
    228 #define HDR_SS_FIELD 14
    229 #define HDR_TID 24
    230 #define HDR_PID 26
    231 #define HDR_UID 28
    232 #define HDR_MID 30
    233 #define HDR_WCT 32
    234 #define HDR_VWV 33
    235 
    236 
    237 /* types of buffers in core SMB protocol */
    238 #define SMB_DATA_BLOCK 0x1
    239 #define SMB_ASCII4     0x4
    240 
    241 
    242 /* flag defines. CIFS spec 3.1.1 */
    243 #define FLAG_SUPPORT_LOCKREAD       0x01
    244 #define FLAG_CLIENT_BUF_AVAIL       0x02
    245 #define FLAG_RESERVED               0x04
    246 #define FLAG_CASELESS_PATHNAMES     0x08
    247 #define FLAG_CANONICAL_PATHNAMES    0x10
    248 #define FLAG_REQUEST_OPLOCK         0x20
    249 #define FLAG_REQUEST_BATCH_OPLOCK   0x40
    250 #define FLAG_REPLY                  0x80
    251 
    252 /* the complete */
    253 #define SMBmkdir      0x00   /* create directory */
    254 #define SMBrmdir      0x01   /* delete directory */
    255 #define SMBopen       0x02   /* open file */
    256 #define SMBcreate     0x03   /* create file */
    257 #define SMBclose      0x04   /* close file */
    258 #define SMBflush      0x05   /* flush file */
    259 #define SMBunlink     0x06   /* delete file */
    260 #define SMBmv         0x07   /* rename file */
    261 #define SMBgetatr     0x08   /* get file attributes */
    262 #define SMBsetatr     0x09   /* set file attributes */
    263 #define SMBread       0x0A   /* read from file */
    264 #define SMBwrite      0x0B   /* write to file */
    265 #define SMBlock       0x0C   /* lock byte range */
    266 #define SMBunlock     0x0D   /* unlock byte range */
    267 #define SMBctemp      0x0E   /* create temporary file */
    268 #define SMBmknew      0x0F   /* make new file */
    269 #define SMBchkpth     0x10   /* check directory path */
    270 #define SMBexit       0x11   /* process exit */
    271 #define SMBlseek      0x12   /* seek */
    272 #define SMBtcon       0x70   /* tree connect */
    273 #define SMBtconX      0x75   /* tree connect and X*/
    274 #define SMBtdis       0x71   /* tree disconnect */
    275 #define SMBnegprot    0x72   /* negotiate protocol */
    276 #define SMBdskattr    0x80   /* get disk attributes */
    277 #define SMBsearch     0x81   /* search directory */
    278 #define SMBsplopen    0xC0   /* open print spool file */
    279 #define SMBsplwr      0xC1   /* write to print spool file */
    280 #define SMBsplclose   0xC2   /* close print spool file */
    281 #define SMBsplretq    0xC3   /* return print queue */
    282 #define SMBsends      0xD0   /* send single block message */
    283 #define SMBsendb      0xD1   /* send broadcast message */
    284 #define SMBfwdname    0xD2   /* forward user name */
    285 #define SMBcancelf    0xD3   /* cancel forward */
    286 #define SMBgetmac     0xD4   /* get machine name */
    287 #define SMBsendstrt   0xD5   /* send start of multi-block message */
    288 #define SMBsendend    0xD6   /* send end of multi-block message */
    289 #define SMBsendtxt    0xD7   /* send text of multi-block message */
    290 
    291 /* Core+ protocol */
    292 #define SMBlockread       0x13   /* Lock a range and read */
    293 #define SMBwriteunlock 0x14 /* write then range then unlock it */
    294 #define SMBreadbraw   0x1a  /* read a block of data with no smb header */
    295 #define SMBwritebraw  0x1d  /* write a block of data with no smb header */
    296 #define SMBwritec     0x20  /* secondary write request */
    297 #define SMBwriteclose 0x2c  /* write a file then close it */
    298 
    299 /* dos extended protocol */
    300 #define SMBreadBraw      0x1A   /* read block raw */
    301 #define SMBreadBmpx      0x1B   /* read block multiplexed */
    302 #define SMBreadBs        0x1C   /* read block (secondary response) */
    303 #define SMBwriteBraw     0x1D   /* write block raw */
    304 #define SMBwriteBmpx     0x1E   /* write block multiplexed */
    305 #define SMBwriteBs       0x1F   /* write block (secondary request) */
    306 #define SMBwriteC        0x20   /* write complete response */
    307 #define SMBsetattrE      0x22   /* set file attributes expanded */
    308 #define SMBgetattrE      0x23   /* get file attributes expanded */
    309 #define SMBlockingX      0x24   /* lock/unlock byte ranges and X */
    310 #define SMBtrans         0x25   /* transaction - name, bytes in/out */
    311 #define SMBtranss        0x26   /* transaction (secondary request/response) */
    312 #define SMBioctl         0x27   /* IOCTL */
    313 #define SMBioctls        0x28   /* IOCTL  (secondary request/response) */
    314 #define SMBcopy          0x29   /* copy */
    315 #define SMBmove          0x2A   /* move */
    316 #define SMBecho          0x2B   /* echo */
    317 #define SMBopenX         0x2D   /* open and X */
    318 #define SMBreadX         0x2E   /* read and X */
    319 #define SMBwriteX        0x2F   /* write and X */
    320 #define SMBsesssetupX    0x73   /* Session Set Up & X (including User Logon) */
    321 #define SMBffirst        0x82   /* find first */
    322 #define SMBfunique       0x83   /* find unique */
    323 #define SMBfclose        0x84   /* find close */
    324 #define SMBkeepalive     0x85   /* keepalive */
    325 #define SMBinvalid       0xFE   /* invalid command */
    326 
    327 /* Extended 2.0 protocol */
    328 #define SMBtrans2        0x32   /* TRANS2 protocol set */
    329 #define SMBtranss2       0x33   /* TRANS2 protocol set, secondary command */
    330 #define SMBfindclose     0x34   /* Terminate a TRANSACT2_FINDFIRST */
    331 #define SMBfindnclose    0x35   /* Terminate a TRANSACT2_FINDNOTIFYFIRST */
    332 #define SMBulogoffX      0x74   /* user logoff */
    333 
    334 /* NT SMB extensions. */
    335 #define SMBnttrans       0xA0   /* NT transact */
    336 #define SMBnttranss      0xA1   /* NT transact secondary */
    337 #define SMBntcreateX     0xA2   /* NT create and X */
    338 #define SMBntcancel      0xA4   /* NT cancel */
    339 #define SMBntrename      0xA5   /* NT rename */
    340 
    341 /* used to indicate end of chain */
    342 #define SMB_CHAIN_NONE   0xFF
    343 
    344 /* These are the trans subcommands */
    345 #define TRANSACT_SETNAMEDPIPEHANDLESTATE  0x01
    346 #define TRANSACT_DCERPCCMD                0x26
    347 #define TRANSACT_WAITNAMEDPIPEHANDLESTATE 0x53
    348 
    349 /* These are the NT transact sub commands. */
    350 #define NT_TRANSACT_CREATE                1
    351 #define NT_TRANSACT_IOCTL                 2
    352 #define NT_TRANSACT_SET_SECURITY_DESC     3
    353 #define NT_TRANSACT_NOTIFY_CHANGE         4
    354 #define NT_TRANSACT_RENAME                5
    355 #define NT_TRANSACT_QUERY_SECURITY_DESC   6
    356 
    357 /* this is used on a TConX. I'm not sure the name is very helpful though */
    358 #define SMB_SUPPORT_SEARCH_BITS        0x0001
    359 #define SMB_SHARE_IN_DFS               0x0002
    360 
    361209/* Named pipe write mode flags. Used in writeX calls. */
    362210#define PIPE_RAW_MODE 0x4
     
    366214#define DESIRED_ACCESS_PIPE 0x2019f
    367215 
    368 
    369 /* FileAttributes (search attributes) field */
    370 #define FILE_ATTRIBUTE_READONLY         0x0001
    371 #define FILE_ATTRIBUTE_HIDDEN           0x0002
    372 #define FILE_ATTRIBUTE_SYSTEM           0x0004
    373 #define FILE_ATTRIBUTE_VOLUME           0x0008
    374 #define FILE_ATTRIBUTE_DIRECTORY        0x0010
    375 #define FILE_ATTRIBUTE_ARCHIVE          0x0020
    376 #define FILE_ATTRIBUTE_DEVICE           0x0040
    377 #define FILE_ATTRIBUTE_NORMAL           0x0080
    378 #define FILE_ATTRIBUTE_TEMPORARY        0x0100
    379 #define FILE_ATTRIBUTE_SPARSE           0x0200
    380 #define FILE_ATTRIBUTE_REPARSE_POINT    0x0400
    381 #define FILE_ATTRIBUTE_COMPRESSED       0x0800
    382 #define FILE_ATTRIBUTE_OFFLINE          0x1000
    383 #define FILE_ATTRIBUTE_NONINDEXED       0x2000
    384 #define FILE_ATTRIBUTE_ENCRYPTED        0x4000
    385 #define FILE_ATTRIBUTE_ALL_MASK         0x7FFF
    386 
    387 /* Flags - combined with attributes. */
    388 #define FILE_FLAG_WRITE_THROUGH    0x80000000L
    389 #define FILE_FLAG_NO_BUFFERING     0x20000000L
    390 #define FILE_FLAG_RANDOM_ACCESS    0x10000000L
    391 #define FILE_FLAG_SEQUENTIAL_SCAN  0x08000000L
    392 #define FILE_FLAG_DELETE_ON_CLOSE  0x04000000L
    393 #define FILE_FLAG_BACKUP_SEMANTICS 0x02000000L /* only if backup/restore privilege? */
    394 #define FILE_FLAG_POSIX_SEMANTICS  0x01000000L
    395 
    396 /* Responses when opening a file. */
    397 #define FILE_WAS_SUPERSEDED 0
    398 #define FILE_WAS_OPENED 1
    399 #define FILE_WAS_CREATED 2
    400 #define FILE_WAS_OVERWRITTEN 3
    401 
    402 /* File type flags */
    403 #define FILE_TYPE_DISK  0
    404 #define FILE_TYPE_BYTE_MODE_PIPE 1
    405 #define FILE_TYPE_MESSAGE_MODE_PIPE 2
    406 #define FILE_TYPE_PRINTER 3
    407 #define FILE_TYPE_COMM_DEVICE 4
    408 #define FILE_TYPE_UNKNOWN 0xFFFF
    409 
    410216/* Flag for NT transact rename call. */
    411217#define RENAME_REPLACE_IF_EXISTS 1
     
    416222#define RENAME_FLAG_RENAME                   0x104
    417223#define RENAME_FLAG_COPY                     0x105
    418 
    419 /* Filesystem Attributes. */
    420 #define FILE_CASE_SENSITIVE_SEARCH 0x01
    421 #define FILE_CASE_PRESERVED_NAMES 0x02
    422 #define FILE_UNICODE_ON_DISK 0x04
    423 /* According to cifs9f, this is 4, not 8 */
    424 /* Acconding to testing, this actually sets the security attribute! */
    425 #define FILE_PERSISTENT_ACLS 0x08
    426 /* These entries added from cifs9f --tsb */
    427 #define FILE_FILE_COMPRESSION 0x10
    428 #define FILE_VOLUME_QUOTAS 0x20
    429 /* I think this is wrong. JRA #define FILE_DEVICE_IS_MOUNTED 0x20 */
    430 #define FILE_VOLUME_SPARSE_FILE 0x40
    431 #define FILE_VOLUME_IS_COMPRESSED 0x8000
    432224
    433225/* ChangeNotify flags. */
     
    473265/* where to find the base of the SMB packet proper */
    474266/* REWRITE TODO: smb_base needs to be removed */
    475 #define smb_base(buf) (((char *)(buf))+4)
     267#define smb_base(buf) (((const char *)(buf))+4)
    476268
    477269/* we don't allow server strings to be longer than 48 characters as
     
    499291#define BROWSER_CONSTANT        0xaa55
    500292
    501 /* Sercurity mode bits. */
    502 #define NEGOTIATE_SECURITY_USER_LEVEL           0x01
    503 #define NEGOTIATE_SECURITY_CHALLENGE_RESPONSE   0x02
    504 #define NEGOTIATE_SECURITY_SIGNATURES_ENABLED   0x04
    505 #define NEGOTIATE_SECURITY_SIGNATURES_REQUIRED  0x08
    506 
    507 /* NT Flags2 bits - cifs6.txt section 3.1.2 */
    508 #define FLAGS2_LONG_PATH_COMPONENTS    0x0001
    509 #define FLAGS2_EXTENDED_ATTRIBUTES     0x0002
    510 #define FLAGS2_SMB_SECURITY_SIGNATURES 0x0004
    511 #define FLAGS2_IS_LONG_NAME            0x0040
    512 #define FLAGS2_EXTENDED_SECURITY       0x0800
    513 #define FLAGS2_DFS_PATHNAMES           0x1000
    514 #define FLAGS2_READ_PERMIT_EXECUTE     0x2000
    515 #define FLAGS2_32_BIT_ERROR_CODES      0x4000
    516 #define FLAGS2_UNICODE_STRINGS         0x8000
    517 
    518 
    519 /* CIFS protocol capabilities */
    520 #define CAP_RAW_MODE            0x00000001
    521 #define CAP_MPX_MODE            0x00000002
    522 #define CAP_UNICODE             0x00000004
    523 #define CAP_LARGE_FILES         0x00000008
    524 #define CAP_NT_SMBS             0x00000010
    525 #define CAP_RPC_REMOTE_APIS     0x00000020
    526 #define CAP_STATUS32            0x00000040
    527 #define CAP_LEVEL_II_OPLOCKS    0x00000080
    528 #define CAP_LOCK_AND_READ       0x00000100
    529 #define CAP_NT_FIND             0x00000200
    530 #define CAP_DFS                 0x00001000
    531 #define CAP_W2K_SMBS            0x00002000
    532 #define CAP_LARGE_READX         0x00004000
    533 #define CAP_LARGE_WRITEX        0x00008000
    534 #define CAP_UNIX                0x00800000 /* Capabilities for UNIX extensions. Created by HP. */
    535 #define CAP_EXTENDED_SECURITY   0x80000000
    536 
    537293/*
    538294 * Global value meaning that the smb_uid field should be
     
    541297
    542298#define UID_FIELD_INVALID 0
    543 
    544 /* Lock types. */
    545 #define LOCKING_ANDX_EXCLUSIVE_LOCK  0x00
    546 #define LOCKING_ANDX_SHARED_LOCK     0x01
    547 #define LOCKING_ANDX_OPLOCK_RELEASE  0x02
    548 #define LOCKING_ANDX_CHANGE_LOCKTYPE 0x04
    549 #define LOCKING_ANDX_CANCEL_LOCK     0x08
    550 #define LOCKING_ANDX_LARGE_FILES     0x10
    551 
    552 /*
    553  * Bits we test with.
    554  */
    555 
    556 #define OPLOCK_NONE      0
    557 #define OPLOCK_EXCLUSIVE 1
    558 #define OPLOCK_BATCH     2
    559 #define OPLOCK_LEVEL_II  4
    560 
    561 #define CORE_OPLOCK_GRANTED (1<<5)
    562 #define EXTENDED_OPLOCK_GRANTED (1<<15)
    563 
    564 /*
    565  * Return values for oplock types.
    566  */
    567 
    568 #define NO_OPLOCK_RETURN 0
    569 #define EXCLUSIVE_OPLOCK_RETURN 1
    570 #define BATCH_OPLOCK_RETURN 2
    571 #define LEVEL_II_OPLOCK_RETURN 3
    572 
    573 /* oplock levels sent in oplock break */
    574 #define OPLOCK_BREAK_TO_NONE     0
    575 #define OPLOCK_BREAK_TO_LEVEL_II 1
    576 
    577 
    578 #define CMD_REPLY 0x8000
    579299
    580300/* The maximum length of a trust account password.
     
    603323#define FS_ATTR_NAMED_STREAMS                     0x00040000
    604324
    605 #define smb_len(buf) (PVAL(buf,3)|(PVAL(buf,2)<<8)|(PVAL(buf,1)<<16))
    606 #define _smb_setlen(buf,len) do {(buf)[0] = 0; (buf)[1] = ((len)&0x10000)>>16; \
    607         (buf)[2] = ((len)&0xFF00)>>8; (buf)[3] = (len)&0xFF;} while (0)
    608 #define _smb2_setlen(buf,len) do {(buf)[0] = 0; (buf)[1] = ((len)&0xFF0000)>>16; \
    609         (buf)[2] = ((len)&0xFF00)>>8; (buf)[3] = (len)&0xFF;} while (0)
    610 
    611 #include "libcli/raw/trans2.h"
     325#include "source4/libcli/raw/trans2.h"
    612326#include "libcli/raw/interfaces.h"
    613 
    614 #endif /* _SMB_H */
     327#include "libcli/smb/smb_common.h"
     328
     329#endif /* _RAW_SMB_H */
  • vendor/current/source4/libcli/raw/smb_signing.c

    r746 r988  
    4343}
    4444
    45 /***********************************************************
    46  SMB signing - Common code before we set a new signing implementation
    47 ************************************************************/
    48 static bool smbcli_set_smb_signing_common(struct smbcli_transport *transport)
    49 {
    50         if (!set_smb_signing_common(&transport->negotiate.sign_info)) {
    51                 return false;
    52         }
    53 
    54         if (!(transport->negotiate.sec_mode &
    55               (NEGOTIATE_SECURITY_SIGNATURES_REQUIRED|NEGOTIATE_SECURITY_SIGNATURES_ENABLED))) {
    56                 DEBUG(5, ("SMB Signing is not negotiated by the peer\n"));
    57                 return false;
    58         }
    59 
    60         /* These calls are INCOMPATIBLE with SMB signing */
    61         transport->negotiate.readbraw_supported = false;
    62         transport->negotiate.writebraw_supported = false;
    63 
    64         return true;
    65 }
    66 
    6745void mark_packet_signed(struct smb_request_buffer *out)
    6846{
     
    203181}
    204182
    205 static void smbcli_req_allocate_seq_num(struct smbcli_request *req)
    206 {
    207         req->seq_num = req->transport->negotiate.sign_info.next_seq_num;
    208        
    209         /* some requests (eg. NTcancel) are one way, and the sequence number
    210            should be increased by 1 not 2 */
    211         if (req->sign_single_increment) {
    212                 req->transport->negotiate.sign_info.next_seq_num += 1;
    213         } else {
    214                 req->transport->negotiate.sign_info.next_seq_num += 2;
    215         }
    216 }
    217 
    218 /***********************************************************
    219  SMB signing - Simple implementation - calculate a MAC to send.
    220 ************************************************************/
    221 void smbcli_request_calculate_sign_mac(struct smbcli_request *req)
    222 {
    223 #if 0
    224         /* enable this when packet signing is preventing you working out why valgrind
    225            says that data is uninitialised */
    226         file_save("pkt.dat", req->out.buffer, req->out.size);
    227 #endif
    228 
    229         switch (req->transport->negotiate.sign_info.signing_state) {
    230         case SMB_SIGNING_ENGINE_OFF:
    231                 break;
    232 
    233         case SMB_SIGNING_ENGINE_BSRSPYL:
    234                 /* mark the packet as signed - BEFORE we sign it...*/
    235                 mark_packet_signed(&req->out);
    236                
    237                 /* I wonder what BSRSPYL stands for - but this is what MS
    238                    actually sends! */
    239                 memcpy((req->out.hdr + HDR_SS_FIELD), "BSRSPYL ", 8);
    240                 break;
    241 
    242         case SMB_SIGNING_ENGINE_ON:
    243                        
    244                 smbcli_req_allocate_seq_num(req);
    245                 sign_outgoing_message(&req->out,
    246                                       &req->transport->negotiate.sign_info.mac_key,
    247                                       req->seq_num);
    248                 break;
    249         }
    250         return;
    251 }
    252 
    253 
    254183/**
    255184 SMB signing - NULL implementation
     
    266195        return true;
    267196}
    268 
    269 /**
    270  SMB signing - TEMP implementation - setup the MAC key.
    271 
    272 */
    273 bool smbcli_temp_set_signing(struct smbcli_transport *transport)
    274 {
    275         if (!smbcli_set_smb_signing_common(transport)) {
    276                 return false;
    277         }
    278         DEBUG(5, ("BSRSPYL SMB signing enabled\n"));
    279         smbcli_set_signing_off(&transport->negotiate.sign_info);
    280 
    281         transport->negotiate.sign_info.mac_key = data_blob(NULL, 0);
    282         transport->negotiate.sign_info.signing_state = SMB_SIGNING_ENGINE_BSRSPYL;
    283 
    284         return true;
    285 }
    286 
    287 /***********************************************************
    288  SMB signing - Simple implementation - check a MAC sent by server.
    289 ************************************************************/
    290 /**
    291  * Check a packet supplied by the server.
    292  * @return false if we had an established signing connection
    293  *         which had a back checksum, true otherwise
    294  */
    295 bool smbcli_request_check_sign_mac(struct smbcli_request *req)
    296 {
    297         bool good;
    298 
    299         if (!req->transport->negotiate.sign_info.doing_signing &&
    300             req->sign_caller_checks) {
    301                 return true;
    302         }
    303 
    304         req->sign_caller_checks = false;
    305 
    306         switch (req->transport->negotiate.sign_info.signing_state)
    307         {
    308         case SMB_SIGNING_ENGINE_OFF:
    309                 return true;
    310         case SMB_SIGNING_ENGINE_BSRSPYL:
    311                 return true;
    312 
    313         case SMB_SIGNING_ENGINE_ON:
    314         {                       
    315                 if (req->in.size < (HDR_SS_FIELD + 8)) {
    316                         return false;
    317                 } else {
    318                         good = check_signed_incoming_message(&req->in,
    319                                                              &req->transport->negotiate.sign_info.mac_key,
    320                                                              req->seq_num+1);
    321                        
    322                         return signing_good(&req->transport->negotiate.sign_info,
    323                                             req->seq_num+1, good);
    324                 }
    325         }
    326         }
    327         return false;
    328 }
    329 
    330197
    331198/***********************************************************
     
    363230}
    364231
    365 
    366 /***********************************************************
    367  SMB signing - Simple implementation - setup the MAC key.
    368 ************************************************************/
    369 bool smbcli_transport_simple_set_signing(struct smbcli_transport *transport,
    370                                          const DATA_BLOB user_session_key,
    371                                          const DATA_BLOB response)
    372 {
    373         if (!smbcli_set_smb_signing_common(transport)) {
    374                 return false;
    375         }
    376 
    377         return smbcli_simple_set_signing(transport,
    378                                          &transport->negotiate.sign_info,
    379                                          &user_session_key,
    380                                          &response);
    381 }
    382 
    383 
    384 bool smbcli_init_signing(struct smbcli_transport *transport)
    385 {
    386         transport->negotiate.sign_info.next_seq_num = 0;
    387         transport->negotiate.sign_info.mac_key = data_blob(NULL, 0);
    388         if (!smbcli_set_signing_off(&transport->negotiate.sign_info)) {
    389                 return false;
    390         }
    391        
    392         switch (transport->options.signing) {
    393         case SMB_SIGNING_OFF:
    394                 transport->negotiate.sign_info.allow_smb_signing = false;
    395                 break;
    396         case SMB_SIGNING_SUPPORTED:
    397         case SMB_SIGNING_AUTO:
    398                 transport->negotiate.sign_info.allow_smb_signing = true;
    399                 break;
    400         case SMB_SIGNING_REQUIRED:
    401                 transport->negotiate.sign_info.allow_smb_signing = true;
    402                 transport->negotiate.sign_info.mandatory_signing = true;
    403                 break;
    404         }
    405         return true;
    406 }
  • vendor/current/source4/libcli/raw/trans2.h

    r414 r988  
    2222#ifndef _TRANS2_H_
    2323#define _TRANS2_H_
    24 
    25 /* These are the TRANS2 sub commands */
    26 #define TRANSACT2_OPEN                        0
    27 #define TRANSACT2_FINDFIRST                   1
    28 #define TRANSACT2_FINDNEXT                    2
    29 #define TRANSACT2_QFSINFO                     3
    30 #define TRANSACT2_SETFSINFO                   4
    31 #define TRANSACT2_QPATHINFO                   5
    32 #define TRANSACT2_SETPATHINFO                 6
    33 #define TRANSACT2_QFILEINFO                   7
    34 #define TRANSACT2_SETFILEINFO                 8
    35 #define TRANSACT2_FSCTL                       9
    36 #define TRANSACT2_IOCTL                     0xA
    37 #define TRANSACT2_FINDNOTIFYFIRST           0xB
    38 #define TRANSACT2_FINDNOTIFYNEXT            0xC
    39 #define TRANSACT2_MKDIR                     0xD
    40 #define TRANSACT2_SESSION_SETUP             0xE
    41 #define TRANSACT2_GET_DFS_REFERRAL         0x10
    42 #define TRANSACT2_REPORT_DFS_INCONSISTANCY 0x11
    4324
    4425
     
    8364#define SMB_QFS_FULL_SIZE_INFORMATION                   1007
    8465#define SMB_QFS_OBJECTID_INFORMATION                    1008
     66#define SMB_QFS_SECTOR_SIZE_INFORMATION                 1011
    8567
    8668
     
    303285#define QFS_TYPE_VIRTUAL                        0x40
    304286
     287/* SMB_QFS_SECTOR_SIZE_INFORMATION values */
     288#define QFS_SSINFO_FLAGS_ALIGNED_DEVICE                 0x00000001
     289#define QFS_SSINFO_FLAGS_PARTITION_ALIGNED_ON_DEVICE    0x00000002
     290#define QFS_SSINFO_FLAGS_NO_SEEK_PENALTY                0x00000004
     291#define QFS_SSINFO_FLAGS_TRIM_ENABLED                   0x00000008
     292
     293#define QFS_SSINFO_OFFSET_UNKNOWN                       0xffffffff
    305294
    306295/*
     
    317306#define SMB_QFS_MAC_FS_INFO                     0x301
    318307
    319 
    320 
    321 /* UNIX CIFS Extensions - created by HP */
    322 /*
    323  * UNIX CIFS Extensions have the range 0x200 - 0x2FF reserved.
    324  * Supposedly Microsoft have agreed to this.
    325  */
    326 
    327 #define MIN_UNIX_INFO_LEVEL 0x200
    328 #define MAX_UNIX_INFO_LEVEL 0x2FF
    329 
    330 #define INFO_LEVEL_IS_UNIX(level) (((level) >= MIN_UNIX_INFO_LEVEL) && ((level) <= MAX_UNIX_INFO_LEVEL))
    331 
    332 #define SMB_MODE_NO_CHANGE                 0xFFFFFFFF     /* file mode value which */
    333                                               /* means "don't change it" */
    334 #define SMB_UID_NO_CHANGE                  0xFFFFFFFF
    335 #define SMB_GID_NO_CHANGE                  0xFFFFFFFF
    336 
    337 #define SMB_SIZE_NO_CHANGE_LO              0xFFFFFFFF
    338 #define SMB_SIZE_NO_CHANGE_HI              0xFFFFFFFF
    339  
    340 #define SMB_TIME_NO_CHANGE_LO              0xFFFFFFFF
    341 #define SMB_TIME_NO_CHANGE_HI              0xFFFFFFFF
    342 
    343 /*
    344 UNIX_BASIC  info level:
    345 
    346 Offset Size         Name
    347 0      LARGE_INTEGER EndOfFile                File size
    348 8      LARGE_INTEGER Blocks                   Number of bytes used on disk (st_blocks).
    349 16     LARGE_INTEGER CreationTime             Creation time
    350 24     LARGE_INTEGER LastAccessTime           Last access time
    351 32     LARGE_INTEGER LastModificationTime     Last modification time
    352 40     LARGE_INTEGER Uid                      Numeric user id for the owner
    353 48     LARGE_INTEGER Gid                      Numeric group id of owner
    354 56     ULONG Type                             Enumeration specifying the pathname type:
    355                                               0 -- File
    356                                               1 -- Directory
    357                                               2 -- Symbolic link
    358                                               3 -- Character device
    359                                               4 -- Block device
    360                                               5 -- FIFO (named pipe)
    361                                               6 -- Unix domain socket
    362 
    363 60     LARGE_INTEGER devmajor                 Major device number if type is device
    364 68     LARGE_INTEGER devminor                 Minor device number if type is device
    365 76     LARGE_INTEGER uniqueid                 This is a server-assigned unique id for the file. The client
    366                                               will typically map this onto an inode number. The scope of
    367                                               uniqueness is the share.
    368 84     LARGE_INTEGER permissions              Standard UNIX file permissions  - see below.
    369 92     LARGE_INTEGER nlinks                   The number of directory entries that map to this entry
    370                                               (number of hard links)
    371 
    372 100 - end.
    373 */
    374 
    375 /*
    376 SMB_QUERY_FILE_UNIX_INFO2 is SMB_QUERY_FILE_UNIX_BASIC with create
    377 time and file flags appended. The corresponding info level for
    378 findfirst/findnext is SMB_FIND_FILE_UNIX_UNIX2.
    379 
    380 Size    Offset  Value
    381 ---------------------
    382 0      LARGE_INTEGER EndOfFile          File size
    383 8      LARGE_INTEGER Blocks             Number of blocks used on disk
    384 16     LARGE_INTEGER ChangeTime         Attribute change time
    385 24     LARGE_INTEGER LastAccessTime           Last access time
    386 32     LARGE_INTEGER LastModificationTime     Last modification time
    387 40     LARGE_INTEGER Uid                Numeric user id for the owner
    388 48     LARGE_INTEGER Gid                Numeric group id of owner
    389 56     ULONG Type                       Enumeration specifying the file type
    390 60     LARGE_INTEGER devmajor           Major device number if type is device
    391 68     LARGE_INTEGER devminor           Minor device number if type is device
    392 76     LARGE_INTEGER uniqueid           This is a server-assigned unique id
    393 84     LARGE_INTEGER permissions        Standard UNIX permissions
    394 92     LARGE_INTEGER nlinks             Number of hard link)
    395 100    LARGE_INTEGER CreationTime       Create/birth time
    396 108    ULONG FileFlags                  File flags enumeration
    397 112    ULONG FileFlagsMask              Mask of valid flags
    398 */
    399 
    400 /* UNIX filetype mappings. */
    401 
    402 #define UNIX_TYPE_FILE      0
    403 #define UNIX_TYPE_DIR       1
    404 #define UNIX_TYPE_SYMLINK   2
    405 #define UNIX_TYPE_CHARDEV   3
    406 #define UNIX_TYPE_BLKDEV    4
    407 #define UNIX_TYPE_FIFO      5
    408 #define UNIX_TYPE_SOCKET    6
    409 #define UNIX_TYPE_UNKNOWN   0xFFFFFFFF
    410 
    411 /*
    412  * Oh this is fun. "Standard UNIX permissions" has no
    413  * meaning in POSIX. We need to define the mapping onto
    414  * and off the wire as this was not done in the original HP
    415  * spec. JRA.
    416  */
    417 
    418 #define UNIX_X_OTH                      0000001
    419 #define UNIX_W_OTH                      0000002
    420 #define UNIX_R_OTH                      0000004
    421 #define UNIX_X_GRP                      0000010
    422 #define UNIX_W_GRP                      0000020
    423 #define UNIX_R_GRP                      0000040
    424 #define UNIX_X_USR                      0000100
    425 #define UNIX_W_USR                      0000200
    426 #define UNIX_R_USR                      0000400
    427 #define UNIX_STICKY                     0001000
    428 #define UNIX_SET_GID                    0002000
    429 #define UNIX_SET_UID                    0004000
    430 
    431 /* Masks for the above */
    432 #define UNIX_OTH_MASK                   0000007
    433 #define UNIX_GRP_MASK                   0000070
    434 #define UNIX_USR_MASK                   0000700
    435 #define UNIX_PERM_MASK                  0000777
    436 #define UNIX_EXTRA_MASK                 0007000
    437 #define UNIX_ALL_MASK                   0007777
    438 
    439 /* Flags for the file_flags field in UNIX_INFO2: */
    440 #define EXT_SECURE_DELETE               0x00000001
    441 #define EXT_ENABLE_UNDELETE             0x00000002
    442 #define EXT_SYNCHRONOUS                 0x00000004
    443 #define EXT_IMMUTABLE                   0x00000008
    444 #define EXT_OPEN_APPEND_ONLY            0x00000010
    445 #define EXT_DO_NOT_BACKUP               0x00000020
    446 #define EXT_NO_UPDATE_ATIME             0x00000040
    447 #define EXT_HIDDEN                      0x00000080
    448 
    449 #define SMB_QFILEINFO_UNIX_LINK         0x201
    450 #define SMB_SFILEINFO_UNIX_LINK         0x201
    451 #define SMB_SFILEINFO_UNIX_HLINK        0x203
    452 
    453 /*
    454  Info level for QVOLINFO - returns version of CIFS UNIX extensions, plus
    455  64-bits worth of capability fun :-).
    456 */
    457 
    458 #define SMB_QUERY_CIFS_UNIX_INFO      0x200
    459 
    460 /* Returns the following.
    461 
    462   UINT16             major version number
    463   UINT16             minor version number
    464   LARGE_INTEGER      capability bitfield
    465 
    466 */
    467 
    468 #define CIFS_UNIX_MAJOR_VERSION 1
    469 #define CIFS_UNIX_MINOR_VERSION 0
    470 
    471 #define CIFS_UNIX_FCNTL_LOCKS_CAP           0x1
    472 #define CIFS_UNIX_POSIX_ACLS_CAP            0x2
    473 
    474 /* ... more as we think of them :-). */
    475 
    476308#endif
Note: See TracChangeset for help on using the changeset viewer.