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
Files:
2 added
5 deleted
81 edited

Legend:

Unmodified
Added
Removed
  • vendor/current/source4/libcli/cliconnect.c

    r740 r988  
    2727#include "libcli/auth/libcli_auth.h"
    2828#include "libcli/smb_composite/smb_composite.h"
     29#include "libcli/smb/smbXcli_base.h"
    2930
    3031/*
     
    3637                           struct resolve_context *resolve_ctx,
    3738                           struct smbcli_options *options,
    38                const char *socket_options)
    39 {
    40         struct smbcli_socket *sock;
    41 
    42         sock = smbcli_sock_connect_byname(server, ports, NULL,
    43                                           resolve_ctx, ev_ctx,
    44                       socket_options);
    45 
    46         if (sock == NULL) return false;
    47        
    48         cli->transport = smbcli_transport_init(sock, cli, true, options);
    49         if (!cli->transport) {
     39                           const char *socket_options,
     40                           struct nbt_name *calling,
     41                           struct nbt_name *called)
     42{
     43        NTSTATUS status;
     44
     45        cli->options = *options;
     46
     47        status = smbcli_sock_connect(cli,
     48                                     NULL, /* host_addr */
     49                                     ports,
     50                                     server,
     51                                     resolve_ctx,
     52                                     ev_ctx,
     53                                     socket_options,
     54                                     calling,
     55                                     called,
     56                                     &cli->sock);
     57        if (!NT_STATUS_IS_OK(status)) {
    5058                return false;
    5159        }
    5260
    5361        return true;
    54 }
    55 
    56 /* wrapper around smbcli_transport_connect() */
    57 bool smbcli_transport_establish(struct smbcli_state *cli,
    58                                 struct nbt_name *calling,
    59                                 struct nbt_name *called)
    60 {
    61         return smbcli_transport_connect(cli->transport, calling, called);
    6262}
    6363
     
    6565NTSTATUS smbcli_negprot(struct smbcli_state *cli, bool unicode, int maxprotocol)
    6666{
    67         return smb_raw_negotiate(cli->transport, unicode, maxprotocol);
     67        if (unicode) {
     68                cli->options.unicode = 1;
     69        } else {
     70                cli->options.unicode = 0;
     71        }
     72
     73        cli->transport = smbcli_transport_init(cli->sock, cli,
     74                                               true, &cli->options);
     75        cli->sock = NULL;
     76        if (!cli->transport) {
     77                return NT_STATUS_NO_MEMORY;
     78        }
     79
     80        return smb_raw_negotiate(cli->transport, unicode, PROTOCOL_CORE, maxprotocol);
    6881}
    6982
     
    113126        /* setup a tree connect */
    114127        tcon.generic.level = RAW_TCON_TCONX;
    115         tcon.tconx.in.flags = 0;
     128        tcon.tconx.in.flags = TCONX_FLAG_EXTENDED_RESPONSE;
     129        tcon.tconx.in.flags |= TCONX_FLAG_EXTENDED_SIGNATURES;
    116130        if (cli->transport->negotiate.sec_mode & NEGOTIATE_SECURITY_USER_LEVEL) {
    117131                tcon.tconx.in.password = data_blob(NULL, 0);
     
    131145
    132146        cli->tree->tid = tcon.tconx.out.tid;
     147
     148        if (tcon.tconx.out.options & SMB_EXTENDED_SIGNATURES) {
     149                smb1cli_session_protect_session_key(cli->tree->session->smbXcli);
     150        }
    133151
    134152        talloc_free(mem_ctx);
  • vendor/current/source4/libcli/clifile.c

    r740 r988  
    5252
    5353/****************************************************************************
    54  Map standard UNIX permissions onto wire representations.
    55 ****************************************************************************/
    56 uint32_t unix_perms_to_wire(mode_t perms)
    57 {
    58         unsigned int ret = 0;
    59 
    60         ret |= ((perms & S_IXOTH) ?  UNIX_X_OTH : 0);
    61         ret |= ((perms & S_IWOTH) ?  UNIX_W_OTH : 0);
    62         ret |= ((perms & S_IROTH) ?  UNIX_R_OTH : 0);
    63         ret |= ((perms & S_IXGRP) ?  UNIX_X_GRP : 0);
    64         ret |= ((perms & S_IWGRP) ?  UNIX_W_GRP : 0);
    65         ret |= ((perms & S_IRGRP) ?  UNIX_R_GRP : 0);
    66         ret |= ((perms & S_IXUSR) ?  UNIX_X_USR : 0);
    67         ret |= ((perms & S_IWUSR) ?  UNIX_W_USR : 0);
    68         ret |= ((perms & S_IRUSR) ?  UNIX_R_USR : 0);
    69 #ifdef S_ISVTX
    70         ret |= ((perms & S_ISVTX) ?  UNIX_STICKY : 0);
    71 #endif
    72 #ifdef S_ISGID
    73         ret |= ((perms & S_ISGID) ?  UNIX_SET_GID : 0);
    74 #endif
    75 #ifdef S_ISUID
    76         ret |= ((perms & S_ISUID) ?  UNIX_SET_UID : 0);
    77 #endif
    78         return ret;
    79 }
    80 
    81 /****************************************************************************
    8254 Symlink a file (UNIX extensions).
    8355****************************************************************************/
     
    682654        TALLOC_CTX *mem_ctx;
    683655        NTSTATUS status;
     656        int ret = -1;
    684657
    685658        mem_ctx = talloc_init("raw_open");
    686         if (!mem_ctx) return -1;
     659        if (!mem_ctx) return ret;
    687660
    688661        open_parms.openx.level = RAW_OPEN_CTEMP;
     
    692665
    693666        status = smb_raw_open(tree, mem_ctx, &open_parms);
    694         if (tmp_path) {
    695                 *tmp_path = strdup(open_parms.ctemp.out.name);
     667        if (NT_STATUS_IS_OK(status)) {
     668                if (tmp_path) {
     669                        *tmp_path = strdup(open_parms.ctemp.out.name);
     670                }
     671                ret = open_parms.ctemp.out.file.fnum;
    696672        }
    697673        talloc_free(mem_ctx);
    698         if (NT_STATUS_IS_OK(status)) {
    699                 return open_parms.ctemp.out.file.fnum;
    700         }
    701         return -1;
    702 }
     674        return ret;
     675}
  • vendor/current/source4/libcli/clilist.c

    r414 r988  
    112112        int max_matches = 512;
    113113        char *mask;
    114         int ff_eos = 0, i, ff_searchcount;
     114        int ff_eos = 0, i;
    115115        int ff_dir_handle=0;
    116116
     
    155155               
    156156                        ff_dir_handle = first_parms.t2ffirst.out.handle;
    157                         ff_searchcount = first_parms.t2ffirst.out.count;
    158157                        ff_eos = first_parms.t2ffirst.out.end_of_search;
    159158                       
     
    182181                                return -1;
    183182                        }
    184                         ff_searchcount = next_parms.t2fnext.out.count;
    185183                        ff_eos = next_parms.t2fnext.out.end_of_search;
    186184                        received = next_parms.t2fnext.out.count;
  • vendor/current/source4/libcli/climessage.c

    r414 r988  
    3434       
    3535        req = smbcli_request_setup(tree, SMBsendstrt, 0, 0);
     36        if (req == NULL) {
     37                return false;
     38        }
    3639        smbcli_req_append_string(req, username, STR_TERMINATE);
    3740        smbcli_req_append_string(req, host, STR_TERMINATE);
     
    5861       
    5962        req = smbcli_request_setup(tree, SMBsendtxt, 1, 0);
     63        if (req == NULL) {
     64                return false;
     65        }
    6066        SSVAL(req->out.vwv, VWV(0), grp);
    6167
     
    8187       
    8288        req = smbcli_request_setup(tree, SMBsendend, 1, 0);
     89        if (req == NULL) {
     90                return false;
     91        }
    8392        SSVAL(req->out.vwv, VWV(0), grp);
    8493
  • vendor/current/source4/libcli/clireadwrite.c

    r414 r988  
    106106        parms.writex.in.wmode = write_mode;
    107107        parms.writex.in.remaining = 0;
    108        
    109         while (total < size) {
     108
     109        do {
    110110                NTSTATUS status;
    111111
     
    125125                total += parms.writex.out.nwritten;
    126126                buf += parms.writex.out.nwritten;
    127         }
     127        } while (total < size);
    128128
    129129        return total;
  • vendor/current/source4/libcli/composite/composite.c

    r740 r988  
    5656
    5757        while (c->state < COMPOSITE_STATE_DONE) {
    58                 if (event_loop_once(c->event_ctx) != 0) {
     58                if (tevent_loop_once(c->event_ctx) != 0) {
    5959                        return NT_STATUS_UNSUCCESSFUL;
    6060                }
     
    107107        }
    108108        if (!ctx->used_wait && !ctx->async.fn) {
    109                 event_add_timed(ctx->event_ctx, ctx, timeval_zero(), composite_trigger, ctx);
     109                tevent_add_timer(ctx->event_ctx, ctx, timeval_zero(), composite_trigger, ctx);
    110110        }
    111111        ctx->status = status;
     
    137137{
    138138        if (!ctx->used_wait && !ctx->async.fn) {
    139                 event_add_timed(ctx->event_ctx, ctx, timeval_zero(), composite_trigger, ctx);
     139                tevent_add_timer(ctx->event_ctx, ctx, timeval_zero(), composite_trigger, ctx);
    140140        }
    141141        ctx->state = COMPOSITE_STATE_DONE;
     
    158158           immediate event, otherwise we can be stuck forever */
    159159        if (new_ctx->state >= COMPOSITE_STATE_DONE && continuation) {
    160                 event_add_timed(new_ctx->event_ctx, new_ctx, timeval_zero(), composite_trigger, new_ctx);
     160                tevent_add_timer(new_ctx->event_ctx, new_ctx, timeval_zero(), composite_trigger, new_ctx);
    161161        }
    162162}
     
    168168{
    169169        if (composite_nomem(new_req, ctx)) return;
     170        if (new_req->state > SMBCLI_REQUEST_RECV) {
     171                composite_error(ctx, new_req->status);
     172                return;
     173        }
    170174        new_req->async.fn = continuation;
    171175        new_req->async.private_data = private_data;
     
    178182{
    179183        if (composite_nomem(new_req, ctx)) return;
     184        if (new_req->state > SMB2_REQUEST_RECV) {
     185                composite_error(ctx, new_req->status);
     186                return;
     187        }
    180188        new_req->async.fn = continuation;
    181189        new_req->async.private_data = private_data;
  • vendor/current/source4/libcli/dgram/dgramsocket.c

    r740 r988  
    4949
    5050        blob = data_blob_talloc(tmp_ctx, NULL, dsize);
    51         if (blob.data == NULL) {
     51        if ((dsize != 0) && (blob.data == NULL)) {
    5252                talloc_free(tmp_ctx);
    5353                return;
     
    132132        }
    133133
    134         EVENT_FD_NOT_WRITEABLE(dgmsock->fde);
     134        TEVENT_FD_NOT_WRITEABLE(dgmsock->fde);
    135135        return;
    136136}
     
    145145        struct nbt_dgram_socket *dgmsock = talloc_get_type(private_data,
    146146                                                           struct nbt_dgram_socket);
    147         if (flags & EVENT_FD_WRITE) {
     147        if (flags & TEVENT_FD_WRITE) {
    148148                dgm_socket_send(dgmsock);
    149149        }
    150         if (flags & EVENT_FD_READ) {
     150        if (flags & TEVENT_FD_READ) {
    151151                dgm_socket_recv(dgmsock);
    152152        }
     
    176176        talloc_steal(dgmsock, dgmsock->sock);
    177177
    178         dgmsock->fde = event_add_fd(dgmsock->event_ctx, dgmsock,
     178        dgmsock->fde = tevent_add_fd(dgmsock->event_ctx, dgmsock,
    179179                                    socket_get_fd(dgmsock->sock), 0,
    180180                                    dgm_socket_handler, dgmsock);
     
    203203        dgmsock->incoming.handler = handler;
    204204        dgmsock->incoming.private_data = private_data;
    205         EVENT_FD_READABLE(dgmsock->fde);
     205        TEVENT_FD_READABLE(dgmsock->fde);
    206206        return NT_STATUS_OK;
    207207}
     
    232232        }
    233233
    234         DLIST_ADD_END(dgmsock->send_queue, req, struct nbt_dgram_request *);
    235 
    236         EVENT_FD_WRITEABLE(dgmsock->fde);
     234        DLIST_ADD_END(dgmsock->send_queue, req);
     235
     236        TEVENT_FD_WRITEABLE(dgmsock->fde);
    237237
    238238        return NT_STATUS_OK;
  • vendor/current/source4/libcli/dgram/mailslot.c

    r740 r988  
    7272        talloc_set_destructor(dgmslot, dgram_mailslot_destructor);
    7373
    74         EVENT_FD_READABLE(dgmsock->fde);
     74        TEVENT_FD_READABLE(dgmsock->fde);
    7575
    7676        return dgmslot;
  • vendor/current/source4/libcli/finddcs_cldap.c

    r740 r988  
    2828#include "libcli/security/security.h"
    2929#include "lib/util/tevent_ntstatus.h"
     30#include "lib/tsocket/tsocket.h"
    3031#include "libcli/composite/composite.h"
     32#include "lib/util/util_net.h"
    3133
    3234struct finddcs_cldap_state {
     
    4143        struct cldap_socket *cldap;
    4244        struct cldap_netlogon *netlogon;
     45        NTSTATUS status;
    4346};
    4447
     
    5356                                     struct resolve_context *resolve_ctx,
    5457                                     struct tevent_context *event_ctx);
     58static void finddcs_cldap_nbt_resolved(struct composite_context *ctx);
     59static bool finddcs_cldap_name_lookup(struct finddcs_cldap_state *state,
     60                                      struct finddcs *io,
     61                                      struct resolve_context *resolve_ctx,
     62                                      struct tevent_context *event_ctx);
    5563static void finddcs_cldap_name_resolved(struct composite_context *ctx);
    5664static void finddcs_cldap_next_server(struct finddcs_cldap_state *state);
     
    6068/*
    6169 * find a list of DCs via DNS/CLDAP
    62  *
    6370 */
    6471struct tevent_req *finddcs_cldap_send(TALLOC_CTX *mem_ctx,
     
    7885        state->ev = event_ctx;
    7986        state->minimum_dc_flags = io->in.minimum_dc_flags;
    80         state->domain_name = talloc_strdup(state, io->in.domain_name);
    81         if (tevent_req_nomem(state->domain_name, req)) {
    82                 return tevent_req_post(req, event_ctx);
     87
     88        if (io->in.domain_name) {
     89                state->domain_name = talloc_strdup(state, io->in.domain_name);
     90                if (tevent_req_nomem(state->domain_name, req)) {
     91                        return tevent_req_post(req, event_ctx);
     92                }
     93        } else {
     94                state->domain_name = NULL;
    8395        }
    8496
     
    93105
    94106        if (io->in.server_address) {
    95                 DEBUG(4,("finddcs: searching for a DC by IP %s\n", io->in.server_address));
    96                 if (!finddcs_cldap_ipaddress(state, io)) {
    97                         return tevent_req_post(req, event_ctx);
    98                 }
    99         } else if (strchr(state->domain_name, '.')) {
    100                 /* looks like a DNS name */
    101                 DEBUG(4,("finddcs: searching for a DC by DNS domain %s\n", state->domain_name));
    102                 if (!finddcs_cldap_srv_lookup(state, io, resolve_ctx, event_ctx)) {
    103                         return tevent_req_post(req, event_ctx);
     107                if (is_ipaddress(io->in.server_address)) {
     108                        DEBUG(4,("finddcs: searching for a DC by IP %s\n",
     109                                 io->in.server_address));
     110                        if (!finddcs_cldap_ipaddress(state, io)) {
     111                                return tevent_req_post(req, event_ctx);
     112                        }
     113                } else {
     114                        if (!finddcs_cldap_name_lookup(state, io, resolve_ctx,
     115                                                       event_ctx)) {
     116                                return tevent_req_post(req, event_ctx);
     117                        }
     118                }
     119        } else if (io->in.domain_name) {
     120                if (strchr(state->domain_name, '.')) {
     121                        /* looks like a DNS name */
     122                        DEBUG(4,("finddcs: searching for a DC by DNS domain %s\n", state->domain_name));
     123                        if (!finddcs_cldap_srv_lookup(state, io, resolve_ctx,
     124                                                      event_ctx)) {
     125                                return tevent_req_post(req, event_ctx);
     126                        }
     127                } else {
     128                        DEBUG(4,("finddcs: searching for a DC by NBT lookup %s\n", state->domain_name));
     129                        if (!finddcs_cldap_nbt_lookup(state, io, resolve_ctx,
     130                                                      event_ctx)) {
     131                                return tevent_req_post(req, event_ctx);
     132                        }
    104133                }
    105134        } else {
    106                 DEBUG(4,("finddcs: searching for a DC by NBT lookup %s\n", state->domain_name));
    107                 if (!finddcs_cldap_nbt_lookup(state, io, resolve_ctx, event_ctx)) {
    108                         return tevent_req_post(req, event_ctx);
    109                 }
     135                /* either we have the domain name or the IP address */
     136                tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER_MIX);
     137                DEBUG(2,("finddcs: Please specify at least the domain name or the IP address! \n"));
     138                return tevent_req_post(req, event_ctx);
    110139        }
    111140
     
    132161        state->srv_addresses[1] = NULL;
    133162        state->srv_address_index = 0;
    134         status = cldap_socket_init(state, state->ev, NULL, NULL, &state->cldap);
    135         if (tevent_req_nterror(state->req, status)) {
    136                 return false;
    137         }
    138163
    139164        finddcs_cldap_next_server(state);
     
    191216                return false;
    192217        }
     218        creq->async.fn = finddcs_cldap_nbt_resolved;
     219        creq->async.private_data = state;
     220        return true;
     221}
     222
     223static bool finddcs_cldap_name_lookup(struct finddcs_cldap_state *state,
     224                                      struct finddcs *io,
     225                                      struct resolve_context *resolve_ctx,
     226                                      struct tevent_context *event_ctx)
     227{
     228        struct composite_context *creq;
     229        struct nbt_name name;
     230
     231        make_nbt_name(&name, io->in.server_address, NBT_NAME_SERVER);
     232        creq = resolve_name_send(resolve_ctx, state, &name, event_ctx);
     233        if (tevent_req_nomem(creq, state->req)) {
     234                return false;
     235        }
    193236        creq->async.fn = finddcs_cldap_name_resolved;
    194237        creq->async.private_data = state;
     
    202245{
    203246        struct tevent_req *subreq;
     247        struct tsocket_address *dest;
     248        int ret;
     249
     250        TALLOC_FREE(state->cldap);
    204251
    205252        if (state->srv_addresses[state->srv_address_index] == NULL) {
    206                 tevent_req_nterror(state->req, NT_STATUS_OBJECT_NAME_NOT_FOUND);
     253                if (NT_STATUS_IS_OK(state->status)) {
     254                        tevent_req_nterror(state->req, NT_STATUS_OBJECT_NAME_NOT_FOUND);
     255                } else {
     256                        tevent_req_nterror(state->req, state->status);
     257                }
    207258                DEBUG(2,("finddcs: No matching CLDAP server found\n"));
    208259                return;
    209260        }
    210261
     262        /* we should get the port from the SRV response */
     263        ret = tsocket_address_inet_from_strings(state, "ip",
     264                                                state->srv_addresses[state->srv_address_index],
     265                                                389,
     266                                                &dest);
     267        if (ret == 0) {
     268                state->status = NT_STATUS_OK;
     269        } else {
     270                state->status = map_nt_error_from_unix_common(errno);
     271        }
     272        if (!NT_STATUS_IS_OK(state->status)) {
     273                state->srv_address_index++;
     274                finddcs_cldap_next_server(state);
     275                return;
     276        }
     277
     278        state->status = cldap_socket_init(state, NULL, dest, &state->cldap);
     279        if (!NT_STATUS_IS_OK(state->status)) {
     280                state->srv_address_index++;
     281                finddcs_cldap_next_server(state);
     282                return;
     283        }
     284
     285        TALLOC_FREE(state->netlogon);
    211286        state->netlogon = talloc_zero(state, struct cldap_netlogon);
    212         if (tevent_req_nomem(state->netlogon, state->req)) {
    213                 return;
    214         }
    215 
    216         state->netlogon->in.dest_address = state->srv_addresses[state->srv_address_index];
    217         /* we should get the port from the SRV response */
    218         state->netlogon->in.dest_port = 389;
    219         if (strchr(state->domain_name, '.')) {
     287        if (state->netlogon == NULL) {
     288                state->status = NT_STATUS_NO_MEMORY;
     289                state->srv_address_index++;
     290                finddcs_cldap_next_server(state);
     291                return;
     292        }
     293
     294        if ((state->domain_name != NULL) && (strchr(state->domain_name, '.'))) {
    220295                state->netlogon->in.realm = state->domain_name;
    221296        }
    222297        if (state->domain_sid) {
    223298                state->netlogon->in.domain_sid = dom_sid_string(state, state->domain_sid);
    224                 if (tevent_req_nomem(state->netlogon->in.domain_sid, state->req)) {
     299                if (state->netlogon->in.domain_sid == NULL) {
     300                        state->status = NT_STATUS_NO_MEMORY;
     301                        state->srv_address_index++;
     302                        finddcs_cldap_next_server(state);
    225303                        return;
    226304                }
     
    233311        state->netlogon->in.map_response = true;
    234312
    235         DEBUG(4,("finddcs: performing CLDAP query on %s\n", state->netlogon->in.dest_address));
    236 
    237         subreq = cldap_netlogon_send(state, state->cldap, state->netlogon);
    238         if (tevent_req_nomem(subreq, state->req)) {
     313        DEBUG(4,("finddcs: performing CLDAP query on %s\n",
     314                 state->srv_addresses[state->srv_address_index]));
     315
     316        subreq = cldap_netlogon_send(state, state->ev,
     317                                     state->cldap, state->netlogon);
     318        if (subreq == NULL) {
     319                state->status = NT_STATUS_NO_MEMORY;
     320                state->srv_address_index++;
     321                finddcs_cldap_next_server(state);
    239322                return;
    240323        }
     
    255338
    256339        status = cldap_netlogon_recv(subreq, state->netlogon, state->netlogon);
    257         talloc_free(subreq);
     340        TALLOC_FREE(subreq);
     341        TALLOC_FREE(state->cldap);
    258342        if (!NT_STATUS_IS_OK(status)) {
     343                state->status = status;
    259344                state->srv_address_index++;
    260345                finddcs_cldap_next_server(state);
     
    280365}
    281366
    282 /*
    283    handle NBT name lookup reply
    284  */
    285367static void finddcs_cldap_name_resolved(struct composite_context *ctx)
    286368{
    287369        struct finddcs_cldap_state *state =
    288370                talloc_get_type(ctx->async.private_data, struct finddcs_cldap_state);
    289         const char *address;
    290         NTSTATUS status;
    291 
    292         status = resolve_name_recv(ctx, state, &address);
     371        NTSTATUS status;
     372        unsigned i;
     373
     374        status = resolve_name_multiple_recv(ctx, state, &state->srv_addresses);
     375        if (tevent_req_nterror(state->req, status)) {
     376                DEBUG(2,("finddcs: No matching server found\n"));
     377                return;
     378        }
     379
     380        for (i=0; state->srv_addresses[i]; i++) {
     381                DEBUG(4,("finddcs: response %u at '%s'\n",
     382                         i, state->srv_addresses[i]));
     383        }
     384
     385        state->srv_address_index = 0;
     386
     387        state->status = NT_STATUS_OK;
     388        finddcs_cldap_next_server(state);
     389}
     390
     391/*
     392   handle NBT name lookup reply
     393 */
     394static void finddcs_cldap_nbt_resolved(struct composite_context *ctx)
     395{
     396        struct finddcs_cldap_state *state =
     397                talloc_get_type(ctx->async.private_data, struct finddcs_cldap_state);
     398        NTSTATUS status;
     399        unsigned i;
     400
     401        status = resolve_name_multiple_recv(ctx, state, &state->srv_addresses);
    293402        if (tevent_req_nterror(state->req, status)) {
    294403                DEBUG(2,("finddcs: No matching NBT <1c> server found\n"));
     
    296405        }
    297406
    298         DEBUG(4,("finddcs: Found NBT <1c> server at %s\n", address));
    299 
    300         state->srv_addresses = talloc_array(state, const char *, 2);
    301         if (tevent_req_nomem(state->srv_addresses, state->req)) {
    302                 return;
    303         }
    304         state->srv_addresses[0] = address;
    305         state->srv_addresses[1] = NULL;
     407        for (i=0; state->srv_addresses[i]; i++) {
     408                DEBUG(4,("finddcs: NBT <1c> response %u at '%s'\n",
     409                         i, state->srv_addresses[i]));
     410        }
    306411
    307412        state->srv_address_index = 0;
    308 
    309         status = cldap_socket_init(state, state->ev, NULL, NULL, &state->cldap);
    310         if (tevent_req_nterror(state->req, status)) {
    311                 return;
    312         }
    313413
    314414        finddcs_cldap_next_server(state);
     
    338438        state->srv_address_index = 0;
    339439
    340         status = cldap_socket_init(state, state->ev, NULL, NULL, &state->cldap);
    341         if (tevent_req_nterror(state->req, status)) {
    342                 return;
    343         }
    344 
     440        state->status = NT_STATUS_OK;
    345441        finddcs_cldap_next_server(state);
    346442}
     
    358454                return NT_STATUS_INTERNAL_ERROR;
    359455        }
    360         status = tevent_req_simple_recv_ntstatus(req);
    361         if (NT_STATUS_IS_OK(status)) {
    362                 talloc_steal(mem_ctx, state->netlogon);
    363                 io->out.netlogon = state->netlogon->out.netlogon;
    364                 io->out.address = talloc_steal(mem_ctx, state->srv_addresses[state->srv_address_index]);
    365         }
     456        if (tevent_req_is_nterror(req, &status)) {
     457                tevent_req_received(req);
     458                return status;
     459        }
     460
     461        talloc_steal(mem_ctx, state->netlogon);
     462        io->out.netlogon = state->netlogon->out.netlogon;
     463        io->out.address = talloc_steal(
     464                mem_ctx, state->srv_addresses[state->srv_address_index]);
     465
    366466        tevent_req_received(req);
    367         return status;
     467        return NT_STATUS_OK;
    368468}
    369469
  • vendor/current/source4/libcli/finddcs_nbt.c

    r740 r988  
    2929#include "libcli/resolve/resolve.h"
    3030#include "lib/util/tevent_ntstatus.h"
     31#include "libcli/finddc.h"
    3132
    3233struct finddcs_nbt_state {
    3334        struct tevent_context *ev;
    3435        struct tevent_req *req;
    35         struct messaging_context *msg_ctx;
     36        struct imessaging_context *msg_ctx;
    3637
    3738        const char *my_netbios_name;
     
    7071                                struct resolve_context *resolve_ctx,
    7172                                struct tevent_context *event_ctx,
    72                                 struct messaging_context *msg_ctx)
     73                                struct imessaging_context *msg_ctx)
    7374{
    7475        struct finddcs_nbt_state *state;
     
    9596
    9697        if (domain_sid) {
    97                 state->domain_sid = talloc_reference(state, domain_sid);
     98                state->domain_sid = dom_sid_dup(state, domain_sid);
    9899                if (tevent_req_nomem(state->domain_sid, req)) {
    99100                        return tevent_req_post(req, event_ctx);
     
    284285                *dcs = talloc_steal(mem_ctx, state->dcs);
    285286        }
    286         talloc_free(req);
    287287        return status;
    288288}
     
    295295                 struct resolve_context *resolve_ctx,
    296296                 struct tevent_context *event_ctx,
    297                  struct messaging_context *msg_ctx,
     297                 struct imessaging_context *msg_ctx,
    298298                 int *num_dcs, struct nbt_dc_name **dcs)
    299299{
     300        NTSTATUS status;
    300301        struct tevent_req *req = finddcs_nbt_send(mem_ctx,
    301302                                              my_netbios_name,
     
    305306                                              resolve_ctx,
    306307                                              event_ctx, msg_ctx);
    307         return finddcs_nbt_recv(req, mem_ctx, num_dcs, dcs);
    308 }
     308        status = finddcs_nbt_recv(req, mem_ctx, num_dcs, dcs);
     309        talloc_free(req);
     310        return status;
     311}
  • vendor/current/source4/libcli/ldap/ldap_bind.c

    r740 r988  
    2828#include "lib/tls/tls.h"
    2929#include "auth/gensec/gensec.h"
     30#include "auth/gensec/gensec_internal.h" /* TODO: remove this */
     31#include "source4/auth/gensec/gensec_tstream.h"
    3032#include "auth/credentials/credentials.h"
    3133#include "lib/stream/packet.h"
    3234#include "param/param.h"
     35#include "param/loadparm.h"
    3336
    3437struct ldap_simple_creds {
     
    214217        struct ldap_SearchResEntry *search;
    215218        int count, i;
    216 
     219        bool first = true;
     220        int wrap_flags = 0;
    217221        const char **sasl_names;
    218222        uint32_t old_gensec_features;
     
    221225                NULL
    222226        };
    223 
    224         gensec_init(lp_ctx);
     227        unsigned int logon_retries = 0;
     228        size_t queue_length;
     229
     230        if (conn->sockets.active == NULL) {
     231                status = NT_STATUS_CONNECTION_DISCONNECTED;
     232                goto failed;
     233        }
     234
     235        queue_length = tevent_queue_length(conn->sockets.send_queue);
     236        if (queue_length != 0) {
     237                status = NT_STATUS_INVALID_PARAMETER_MIX;
     238                DEBUG(1, ("SASL bind triggered with non empty send_queue[%zu]: %s\n",
     239                          queue_length, nt_errstr(status)));
     240                goto failed;
     241        }
     242
     243        if (conn->pending != NULL) {
     244                status = NT_STATUS_INVALID_PARAMETER_MIX;
     245                DEBUG(1, ("SASL bind triggered with pending requests: %s\n",
     246                          nt_errstr(status)));
     247                goto failed;
     248        }
     249
     250        status = ildap_search(conn, "", LDAP_SEARCH_SCOPE_BASE, "", supported_sasl_mech_attrs,
     251                              false, NULL, NULL, &sasl_mechs_msgs);
     252        if (!NT_STATUS_IS_OK(status)) {
     253                DEBUG(1, ("Failed to inquire of target's available sasl mechs in rootdse search: %s\n",
     254                          nt_errstr(status)));
     255                goto failed;
     256        }
     257
     258        count = ildap_count_entries(conn, sasl_mechs_msgs);
     259        if (count != 1) {
     260                DEBUG(1, ("Failed to inquire of target's available sasl mechs in rootdse search: wrong number of replies: %d\n",
     261                          count));
     262                goto failed;
     263        }
     264
     265        tmp_ctx = talloc_new(conn);
     266        if (tmp_ctx == NULL) goto failed;
     267
     268        search = &sasl_mechs_msgs[0]->r.SearchResultEntry;
     269        if (search->num_attributes != 1) {
     270                DEBUG(1, ("Failed to inquire of target's available sasl mechs in rootdse search: wrong number of attributes: %d != 1\n",
     271                          search->num_attributes));
     272                goto failed;
     273        }
     274
     275        sasl_names = talloc_array(tmp_ctx, const char *, search->attributes[0].num_values + 1);
     276        if (!sasl_names) {
     277                DEBUG(1, ("talloc_arry(char *, %d) failed\n",
     278                          count));
     279                goto failed;
     280        }
     281
     282        for (i=0; i<search->attributes[0].num_values; i++) {
     283                sasl_names[i] = (const char *)search->attributes[0].values[i].data;
     284        }
     285        sasl_names[i] = NULL;
     286
     287        gensec_init();
     288
     289        if (conn->sockets.active == conn->sockets.tls) {
     290                /*
     291                 * require Kerberos SIGN/SEAL only if we don't use SSL
     292                 * Windows seem not to like double encryption
     293                 */
     294                wrap_flags = 0;
     295        } else if (cli_credentials_is_anonymous(creds)) {
     296                /*
     297                 * anonymous isn't protected
     298                 */
     299                wrap_flags = 0;
     300        } else {
     301                wrap_flags = lpcfg_client_ldap_sasl_wrapping(lp_ctx);
     302        }
     303
     304try_logon_again:
     305        /*
     306          we loop back here on a logon failure, and re-create the
     307          gensec session. The logon_retries counter ensures we don't
     308          loop forever.
     309         */
     310        data_blob_free(&input);
     311        TALLOC_FREE(conn->gensec);
    225312
    226313        status = gensec_client_start(conn, &conn->gensec,
    227                                      conn->event.event_ctx,
    228314                                     lpcfg_gensec_settings(conn, lp_ctx));
    229315        if (!NT_STATUS_IS_OK(status)) {
     
    232318        }
    233319
    234         /* require Kerberos SIGN/SEAL only if we don't use SSL
    235          * Windows seem not to like double encryption */
    236320        old_gensec_features = cli_credentials_get_gensec_features(creds);
    237         if (tls_enabled(conn->sock)) {
     321        if (wrap_flags == 0) {
    238322                cli_credentials_set_gensec_features(creds, old_gensec_features & ~(GENSEC_FEATURE_SIGN|GENSEC_FEATURE_SEAL));
    239323        }
     
    250334         * context, so we don't tatoo it ) */
    251335        cli_credentials_set_gensec_features(creds, old_gensec_features);
     336
     337        if (wrap_flags & ADS_AUTH_SASL_SEAL) {
     338                gensec_want_feature(conn->gensec, GENSEC_FEATURE_SIGN);
     339                gensec_want_feature(conn->gensec, GENSEC_FEATURE_SEAL);
     340        }
     341        if (wrap_flags & ADS_AUTH_SASL_SIGN) {
     342                gensec_want_feature(conn->gensec, GENSEC_FEATURE_SIGN);
     343        }
     344
     345        /*
     346         * This is an indication for the NTLMSSP backend to
     347         * also encrypt when only GENSEC_FEATURE_SIGN is requested
     348         * in gensec_[un]wrap().
     349         */
     350        gensec_want_feature(conn->gensec, GENSEC_FEATURE_LDAP_STYLE);
    252351
    253352        if (conn->host) {
     
    267366        }
    268367
    269         status = ildap_search(conn, "", LDAP_SEARCH_SCOPE_BASE, "", supported_sasl_mech_attrs,
    270                               false, NULL, NULL, &sasl_mechs_msgs);
    271         if (!NT_STATUS_IS_OK(status)) {
    272                 DEBUG(1, ("Failed to inquire of target's available sasl mechs in rootdse search: %s\n",
    273                           nt_errstr(status)));
    274                 goto failed;
    275         }
    276        
    277         count = ildap_count_entries(conn, sasl_mechs_msgs);
    278         if (count != 1) {
    279                 DEBUG(1, ("Failed to inquire of target's available sasl mechs in rootdse search: wrong number of replies: %d\n",
    280                           count));
    281                 goto failed;
    282         }
    283 
    284         tmp_ctx = talloc_new(conn);
    285         if (tmp_ctx == NULL) goto failed;
    286 
    287         search = &sasl_mechs_msgs[0]->r.SearchResultEntry;
    288         if (search->num_attributes != 1) {
    289                 DEBUG(1, ("Failed to inquire of target's available sasl mechs in rootdse search: wrong number of attributes: %d != 1\n",
    290                           search->num_attributes));
    291                 goto failed;
    292         }
    293 
    294         sasl_names = talloc_array(tmp_ctx, const char *, search->attributes[0].num_values + 1);
    295         if (!sasl_names) {
    296                 DEBUG(1, ("talloc_arry(char *, %d) failed\n",
    297                           count));
    298                 goto failed;
    299         }
    300                
    301         for (i=0; i<search->attributes[0].num_values; i++) {
    302                 sasl_names[i] = (const char *)search->attributes[0].values[i].data;
    303         }
    304         sasl_names[i] = NULL;
    305        
    306368        status = gensec_start_mech_by_sasl_list(conn->gensec, sasl_names);
    307369        if (!NT_STATUS_IS_OK(status)) {
     
    318380                int result = LDAP_OTHER;
    319381       
    320                 status = gensec_update(conn->gensec, tmp_ctx,
     382                status = gensec_update_ev(conn->gensec, tmp_ctx,
     383                                       conn->event.event_ctx,
    321384                                       input,
    322385                                       &output);
     
    328391                 *
    329392                 * Likewise, you must not feed GENSEC too much (after the OK),
    330                  * it doesn't like that either
     393                 * it doesn't like that either.
     394                 *
     395                 * For SASL/EXTERNAL, there is no data to send, but we still
     396                 * must send the actual Bind request the first time around.
     397                 * Otherwise, a result of NT_STATUS_OK with 0 output means the
     398                 * end of a multi-step authentication, and no message must be
     399                 * sent.
    331400                 */
    332401
     
    338407                }
    339408                if (NT_STATUS_IS_OK(status) && output.length == 0) {
    340                         break;
    341                 }
     409                        if (!first)
     410                                break;
     411                }
     412                first = false;
    342413
    343414                /* Perhaps we should make gensec_start_mech_by_sasl_list() return the name we got? */
     
    367438                result = response->r.BindResponse.response.resultcode;
    368439
     440                if (result == LDAP_STRONG_AUTH_REQUIRED) {
     441                        if (wrap_flags == 0) {
     442                                wrap_flags = ADS_AUTH_SASL_SIGN;
     443                                goto try_logon_again;
     444                        }
     445                }
     446
     447                if (result == LDAP_INVALID_CREDENTIALS) {
     448                        /*
     449                          try a second time on invalid credentials, to
     450                          give the user a chance to re-enter the
     451                          password and to handle the case where our
     452                          kerberos ticket is invalid as the server
     453                          password has changed
     454                        */
     455                        const char *principal;
     456
     457                        principal = gensec_get_target_principal(conn->gensec);
     458                        if (principal == NULL) {
     459                                const char *hostname = gensec_get_target_hostname(conn->gensec);
     460                                const char *service  = gensec_get_target_service(conn->gensec);
     461                                if (hostname != NULL && service != NULL) {
     462                                        principal = talloc_asprintf(tmp_ctx, "%s/%s", service, hostname);
     463                                }
     464                        }
     465
     466                        if (cli_credentials_failed_kerberos_login(creds, principal, &logon_retries) ||
     467                            cli_credentials_wrong_password(creds)) {
     468                                /*
     469                                  destroy our gensec session and loop
     470                                  back up to the top to retry,
     471                                  offering the user a chance to enter
     472                                  new credentials, or get a new ticket
     473                                  if using kerberos
     474                                 */
     475                                goto try_logon_again;
     476                        }
     477                }
     478
    369479                if (result != LDAP_SUCCESS && result != LDAP_SASL_BIND_IN_PROGRESS) {
    370480                        status = ldap_check_response(conn,
     
    384494        }
    385495
    386         talloc_free(tmp_ctx);
    387 
    388         if (NT_STATUS_IS_OK(status)) {
    389                 struct socket_context *sasl_socket;
    390                 status = gensec_socket_init(conn->gensec,
    391                                             conn,
    392                                             conn->sock,
    393                                             conn->event.event_ctx,
    394                                             ldap_read_io_handler,
    395                                             conn,
    396                                             &sasl_socket);
    397                 if (!NT_STATUS_IS_OK(status)) goto failed;
    398 
    399                 conn->sock = sasl_socket;
    400                 packet_set_socket(conn->packet, conn->sock);
    401 
    402                 conn->bind.type = LDAP_BIND_SASL;
    403                 conn->bind.creds = creds;
    404         }
    405 
    406         return status;
     496        TALLOC_FREE(tmp_ctx);
     497
     498        if (!NT_STATUS_IS_OK(status)) {
     499                goto failed;
     500        }
     501
     502        conn->bind.type = LDAP_BIND_SASL;
     503        conn->bind.creds = creds;
     504
     505        if (wrap_flags & ADS_AUTH_SASL_SEAL) {
     506                if (!gensec_have_feature(conn->gensec, GENSEC_FEATURE_SIGN)) {
     507                        return NT_STATUS_INVALID_NETWORK_RESPONSE;
     508                }
     509
     510                if (!gensec_have_feature(conn->gensec, GENSEC_FEATURE_SEAL)) {
     511                        return NT_STATUS_INVALID_NETWORK_RESPONSE;
     512                }
     513        } else if (wrap_flags & ADS_AUTH_SASL_SIGN) {
     514                if (!gensec_have_feature(conn->gensec, GENSEC_FEATURE_SIGN)) {
     515                        return NT_STATUS_INVALID_NETWORK_RESPONSE;
     516                }
     517        }
     518
     519        if (!gensec_have_feature(conn->gensec, GENSEC_FEATURE_SIGN) &&
     520            !gensec_have_feature(conn->gensec, GENSEC_FEATURE_SEAL)) {
     521                return NT_STATUS_OK;
     522        }
     523
     524        status = gensec_create_tstream(conn->sockets.raw,
     525                                       conn->gensec,
     526                                       conn->sockets.raw,
     527                                       &conn->sockets.sasl);
     528        if (!NT_STATUS_IS_OK(status)) {
     529                goto failed;
     530        }
     531
     532        conn->sockets.active = conn->sockets.sasl;
     533
     534        return NT_STATUS_OK;
    407535
    408536failed:
  • vendor/current/source4/libcli/ldap/ldap_client.c

    r740 r988  
    2626#include <tevent.h>
    2727#include "lib/socket/socket.h"
     28#include "lib/tsocket/tsocket.h"
     29#include "libcli/util/tstream.h"
    2830#include "../lib/util/asn1.h"
    2931#include "../lib/util/dlinklist.h"
     
    3234#include "libcli/ldap/ldap_client.h"
    3335#include "libcli/composite/composite.h"
    34 #include "lib/stream/packet.h"
    3536#include "lib/tls/tls.h"
    3637#include "auth/gensec/gensec.h"
     
    3940#include "libcli/resolve/resolve.h"
    4041
     42static void ldap_connection_dead(struct ldap_connection *conn, NTSTATUS status);
     43
     44static int ldap_connection_destructor(struct ldap_connection *conn)
     45{
     46        /*
     47         * NT_STATUS_OK means that callbacks of pending requests are not
     48         * triggered
     49         */
     50        ldap_connection_dead(conn, NT_STATUS_OK);
     51        return 0;
     52}
     53
    4154/**
    4255  create a new ldap_connection stucture. The event context is optional
    4356*/
     57
    4458_PUBLIC_ struct ldap_connection *ldap4_new_connection(TALLOC_CTX *mem_ctx,
    4559                                             struct loadparm_context *lp_ctx,
     
    6074        conn->event.event_ctx = ev;
    6175
     76        conn->sockets.send_queue = tevent_queue_create(conn,
     77                                        "ldap_connection send_queue");
     78        if (conn->sockets.send_queue == NULL) {
     79                TALLOC_FREE(conn);
     80                return NULL;
     81        }
     82
    6283        conn->lp_ctx = lp_ctx;
    6384
     
    6788        /* explicitly avoid reconnections by default */
    6889        conn->reconnect.max_retries = 0;
    69        
     90
     91        talloc_set_destructor(conn, ldap_connection_destructor);
    7092        return conn;
    7193}
     
    7496  the connection is dead
    7597*/
    76 static void ldap_connection_dead(struct ldap_connection *conn)
     98static void ldap_connection_dead(struct ldap_connection *conn, NTSTATUS status)
    7799{
    78100        struct ldap_request *req;
    79101
    80         talloc_free(conn->sock);  /* this will also free event.fde */
    81         talloc_free(conn->packet);
    82         conn->sock = NULL;
    83         conn->event.fde = NULL;
    84         conn->packet = NULL;
     102        tevent_queue_stop(conn->sockets.send_queue);
     103        TALLOC_FREE(conn->sockets.recv_subreq);
     104        conn->sockets.active = NULL;
     105        TALLOC_FREE(conn->sockets.sasl);
     106        TALLOC_FREE(conn->sockets.tls);
     107        TALLOC_FREE(conn->sockets.raw);
    85108
    86109        /* return an error for any pending request ... */
     
    88111                req = conn->pending;
    89112                DLIST_REMOVE(req->conn->pending, req);
     113                req->conn = NULL;
    90114                req->state = LDAP_REQUEST_DONE;
    91                 req->status = NT_STATUS_UNEXPECTED_NETWORK_ERROR;
     115                if (NT_STATUS_IS_OK(status)) {
     116                        continue;
     117                }
     118                req->status = status;
    92119                if (req->async.fn) {
    93120                        req->async.fn(req);
     
    101128  handle packet errors
    102129*/
    103 static void ldap_error_handler(void *private_data, NTSTATUS status)
    104 {
    105         struct ldap_connection *conn = talloc_get_type(private_data,
    106                                                        struct ldap_connection);
    107         ldap_connection_dead(conn);
     130static void ldap_error_handler(struct ldap_connection *conn, NTSTATUS status)
     131{
     132        ldap_connection_dead(conn, status);
    108133
    109134        /* but try to reconnect so that the ldb client can go on */
     
    131156                DEBUG(0,("ldap: no matching message id for %u\n",
    132157                         msg->messageid));
    133                 talloc_free(msg);
     158                TALLOC_FREE(msg);
    134159                return;
    135160        }
     
    139164                if (!msg->controls_decoded[i] &&
    140165                    msg->controls[i]->critical) {
     166                        TALLOC_FREE(msg);
    141167                        req->status = NT_STATUS_LDAP(LDAP_UNAVAILABLE_CRITICAL_EXTENSION);
    142168                        req->state = LDAP_REQUEST_DONE;
     
    150176
    151177        /* add to the list of replies received */
    152         talloc_steal(req, msg);
    153178        req->replies = talloc_realloc(req, req->replies,
    154179                                      struct ldap_message *, req->num_replies+1);
    155180        if (req->replies == NULL) {
     181                TALLOC_FREE(msg);
    156182                req->status = NT_STATUS_NO_MEMORY;
    157183                req->state = LDAP_REQUEST_DONE;
     
    179205}
    180206
     207static void ldap_connection_recv_done(struct tevent_req *subreq);
     208
     209static void ldap_connection_recv_next(struct ldap_connection *conn)
     210{
     211        struct tevent_req *subreq = NULL;
     212
     213        if (conn->sockets.recv_subreq != NULL) {
     214                return;
     215        }
     216
     217        if (conn->sockets.active == NULL) {
     218                return;
     219        }
     220
     221        if (conn->pending == NULL) {
     222                return;
     223        }
     224
     225        /*
     226         * The minimum size of a LDAP pdu is 7 bytes
     227         *
     228         * dumpasn1 -hh ldap-unbind-min.dat
     229         *
     230         *     <30 05 02 01 09 42 00>
     231         *    0    5: SEQUENCE {
     232         *     <02 01 09>
     233         *    2    1:   INTEGER 9
     234         *     <42 00>
     235         *    5    0:   [APPLICATION 2]
     236         *          :     Error: Object has zero length.
     237         *          :   }
     238         *
     239         * dumpasn1 -hh ldap-unbind-windows.dat
     240         *
     241         *     <30 84 00 00 00 05 02 01 09 42 00>
     242         *    0    5: SEQUENCE {
     243         *     <02 01 09>
     244         *    6    1:   INTEGER 9
     245         *     <42 00>
     246         *    9    0:   [APPLICATION 2]
     247         *          :     Error: Object has zero length.
     248         *          :   }
     249         *
     250         * This means using an initial read size
     251         * of 7 is ok.
     252         */
     253        subreq = tstream_read_pdu_blob_send(conn,
     254                                            conn->event.event_ctx,
     255                                            conn->sockets.active,
     256                                            7, /* initial_read_size */
     257                                            ldap_full_packet,
     258                                            conn);
     259        if (subreq == NULL) {
     260                ldap_error_handler(conn, NT_STATUS_NO_MEMORY);
     261                return;
     262        }
     263        tevent_req_set_callback(subreq, ldap_connection_recv_done, conn);
     264        conn->sockets.recv_subreq = subreq;
     265        return;
     266}
    181267
    182268/*
    183269  decode/process LDAP data
    184270*/
    185 static NTSTATUS ldap_recv_handler(void *private_data, DATA_BLOB blob)
     271static void ldap_connection_recv_done(struct tevent_req *subreq)
    186272{
    187273        NTSTATUS status;
    188         struct ldap_connection *conn = talloc_get_type(private_data,
    189                                                        struct ldap_connection);
    190         struct ldap_message *msg = talloc(conn, struct ldap_message);
    191         struct asn1_data *asn1 = asn1_init(conn);
    192 
    193         if (asn1 == NULL || msg == NULL) {
    194                 return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR);
    195         }
    196 
    197         if (!asn1_load(asn1, blob)) {
    198                 talloc_free(msg);
    199                 talloc_free(asn1);
    200                 return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR);
    201         }
    202        
     274        struct ldap_connection *conn =
     275                tevent_req_callback_data(subreq,
     276                struct ldap_connection);
     277        struct ldap_message *msg;
     278        struct asn1_data *asn1;
     279        DATA_BLOB blob;
     280
     281        msg = talloc_zero(conn, struct ldap_message);
     282        if (msg == NULL) {
     283                ldap_error_handler(conn, NT_STATUS_NO_MEMORY);
     284                return;
     285        }
     286
     287        asn1 = asn1_init(conn);
     288        if (asn1 == NULL) {
     289                TALLOC_FREE(msg);
     290                ldap_error_handler(conn, NT_STATUS_NO_MEMORY);
     291                return;
     292        }
     293
     294        conn->sockets.recv_subreq = NULL;
     295
     296        status = tstream_read_pdu_blob_recv(subreq,
     297                                            asn1,
     298                                            &blob);
     299        TALLOC_FREE(subreq);
     300        if (!NT_STATUS_IS_OK(status)) {
     301                TALLOC_FREE(msg);
     302                asn1_free(asn1);
     303                ldap_error_handler(conn, status);
     304                return;
     305        }
     306
     307        asn1_load_nocopy(asn1, blob.data, blob.length);
     308
    203309        status = ldap_decode(asn1, samba_ldap_control_handlers(), msg);
     310        asn1_free(asn1);
    204311        if (!NT_STATUS_IS_OK(status)) {
    205                 asn1_free(asn1);
    206                 return status;
     312                TALLOC_FREE(msg);
     313                ldap_error_handler(conn, status);
     314                return;
    207315        }
    208316
    209317        ldap_match_message(conn, msg);
    210 
    211         data_blob_free(&blob);
    212         asn1_free(asn1);
    213         return NT_STATUS_OK;
    214 }
    215 
    216 /* Handle read events, from the GENSEC socket callback, or real events */
    217 void ldap_read_io_handler(void *private_data, uint16_t flags)
    218 {
    219         struct ldap_connection *conn = talloc_get_type(private_data,
    220                                                        struct ldap_connection);
    221         packet_recv(conn->packet);
    222 }
    223 
    224 /*
    225   handle ldap socket events
    226 */
    227 static void ldap_io_handler(struct tevent_context *ev, struct tevent_fd *fde,
    228                             uint16_t flags, void *private_data)
    229 {
    230         struct ldap_connection *conn = talloc_get_type(private_data,
    231                                                        struct ldap_connection);
    232         if (flags & TEVENT_FD_WRITE) {
    233                 packet_queue_run(conn->packet);
    234                 if (!tls_enabled(conn->sock)) return;
    235         }
    236         if (flags & TEVENT_FD_READ) {
    237                 ldap_read_io_handler(private_data, flags);
    238         }
     318        ldap_connection_recv_next(conn);
     319
     320        return;
    239321}
    240322
     
    285367        struct composite_context *ctx;
    286368        struct ldap_connection *conn;
     369        struct socket_context *sock;
     370        struct tstream_context *raw;
     371        struct tstream_tls_params *tls_params;
     372        struct tstream_context *tls;
    287373};
    288374
     
    328414                char path[1025];
    329415       
    330                 NTSTATUS status = socket_create("unix", SOCKET_TYPE_STREAM, &conn->sock, 0);
     416                NTSTATUS status = socket_create("unix", SOCKET_TYPE_STREAM, &state->sock, 0);
    331417                if (!NT_STATUS_IS_OK(status)) {
    332418                        return NULL;
    333419                }
    334                 talloc_steal(conn, conn->sock);
     420                talloc_steal(state, state->sock);
    335421                SMB_ASSERT(sizeof(protocol)>10);
    336422                SMB_ASSERT(sizeof(path)>1024);
     
    355441
    356442                rfc1738_unescape(path);
    357        
    358                 unix_addr = socket_address_from_strings(conn, conn->sock->backend_name,
     443
     444                unix_addr = socket_address_from_strings(state, state->sock->backend_name,
    359445                                                        path, 0);
    360                 if (!unix_addr) {
    361                         return NULL;
    362                 }
    363 
    364                 ctx = socket_connect_send(conn->sock, NULL, unix_addr,
    365                                           0, conn->event.event_ctx);
     446                if (composite_nomem(unix_addr, result)) {
     447                        return result;
     448                }
     449
     450
     451                ctx = socket_connect_send(state->sock, NULL, unix_addr,
     452                                          0, result->event_ctx);
    366453                ctx->async.fn = ldap_connect_recv_unix_conn;
    367454                ctx->async.private_data = state;
     
    370457                NTSTATUS status = ldap_parse_basic_url(conn, url, &conn->host,
    371458                                                          &conn->port, &conn->ldaps);
    372                 if (!NT_STATUS_IS_OK(state->ctx->status)) {
    373                         composite_error(state->ctx, status);
     459                if (!NT_STATUS_IS_OK(status)) {
     460                        composite_error(result, status);
    374461                        return result;
    375462                }
    376                
     463
     464                if (conn->ldaps) {
     465                        char *ca_file = lpcfg_tls_cafile(state, conn->lp_ctx);
     466                        char *crl_file = lpcfg_tls_crlfile(state, conn->lp_ctx);
     467                        const char *tls_priority = lpcfg_tls_priority(conn->lp_ctx);
     468                        enum tls_verify_peer_state verify_peer =
     469                                lpcfg_tls_verify_peer(conn->lp_ctx);
     470
     471                        status = tstream_tls_params_client(state,
     472                                                           ca_file,
     473                                                           crl_file,
     474                                                           tls_priority,
     475                                                           verify_peer,
     476                                                           conn->host,
     477                                                           &state->tls_params);
     478                        if (!NT_STATUS_IS_OK(status)) {
     479                                composite_error(result, status);
     480                                return result;
     481                        }
     482                }
     483
    377484                ctx = socket_connect_multi_send(state, conn->host, 1, &conn->port,
    378                                                 lpcfg_resolve_context(conn->lp_ctx), conn->event.event_ctx);
    379                 if (ctx == NULL) goto failed;
     485                                                lpcfg_resolve_context(conn->lp_ctx),
     486                                                result->event_ctx);
     487                if (composite_nomem(ctx, result)) {
     488                        return result;
     489                }
    380490
    381491                ctx->async.fn = ldap_connect_recv_tcp_conn;
     
    388498}
    389499
     500static void ldap_connect_got_tls(struct tevent_req *subreq);
     501
    390502static void ldap_connect_got_sock(struct composite_context *ctx,
    391                                   struct ldap_connection *conn)
    392 {
    393         /* setup a handler for events on this socket */
    394         conn->event.fde = tevent_add_fd(conn->event.event_ctx, conn->sock,
    395                                         socket_get_fd(conn->sock),
    396                                         TEVENT_FD_READ, ldap_io_handler, conn);
    397         if (conn->event.fde == NULL) {
    398                 composite_error(ctx, NT_STATUS_INTERNAL_ERROR);
    399                 return;
    400         }
    401 
    402         tevent_fd_set_close_fn(conn->event.fde, socket_tevent_fd_close_fn);
    403         socket_set_flags(conn->sock, SOCKET_FLAG_NOCLOSE);
    404 
    405         talloc_steal(conn, conn->sock);
    406         if (conn->ldaps) {
    407                 struct socket_context *tls_socket;
    408                 char *cafile = lpcfg_tls_cafile(conn->sock, conn->lp_ctx);
    409 
    410                 if (!cafile || !*cafile) {
    411                         talloc_free(conn->sock);
    412                         return;
    413                 }
    414 
    415                 tls_socket = tls_init_client(conn->sock, conn->event.fde, cafile);
    416                 talloc_free(cafile);
    417 
    418                 if (tls_socket == NULL) {
    419                         talloc_free(conn->sock);
    420                         return;
    421                 }
    422 
    423                 conn->sock = talloc_steal(conn, tls_socket);
    424         }
    425 
    426         conn->packet = packet_init(conn);
    427         if (conn->packet == NULL) {
    428                 talloc_free(conn->sock);
    429                 return;
    430         }
    431 
    432         packet_set_private(conn->packet, conn);
    433         packet_set_socket(conn->packet, conn->sock);
    434         packet_set_callback(conn->packet, ldap_recv_handler);
    435         packet_set_full_request(conn->packet, ldap_full_packet);
    436         packet_set_error_handler(conn->packet, ldap_error_handler);
    437         packet_set_event_context(conn->packet, conn->event.event_ctx);
    438         packet_set_fde(conn->packet, conn->event.fde);
    439 /*      packet_set_serialise(conn->packet); */
    440 
    441         if (conn->ldaps) {
    442                 packet_set_unreliable_select(conn->packet);
    443         }
    444 
    445         composite_done(ctx);
     503                                  struct ldap_connection *conn)
     504{
     505        struct ldap_connect_state *state =
     506                talloc_get_type_abort(ctx->private_data,
     507                struct ldap_connect_state);
     508        struct tevent_req *subreq = NULL;
     509        int fd;
     510        int ret;
     511
     512        socket_set_flags(state->sock, SOCKET_FLAG_NOCLOSE);
     513        fd = socket_get_fd(state->sock);
     514        TALLOC_FREE(state->sock);
     515
     516        smb_set_close_on_exec(fd);
     517
     518        ret = set_blocking(fd, false);
     519        if (ret == -1) {
     520                NTSTATUS status = map_nt_error_from_unix_common(errno);
     521                composite_error(state->ctx, status);
     522                return;
     523        }
     524
     525        ret = tstream_bsd_existing_socket(state, fd, &state->raw);
     526        if (ret == -1) {
     527                NTSTATUS status = map_nt_error_from_unix_common(errno);
     528                composite_error(state->ctx, status);
     529                return;
     530        }
     531
     532        if (!conn->ldaps) {
     533                conn->sockets.raw = talloc_move(conn, &state->raw);
     534                conn->sockets.active = conn->sockets.raw;
     535                composite_done(state->ctx);
     536                return;
     537        }
     538
     539        subreq = tstream_tls_connect_send(state, state->ctx->event_ctx,
     540                                          state->raw, state->tls_params);
     541        if (composite_nomem(subreq, state->ctx)) {
     542                return;
     543        }
     544        tevent_req_set_callback(subreq, ldap_connect_got_tls, state);
     545}
     546
     547static void ldap_connect_got_tls(struct tevent_req *subreq)
     548{
     549        struct ldap_connect_state *state =
     550                tevent_req_callback_data(subreq,
     551                struct ldap_connect_state);
     552        int err;
     553        int ret;
     554
     555        ret = tstream_tls_connect_recv(subreq, &err, state, &state->tls);
     556        TALLOC_FREE(subreq);
     557        if (ret == -1) {
     558                NTSTATUS status = map_nt_error_from_unix_common(err);
     559                composite_error(state->ctx, status);
     560                return;
     561        }
     562
     563        talloc_steal(state->tls, state->tls_params);
     564
     565        state->conn->sockets.raw = talloc_move(state->conn, &state->raw);
     566        state->conn->sockets.tls = talloc_move(state->conn->sockets.raw,
     567                                               &state->tls);
     568        state->conn->sockets.active = state->conn->sockets.tls;
     569        composite_done(state->ctx);
    446570}
    447571
     
    449573{
    450574        struct ldap_connect_state *state =
    451                 talloc_get_type(ctx->async.private_data,
    452                                 struct ldap_connect_state);
     575                talloc_get_type_abort(ctx->async.private_data,
     576                struct ldap_connect_state);
    453577        struct ldap_connection *conn = state->conn;
    454578        uint16_t port;
    455         NTSTATUS status = socket_connect_multi_recv(ctx, state, &conn->sock,
     579        NTSTATUS status = socket_connect_multi_recv(ctx, state, &state->sock,
    456580                                                       &port);
    457581        if (!NT_STATUS_IS_OK(status)) {
     
    466590{
    467591        struct ldap_connect_state *state =
    468                 talloc_get_type(ctx->async.private_data,
    469                                 struct ldap_connect_state);
     592                talloc_get_type_abort(ctx->async.private_data,
     593                struct ldap_connect_state);
    470594        struct ldap_connection *conn = state->conn;
    471595
     
    534658        status = ldap_rebind(conn);
    535659        if ( ! NT_STATUS_IS_OK(status)) {
    536                 ldap_connection_dead(conn);
    537         }
     660                ldap_connection_dead(conn, status);
     661        }
     662}
     663
     664static void ldap_request_destructor_abandon(struct ldap_request *abandon)
     665{
     666        TALLOC_FREE(abandon);
    538667}
    539668
     
    542671{
    543672        if (req->state == LDAP_REQUEST_PENDING) {
     673                struct ldap_message msg = {
     674                        .type = LDAP_TAG_AbandonRequest,
     675                        .r.AbandonRequest.messageid = req->messageid,
     676                };
     677                struct ldap_request *abandon = NULL;
     678
    544679                DLIST_REMOVE(req->conn->pending, req);
    545         }
     680
     681                abandon = ldap_request_send(req->conn, &msg);
     682                if (abandon == NULL) {
     683                        ldap_error_handler(req->conn, NT_STATUS_NO_MEMORY);
     684                        return 0;
     685                }
     686                abandon->async.fn = ldap_request_destructor_abandon;
     687                abandon->async.private_data = NULL;
     688        }
     689
    546690        return 0;
    547691}
    548692
    549 /*
    550   called on timeout of a ldap request
    551 */
    552 static void ldap_request_timeout(struct tevent_context *ev, struct tevent_timer *te,
    553                                       struct timeval t, void *private_data)
    554 {
    555         struct ldap_request *req = talloc_get_type(private_data, struct ldap_request);
    556         req->status = NT_STATUS_IO_TIMEOUT;
     693static void ldap_request_timeout_abandon(struct ldap_request *abandon)
     694{
     695        struct ldap_request *req =
     696                talloc_get_type_abort(abandon->async.private_data,
     697                struct ldap_request);
     698
    557699        if (req->state == LDAP_REQUEST_PENDING) {
    558700                DLIST_REMOVE(req->conn->pending, req);
     
    564706}
    565707
    566 
    567 /*
    568   called on completion of a failed ldap request
    569 */
    570 static void ldap_request_failed_complete(struct tevent_context *ev, struct tevent_timer *te,
     708/*
     709  called on timeout of a ldap request
     710*/
     711static void ldap_request_timeout(struct tevent_context *ev, struct tevent_timer *te,
    571712                                      struct timeval t, void *private_data)
    572713{
    573         struct ldap_request *req = talloc_get_type(private_data, struct ldap_request);
    574         if (req->async.fn) {
    575                 req->async.fn(req);
    576         }
    577 }
    578 
    579 /*
    580   called on completion of a one-way ldap request
    581 */
    582 static void ldap_request_oneway_complete(void *private_data)
    583 {
    584         struct ldap_request *req = talloc_get_type(private_data, struct ldap_request);
     714        struct ldap_request *req =
     715                talloc_get_type_abort(private_data,
     716                struct ldap_request);
     717
     718        req->status = NT_STATUS_IO_TIMEOUT;
    585719        if (req->state == LDAP_REQUEST_PENDING) {
     720                struct ldap_message msg = {
     721                        .type = LDAP_TAG_AbandonRequest,
     722                        .r.AbandonRequest.messageid = req->messageid,
     723                };
     724                struct ldap_request *abandon = NULL;
     725
     726                abandon = ldap_request_send(req->conn, &msg);
     727                if (abandon == NULL) {
     728                        ldap_error_handler(req->conn, NT_STATUS_NO_MEMORY);
     729                        return;
     730                }
     731                talloc_reparent(req->conn, req, abandon);
     732                abandon->async.fn = ldap_request_timeout_abandon;
     733                abandon->async.private_data = req;
    586734                DLIST_REMOVE(req->conn->pending, req);
     735                return;
    587736        }
    588737        req->state = LDAP_REQUEST_DONE;
     
    591740        }
    592741}
     742
     743
     744/*
     745  called on completion of a failed ldap request
     746*/
     747static void ldap_request_failed_complete(struct tevent_context *ev, struct tevent_timer *te,
     748                                      struct timeval t, void *private_data)
     749{
     750        struct ldap_request *req =
     751                talloc_get_type_abort(private_data,
     752                struct ldap_request);
     753
     754        if (req->async.fn) {
     755                req->async.fn(req);
     756        }
     757}
     758
     759static void ldap_request_written(struct tevent_req *subreq);
     760
    593761/*
    594762  send a ldap message - async interface
     
    599767        struct ldap_request *req;
    600768        NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
    601         packet_send_callback_fn_t send_callback = NULL;
     769        struct tevent_req *subreq = NULL;
    602770
    603771        req = talloc_zero(conn, struct ldap_request);
    604772        if (req == NULL) return NULL;
    605773
    606         if (conn->sock == NULL) {
     774        if (conn->sockets.active == NULL) {
    607775                status = NT_STATUS_INVALID_CONNECTION;
    608776                goto failed;
     
    629797        }
    630798
    631         if (req->type == LDAP_TAG_AbandonRequest ||
    632             req->type == LDAP_TAG_UnbindRequest) {
    633                 send_callback = ldap_request_oneway_complete;
    634         }
    635 
    636         status = packet_send_callback(conn->packet, req->data,
    637                                       send_callback, req);
    638         if (!NT_STATUS_IS_OK(status)) {
    639                 goto failed;
    640         }
    641 
    642         req->state = LDAP_REQUEST_PENDING;
    643         DLIST_ADD(conn->pending, req);
    644 
    645799        /* put a timeout on the request */
    646800        req->time_event = tevent_add_timer(conn->event.event_ctx, req,
    647801                                           timeval_current_ofs(conn->timeout, 0),
    648802                                           ldap_request_timeout, req);
     803        if (req->time_event == NULL) {
     804                status = NT_STATUS_NO_MEMORY;
     805                goto failed;
     806        }
     807
     808        req->write_iov.iov_base = req->data.data;
     809        req->write_iov.iov_len = req->data.length;
     810
     811        subreq = tstream_writev_queue_send(req, conn->event.event_ctx,
     812                                           conn->sockets.active,
     813                                           conn->sockets.send_queue,
     814                                           &req->write_iov, 1);
     815        if (subreq == NULL) {
     816                status = NT_STATUS_NO_MEMORY;
     817                goto failed;
     818        }
     819        tevent_req_set_callback(subreq, ldap_request_written, req);
     820
     821        req->state = LDAP_REQUEST_PENDING;
     822        DLIST_ADD(conn->pending, req);
    649823
    650824        return req;
     
    659833}
    660834
     835static void ldap_request_written(struct tevent_req *subreq)
     836{
     837        struct ldap_request *req =
     838                tevent_req_callback_data(subreq,
     839                struct ldap_request);
     840        int err;
     841        ssize_t ret;
     842
     843        ret = tstream_writev_queue_recv(subreq, &err);
     844        TALLOC_FREE(subreq);
     845        if (ret == -1) {
     846                NTSTATUS error = map_nt_error_from_unix_common(err);
     847                ldap_error_handler(req->conn, error);
     848                return;
     849        }
     850
     851        if (req->type == LDAP_TAG_AbandonRequest ||
     852            req->type == LDAP_TAG_UnbindRequest)
     853        {
     854                if (req->state == LDAP_REQUEST_PENDING) {
     855                        DLIST_REMOVE(req->conn->pending, req);
     856                }
     857                req->state = LDAP_REQUEST_DONE;
     858                if (req->async.fn) {
     859                        req->async.fn(req);
     860                }
     861                return;
     862        }
     863
     864        ldap_connection_recv_next(req->conn);
     865}
     866
    661867
    662868/*
     
    668874        while (req->state < LDAP_REQUEST_DONE) {
    669875                if (tevent_loop_once(req->conn->event.event_ctx) != 0) {
     876                        req->state = LDAP_REQUEST_ERROR;
    670877                        req->status = NT_STATUS_UNEXPECTED_NETWORK_ERROR;
    671878                        break;
  • vendor/current/source4/libcli/ldap/ldap_client.h

    r740 r988  
    2121
    2222
     23#include "system/network.h" /* for struct iovec */
    2324#include "libcli/ldap/libcli_ldap.h"
    2425
     
    4041        NTSTATUS status;
    4142        DATA_BLOB data;
     43        struct iovec write_iov;
     44
    4245        struct {
    4346                void (*fn)(struct ldap_request *);
     
    5154/* main context for a ldap client connection */
    5255struct ldap_connection {
    53         struct socket_context *sock;
     56        struct {
     57                struct tstream_context *raw;
     58                struct tstream_context *tls;
     59                struct tstream_context *sasl;
     60                struct tstream_context *active;
     61
     62                struct tevent_queue *send_queue;
     63                struct tevent_req *recv_subreq;
     64        } sockets;
     65
    5466        struct loadparm_context *lp_ctx;
    5567
     
    90102        struct {
    91103                struct tevent_context *event_ctx;
    92                 struct tevent_fd *fde;
    93104        } event;
    94 
    95         struct packet_context *packet;
    96105};
    97106
  • vendor/current/source4/libcli/ldap/ldap_controls.c

    r740 r988  
    427427}
    428428
     429static bool decode_verify_name_request(void *mem_ctx, DATA_BLOB in, void *_out)
     430{
     431        void **out = (void **)_out;
     432        DATA_BLOB name;
     433        struct asn1_data *data = asn1_init(mem_ctx);
     434        struct ldb_verify_name_control *lvnc;
     435        int len;
     436
     437        if (!data) return false;
     438
     439        if (!asn1_load(data, in)) {
     440                return false;
     441        }
     442
     443        lvnc = talloc(mem_ctx, struct ldb_verify_name_control);
     444        if (!lvnc) {
     445                return false;
     446        }
     447
     448        if (!asn1_start_tag(data, ASN1_SEQUENCE(0))) {
     449                return false;
     450        }
     451
     452        if (!asn1_read_Integer(data, &(lvnc->flags))) {
     453                return false;
     454        }
     455
     456        if (!asn1_read_OctetString(data, mem_ctx, &name)) {
     457                return false;
     458        }
     459
     460        if (name.length) {
     461                len = utf16_len_n(name.data, name.length);
     462                convert_string_talloc(mem_ctx, CH_UTF16, CH_UNIX,
     463                                        name.data, len,
     464                                        (void **)&lvnc->gc, &lvnc->gc_len);
     465
     466                if (!(lvnc->gc)) {
     467                        return false;
     468                }
     469        } else {
     470                lvnc->gc_len = 0;
     471                lvnc->gc = NULL;
     472        }
     473
     474        if (!asn1_end_tag(data)) {
     475                return false;
     476        }
     477
     478        *out = lvnc;
     479        return true;
     480}
     481
     482static bool encode_verify_name_request(void *mem_ctx, void *in, DATA_BLOB *out)
     483{
     484        struct ldb_verify_name_control *lvnc = talloc_get_type(in, struct ldb_verify_name_control);
     485        struct asn1_data *data = asn1_init(mem_ctx);
     486        DATA_BLOB gc_utf16;
     487
     488        if (!data) return false;
     489
     490        if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) {
     491                return false;
     492        }
     493
     494        if (!asn1_write_Integer(data, lvnc->flags)) {
     495                return false;
     496        }
     497
     498        if (lvnc->gc_len) {
     499                convert_string_talloc(mem_ctx, CH_UNIX, CH_UTF16,
     500                                                lvnc->gc, lvnc->gc_len,
     501                                                (void **)&gc_utf16.data, &gc_utf16.length);
     502                if (!asn1_write_OctetString(data, gc_utf16.data, gc_utf16.length)) {
     503                        return false;
     504                }
     505        } else {
     506                if (!asn1_write_OctetString(data, NULL, 0)) {
     507                        return false;
     508                }
     509        }
     510
     511        if (!asn1_pop_tag(data)) {
     512                return false;
     513        }
     514
     515        if (!asn1_extract_blob(data, mem_ctx, out)) {
     516                return false;
     517        }
     518
     519        talloc_free(data);
     520
     521        return true;
     522}
     523
    429524static bool decode_vlv_request(void *mem_ctx, DATA_BLOB in, void *_out)
    430525{
     
    622717        }
    623718
    624         *out = data_blob_talloc(mem_ctx, data->data, data->length);
    625         if (out->data == NULL) {
    626                 return false;
    627         }
     719        if (!asn1_extract_blob(data, mem_ctx, out)) {
     720                return false;
     721        }
     722
    628723        talloc_free(data);
    629724
     
    680775        }
    681776
    682         *out = data_blob_talloc(mem_ctx, data->data, data->length);
    683         if (out->data == NULL) {
    684                 return false;
    685         }
     777        if (!asn1_extract_blob(data, mem_ctx, out)) {
     778                return false;
     779        }
     780
    686781        talloc_free(data);
    687782
     
    715810        }
    716811
    717         *out = data_blob_talloc(mem_ctx, data->data, data->length);
    718         if (out->data == NULL) {
    719                 return false;
    720         }
     812        if (!asn1_extract_blob(data, mem_ctx, out)) {
     813                return false;
     814        }
     815
    721816        talloc_free(data);
    722817
     
    743838        }
    744839
    745         *out = data_blob_talloc(mem_ctx, data->data, data->length);
    746         if (out->data == NULL) {
    747                 return false;
    748         }
     840        if (!asn1_extract_blob(data, mem_ctx, out)) {
     841                return false;
     842        }
     843
    749844        talloc_free(data);
    750845
     
    771866        }
    772867
    773         *out = data_blob_talloc(mem_ctx, data->data, data->length);
    774         if (out->data == NULL) {
    775                 return false;
    776         }
     868        if (!asn1_extract_blob(data, mem_ctx, out)) {
     869                return false;
     870        }
     871
    777872        talloc_free(data);
    778873
     
    803898        }
    804899
    805         *out = data_blob_talloc(mem_ctx, data->data, data->length);
    806         if (out->data == NULL) {
    807                 return false;
    808         }
     900        if (!asn1_extract_blob(data, mem_ctx, out)) {
     901                return false;
     902        }
     903
    809904        talloc_free(data);
    810905
     
    841936        }
    842937
    843         *out = data_blob_talloc(mem_ctx, data->data, data->length);
    844         if (out->data == NULL) {
    845                 return false;
    846         }
     938        if (!asn1_extract_blob(data, mem_ctx, out)) {
     939                return false;
     940        }
     941
    847942        talloc_free(data);
    848943
     
    877972        }
    878973
    879         *out = data_blob_talloc(mem_ctx, data->data, data->length);
    880         if (out->data == NULL) {
    881                 return false;
    882         }
     974        if (!asn1_extract_blob(data, mem_ctx, out)) {
     975                return false;
     976        }
     977
    883978        talloc_free(data);
    884979
     
    9531048        }
    9541049
    955         *out = data_blob_talloc(mem_ctx, data->data, data->length);
    956         if (out->data == NULL) {
    957                 return false;
    958         }
     1050        if (!asn1_extract_blob(data, mem_ctx, out)) {
     1051                return false;
     1052        }
     1053
    9591054        talloc_free(data);
    9601055
     
    9951090        }
    9961091
    997         *out = data_blob_talloc(mem_ctx, data->data, data->length);
    998         if (out->data == NULL) {
    999                 return false;
    1000         }
     1092        if (!asn1_extract_blob(data, mem_ctx, out)) {
     1093                return false;
     1094        }
     1095
    10011096        talloc_free(data);
    10021097
     
    10351130                }
    10361131               
    1037                 asn1_pop_tag(data);
    1038                 asn1_pop_tag(data);
    1039         }
    1040         asn1_pop_tag(data);
    1041 
    1042         *out = data_blob_talloc(mem_ctx, data->data, data->length);
    1043         if (out->data == NULL) {
    1044                 return false;
    1045         }
     1132                if (!asn1_pop_tag(data)) {
     1133                        return false;
     1134                }
     1135                if (!asn1_pop_tag(data)) {
     1136                        return false;
     1137                }
     1138        }
     1139        if (!asn1_pop_tag(data)) {
     1140                return false;
     1141        }
     1142
     1143        if (!asn1_extract_blob(data, mem_ctx, out)) {
     1144                return false;
     1145        }
     1146
    10461147        talloc_free(data);
    10471148        return true;
     
    10871188                }
    10881189               
    1089                 asn1_read_OctetString_talloc(r[i], data, &r[i]->source_attribute);
    1090                 asn1_read_OctetString_talloc(r[i], data, &r[i]->dereferenced_dn);
     1190                if (!asn1_read_OctetString_talloc(r[i], data, &r[i]->source_attribute)) {
     1191                        return false;
     1192                }
     1193                if (!asn1_read_OctetString_talloc(r[i], data, &r[i]->dereferenced_dn)) {
     1194                        return false;
     1195                }
    10911196                if (asn1_peek_tag(data, ASN1_CONTEXT(0))) {
    10921197                        if (!asn1_start_tag(data, ASN1_CONTEXT(0))) {
    10931198                                return false;
    10941199                        }
    1095                        
    1096                         ldap_decode_attribs_bare(r, data, &r[i]->attributes,
    1097                                                  &r[i]->num_attributes);
    1098                        
     1200                        if (!ldap_decode_attribs_bare(r, data, &r[i]->attributes,
     1201                                                 &r[i]->num_attributes)) {
     1202                                return false;
     1203                        }
    10991204                        if (!asn1_end_tag(data)) {
    11001205                                return false;
     
    11521257        { LDB_CONTROL_ASQ_OID, decode_asq_control, encode_asq_control },
    11531258        { LDB_CONTROL_DIRSYNC_OID, decode_dirsync_request, encode_dirsync_request },
     1259        { LDB_CONTROL_DIRSYNC_EX_OID, decode_dirsync_request, encode_dirsync_request },
    11541260        { LDB_CONTROL_VLV_REQ_OID, decode_vlv_request, encode_vlv_request },
    11551261        { LDB_CONTROL_VLV_RESP_OID, decode_vlv_response, encode_vlv_response },
     
    11591265        { LDB_CONTROL_RELAX_OID, decode_flag_request, encode_flag_request },
    11601266        { DSDB_OPENLDAP_DEREFERENCE_CONTROL, decode_openldap_dereference, encode_openldap_dereference },
    1161 
    1162 /* DSDB_CONTROL_CURRENT_PARTITION_OID is internal only, and has no network representation */
     1267        { LDB_CONTROL_VERIFY_NAME_OID, decode_verify_name_request, encode_verify_name_request },
     1268
     1269        /* the following are internal only, with a network
     1270           representation */
     1271        { DSDB_CONTROL_BYPASS_PASSWORD_HASH_OID, decode_flag_request, encode_flag_request },
     1272
     1273        /* all the ones below are internal only, and have no network
     1274         * representation */
    11631275        { DSDB_CONTROL_CURRENT_PARTITION_OID, NULL, NULL },
    1164 /* DSDB_CONTROL_REPLICATED_UPDATE_OID is internal only, and has no network representation */
    11651276        { DSDB_CONTROL_REPLICATED_UPDATE_OID, NULL, NULL },
    1166 /* DSDB_CONTROL_DN_STORAGE_FORMAT_OID is internal only, and has no network representation */
    11671277        { DSDB_CONTROL_DN_STORAGE_FORMAT_OID, NULL, NULL },
    1168 /* LDB_CONTROL_RECALCULATE_SD_OID is internal only, and has no network representation */
    11691278        { LDB_CONTROL_RECALCULATE_SD_OID, NULL, NULL },
    1170 /* LDB_CONTROL_REVEAL_INTERNALS is internal only, and has no network representation */
    11711279        { LDB_CONTROL_REVEAL_INTERNALS, NULL, NULL },
    1172 /* LDB_CONTROL_AS_SYSTEM_OID is internal only, and has no network representation */
    11731280        { LDB_CONTROL_AS_SYSTEM_OID, NULL, NULL },
    1174 /* DSDB_CONTROL_PASSWORD_CHANGE_STATUS_OID is internal only, and has no network representation */
    11751281        { DSDB_CONTROL_PASSWORD_CHANGE_STATUS_OID, NULL, NULL },
    1176 /* DSDB_CONTROL_PASSWORD_HASH_VALUES_OID is internal only, and has no network representation */
    11771282        { DSDB_CONTROL_PASSWORD_HASH_VALUES_OID, NULL, NULL },
    1178 /* DSDB_CONTROL_PASSWORD_CHANGE_OID is internal only, and has no network representation */
    11791283        { DSDB_CONTROL_PASSWORD_CHANGE_OID, NULL, NULL },
    1180 /* DSDB_CONTROL_APPLY_LINKS is internal only, and has no network representation */
    11811284        { DSDB_CONTROL_APPLY_LINKS, NULL, NULL },
    1182 /* DSDB_CONTROL_BYPASS_PASSWORD_HASH_OID is internal only, and has an empty network representation */
    1183         { DSDB_CONTROL_BYPASS_PASSWORD_HASH_OID, decode_flag_request, encode_flag_request },
    1184 /* LDB_CONTROL_BYPASS_OPERATIONAL_OID is internal only, and has no network representation */
    11851285        { LDB_CONTROL_BYPASS_OPERATIONAL_OID, NULL, NULL },
    1186 /* DSDB_CONTROL_CHANGEREPLMETADATA_OID is internal only, and has no network representation */
    11871286        { DSDB_CONTROL_CHANGEREPLMETADATA_OID, NULL, NULL },
    1188 /* LDB_CONTROL_PROVISION_OID is internal only, and has no network representation */
    11891287        { LDB_CONTROL_PROVISION_OID, NULL, NULL },
    1190 /* DSDB_EXTENDED_REPLICATED_OBJECTS_OID is internal only, and has no network representation */
    11911288        { DSDB_EXTENDED_REPLICATED_OBJECTS_OID, NULL, NULL },
    1192 /* DSDB_EXTENDED_SCHEMA_UPDATE_NOW_OID is internal only, and has no network representation */
    11931289        { DSDB_EXTENDED_SCHEMA_UPDATE_NOW_OID, NULL, NULL },
    1194 /* DSDB_EXTENDED_ALLOCATE_RID_POOL is internal only, and has no network representation */
    11951290        { DSDB_EXTENDED_ALLOCATE_RID_POOL, NULL, NULL },
     1291        { DSDB_CONTROL_NO_GLOBAL_CATALOG, NULL, NULL },
     1292        { DSDB_EXTENDED_SCHEMA_UPGRADE_IN_PROGRESS_OID, NULL, NULL },
    11961293        { NULL, NULL, NULL }
    11971294};
  • vendor/current/source4/libcli/ldap/ldap_ildap.c

    r740 r988  
    120120                      struct ldap_message ***results)
    121121{
     122        NTSTATUS status;
    122123        struct ldb_parse_tree *tree = ldb_parse_tree(conn, expression);
    123         NTSTATUS status;
     124
     125        if (tree == NULL) {
     126                return NT_STATUS_INVALID_PARAMETER;
     127        }
    124128        status = ildap_search_bytree(conn, basedn, scope, tree, attrs,
    125129                                     attributesonly, control_req,
  • vendor/current/source4/libcli/ldap/wscript_build

    r740 r988  
    44                  source='ldap_client.c ldap_bind.c ldap_ildap.c ldap_controls.c',
    55                  autoproto='ldap_proto.h',
    6                   public_deps='errors tevent LIBPACKET',
    7                   public_headers='libcli_ldap.h:ldap-util.h',
    8                   deps='LIBCLI_COMPOSITE samba_socket NDR_SAMR LIBTLS LIBCLI_LDAP_NDR ndr LP_RESOLVE gensec LIBCLI_LDAP_MESSAGE',
     6                  public_deps='samba-errors tevent',
     7                  private_headers='libcli_ldap.h:ldap-util.h',
     8                  deps='cli_composite LIBSAMBA_TSOCKET samba_socket NDR_SAMR LIBTLS ndr LP_RESOLVE gensec cli-ldap-common',
    99                  private_library=True
    1010                  )
  • vendor/current/source4/libcli/libcli.h

    r414 r988  
    2323
    2424#include "librpc/gen_ndr/nbt.h"
     25#include "libcli/raw/libcliraw.h"
    2526
    2627struct substitute_context;
     
    3132 */
    3233struct smbcli_state {
     34        struct smbcli_options options;
     35        struct smbcli_socket *sock; /* NULL if connected */
    3336        struct smbcli_transport *transport;
    3437        struct smbcli_session *session;
     
    6265};
    6366
    64 
    65 
    6667#include "libcli/raw/libcliraw.h"
    6768struct gensec_settings;
    68 #include "libcli/libcli_proto.h"
     69
     70ssize_t smbcli_read(struct smbcli_tree *tree, int fnum, void *_buf, off_t offset, size_t size);
     71
     72/****************************************************************************
     73  write to a file
     74  write_mode: 0x0001 disallow write cacheing
     75              0x0002 return bytes remaining
     76              0x0004 use raw named pipe protocol
     77              0x0008 start of message mode named pipe protocol
     78****************************************************************************/
     79ssize_t smbcli_write(struct smbcli_tree *tree,
     80                     int fnum, uint16_t write_mode,
     81                     const void *_buf, off_t offset, size_t size);
     82
     83/****************************************************************************
     84  write to a file using a SMBwrite and not bypassing 0 byte writes
     85****************************************************************************/
     86ssize_t smbcli_smbwrite(struct smbcli_tree *tree,
     87                     int fnum, const void *_buf, off_t offset, size_t size1);
     88
     89bool smbcli_socket_connect(struct smbcli_state *cli, const char *server,
     90                           const char **ports,
     91                           struct tevent_context *ev_ctx,
     92                           struct resolve_context *resolve_ctx,
     93                           struct smbcli_options *options,
     94                           const char *socket_options,
     95                           struct nbt_name *calling,
     96                           struct nbt_name *called);
     97NTSTATUS smbcli_negprot(struct smbcli_state *cli, bool unicode, int maxprotocol);
     98NTSTATUS smbcli_session_setup(struct smbcli_state *cli,
     99                              struct cli_credentials *credentials,
     100                              const char *workgroup,
     101                              struct smbcli_session_options options,
     102                              struct gensec_settings *gensec_settings);
     103NTSTATUS smbcli_tconX(struct smbcli_state *cli, const char *sharename,
     104                      const char *devtype, const char *password);
     105NTSTATUS smbcli_full_connection(TALLOC_CTX *parent_ctx,
     106                                struct smbcli_state **ret_cli,
     107                                const char *host,
     108                                const char **ports,
     109                                const char *sharename,
     110                                const char *devtype,
     111                                const char *socket_options,
     112                                struct cli_credentials *credentials,
     113                                struct resolve_context *resolve_ctx,
     114                                struct tevent_context *ev,
     115                                struct smbcli_options *options,
     116                                struct smbcli_session_options *session_options,
     117                                struct gensec_settings *gensec_settings);
     118NTSTATUS smbcli_tdis(struct smbcli_state *cli);
     119
     120/****************************************************************************
     121 Initialise a client state structure.
     122****************************************************************************/
     123struct smbcli_state *smbcli_state_init(TALLOC_CTX *mem_ctx);
     124bool smbcli_parse_unc(const char *unc_name, TALLOC_CTX *mem_ctx,
     125                      char **hostname, char **sharename);
     126
     127/****************************************************************************
     128 Symlink a file (UNIX extensions).
     129****************************************************************************/
     130NTSTATUS smbcli_unix_symlink(struct smbcli_tree *tree, const char *fname_src,
     131                          const char *fname_dst);
     132
     133/****************************************************************************
     134 Hard a file (UNIX extensions).
     135****************************************************************************/
     136NTSTATUS smbcli_unix_hardlink(struct smbcli_tree *tree, const char *fname_src,
     137                           const char *fname_dst);
     138
     139/****************************************************************************
     140 chmod a file (UNIX extensions).
     141****************************************************************************/
     142NTSTATUS smbcli_unix_chmod(struct smbcli_tree *tree, const char *fname, mode_t mode);
     143
     144/****************************************************************************
     145 chown a file (UNIX extensions).
     146****************************************************************************/
     147NTSTATUS smbcli_unix_chown(struct smbcli_tree *tree, const char *fname, uid_t uid,
     148                        gid_t gid);
     149
     150/****************************************************************************
     151 Rename a file.
     152****************************************************************************/
     153NTSTATUS smbcli_rename(struct smbcli_tree *tree, const char *fname_src,
     154                    const char *fname_dst);
     155
     156/****************************************************************************
     157 Delete a file.
     158****************************************************************************/
     159NTSTATUS smbcli_unlink(struct smbcli_tree *tree, const char *fname);
     160
     161/****************************************************************************
     162 Create a directory.
     163****************************************************************************/
     164NTSTATUS smbcli_mkdir(struct smbcli_tree *tree, const char *dname);
     165
     166/****************************************************************************
     167 Remove a directory.
     168****************************************************************************/
     169NTSTATUS smbcli_rmdir(struct smbcli_tree *tree, const char *dname);
     170
     171/****************************************************************************
     172 Set or clear the delete on close flag.
     173****************************************************************************/
     174NTSTATUS smbcli_nt_delete_on_close(struct smbcli_tree *tree, int fnum,
     175                                   bool flag);
     176
     177/****************************************************************************
     178 Create/open a file - exposing the full horror of the NT API :-).
     179 Used in CIFS-on-CIFS NTVFS.
     180****************************************************************************/
     181int smbcli_nt_create_full(struct smbcli_tree *tree, const char *fname,
     182                       uint32_t CreatFlags, uint32_t DesiredAccess,
     183                       uint32_t FileAttributes, uint32_t ShareAccess,
     184                       uint32_t CreateDisposition, uint32_t CreateOptions,
     185                       uint8_t SecurityFlags);
     186
     187/****************************************************************************
     188 Open a file (using SMBopenx)
     189 WARNING: if you open with O_WRONLY then getattrE won't work!
     190****************************************************************************/
     191int smbcli_open(struct smbcli_tree *tree, const char *fname, int flags,
     192             int share_mode);
     193
     194/****************************************************************************
     195 Close a file.
     196****************************************************************************/
     197NTSTATUS smbcli_close(struct smbcli_tree *tree, int fnum);
     198
     199/****************************************************************************
     200 send a lock with a specified locktype
     201 this is used for testing LOCKING_ANDX_CANCEL_LOCK
     202****************************************************************************/
     203NTSTATUS smbcli_locktype(struct smbcli_tree *tree, int fnum,
     204                      uint32_t offset, uint32_t len, int timeout,
     205                      uint8_t locktype);
     206
     207/****************************************************************************
     208 Lock a file.
     209****************************************************************************/
     210NTSTATUS smbcli_lock(struct smbcli_tree *tree, int fnum,
     211                  uint32_t offset, uint32_t len, int timeout,
     212                  enum brl_type lock_type);
     213
     214/****************************************************************************
     215 Unlock a file.
     216****************************************************************************/
     217NTSTATUS smbcli_unlock(struct smbcli_tree *tree, int fnum, uint32_t offset, uint32_t len);
     218
     219/****************************************************************************
     220 Lock a file with 64 bit offsets.
     221****************************************************************************/
     222NTSTATUS smbcli_lock64(struct smbcli_tree *tree, int fnum,
     223                    off_t offset, off_t len, int timeout,
     224                    enum brl_type lock_type);
     225
     226/****************************************************************************
     227 Unlock a file with 64 bit offsets.
     228****************************************************************************/
     229NTSTATUS smbcli_unlock64(struct smbcli_tree *tree, int fnum, off_t offset,
     230                         off_t len);
     231
     232/****************************************************************************
     233 Do a SMBgetattrE call.
     234****************************************************************************/
     235NTSTATUS smbcli_getattrE(struct smbcli_tree *tree, int fnum,
     236                      uint16_t *attr, size_t *size,
     237                      time_t *c_time, time_t *a_time, time_t *m_time);
     238
     239/****************************************************************************
     240 Do a SMBgetatr call
     241****************************************************************************/
     242NTSTATUS smbcli_getatr(struct smbcli_tree *tree, const char *fname,
     243                    uint16_t *attr, size_t *size, time_t *t);
     244
     245/****************************************************************************
     246 Do a SMBsetatr call.
     247****************************************************************************/
     248NTSTATUS smbcli_setatr(struct smbcli_tree *tree, const char *fname, uint16_t mode,
     249                    time_t t);
     250
     251/****************************************************************************
     252 Do a setfileinfo basic_info call.
     253****************************************************************************/
     254NTSTATUS smbcli_fsetatr(struct smbcli_tree *tree, int fnum, uint16_t mode,
     255                        NTTIME create_time, NTTIME access_time,
     256                        NTTIME write_time, NTTIME change_time);
     257
     258/****************************************************************************
     259 truncate a file to a given size
     260****************************************************************************/
     261NTSTATUS smbcli_ftruncate(struct smbcli_tree *tree, int fnum, uint64_t size);
     262
     263/****************************************************************************
     264 Check for existence of a dir.
     265****************************************************************************/
     266NTSTATUS smbcli_chkpath(struct smbcli_tree *tree, const char *path);
     267
     268/****************************************************************************
     269 Query disk space.
     270****************************************************************************/
     271NTSTATUS smbcli_dskattr(struct smbcli_tree *tree, uint32_t *bsize,
     272                        uint64_t *total, uint64_t *avail);
     273
     274/****************************************************************************
     275 Create and open a temporary file.
     276****************************************************************************/
     277int smbcli_ctemp(struct smbcli_tree *tree, const char *path, char **tmp_path);
     278
     279/****************************************************************************
     280 Interpret a long filename structure.
     281****************************************************************************/
     282int smbcli_list_new(struct smbcli_tree *tree, const char *Mask, uint16_t attribute,
     283                    enum smb_search_data_level level,
     284                    void (*fn)(struct clilist_file_info *, const char *, void *),
     285                    void *caller_state);
     286
     287/****************************************************************************
     288 Interpret a short filename structure.
     289 The length of the structure is returned.
     290****************************************************************************/
     291int smbcli_list_old(struct smbcli_tree *tree, const char *Mask, uint16_t attribute,
     292                 void (*fn)(struct clilist_file_info *, const char *, void *),
     293                 void *caller_state);
     294
     295/****************************************************************************
     296 Do a directory listing, calling fn on each file found.
     297 This auto-switches between old and new style.
     298****************************************************************************/
     299int smbcli_list(struct smbcli_tree *tree, const char *Mask,uint16_t attribute,
     300                void (*fn)(struct clilist_file_info *, const char *, void *), void *state);
     301
     302/****************************************************************************
     303send a qpathinfo call
     304****************************************************************************/
     305NTSTATUS smbcli_qpathinfo(struct smbcli_tree *tree, const char *fname,
     306                       time_t *c_time, time_t *a_time, time_t *m_time,
     307                       size_t *size, uint16_t *mode);
     308
     309/****************************************************************************
     310send a qpathinfo call with the SMB_QUERY_FILE_ALL_INFO info level
     311****************************************************************************/
     312NTSTATUS smbcli_qpathinfo2(struct smbcli_tree *tree, const char *fname,
     313                        time_t *c_time, time_t *a_time, time_t *m_time,
     314                        time_t *w_time, size_t *size, uint16_t *mode,
     315                        ino_t *ino);
     316
     317/****************************************************************************
     318send a qfileinfo QUERY_FILE_NAME_INFO call
     319****************************************************************************/
     320NTSTATUS smbcli_qfilename(struct smbcli_tree *tree, int fnum, const char **name);
     321
     322/****************************************************************************
     323send a qfileinfo call
     324****************************************************************************/
     325NTSTATUS smbcli_qfileinfo(struct smbcli_tree *tree, int fnum,
     326                       uint16_t *mode, size_t *size,
     327                       time_t *c_time, time_t *a_time, time_t *m_time,
     328                       time_t *w_time, ino_t *ino);
     329
     330/****************************************************************************
     331send a qpathinfo SMB_QUERY_FILE_ALT_NAME_INFO call
     332****************************************************************************/
     333NTSTATUS smbcli_qpathinfo_alt_name(struct smbcli_tree *tree, const char *fname,
     334                                const char **alt_name);
     335
     336/* The following definitions come from ../source4/libcli/climessage.c  */
     337
     338
     339/****************************************************************************
     340start a message sequence
     341****************************************************************************/
     342bool smbcli_message_start(struct smbcli_tree *tree, const char *host, const char *username,
     343                       int *grp);
     344
     345/****************************************************************************
     346send a message
     347****************************************************************************/
     348bool smbcli_message_text(struct smbcli_tree *tree, char *msg, int len, int grp);
     349
     350/****************************************************************************
     351end a message
     352****************************************************************************/
     353bool smbcli_message_end(struct smbcli_tree *tree, int grp);
     354
     355int smbcli_deltree(struct smbcli_tree *tree, const char *dname);
    69356
    70357#endif /* __LIBCLI_H__ */
  • vendor/current/source4/libcli/rap/rap.c

    r740 r988  
    3131        struct rap_call *call;
    3232
    33         call = talloc(mem_ctx, struct rap_call);
    34 
    35         if (call == NULL)
     33        call = talloc_zero(mem_ctx, struct rap_call);
     34        if (call == NULL) {
    3635                return NULL;
     36        }
    3737
    3838        call->callno = callno;
    3939        call->rcv_paramlen = 4;
    4040
    41         call->paramdesc = NULL;
    42         call->datadesc = NULL;
    43         call->auxdatadesc = NULL;
    44 
    45         call->ndr_push_param = ndr_push_init_ctx(mem_ctx);
     41        call->ndr_push_param = ndr_push_init_ctx(call);
     42        if (call->ndr_push_param == NULL) {
     43                talloc_free(call);
     44                return NULL;
     45        }
    4646        call->ndr_push_param->flags = RAPNDR_FLAGS;
    4747
    48         call->ndr_push_data = ndr_push_init_ctx(mem_ctx);
     48        call->ndr_push_data = ndr_push_init_ctx(call);
     49        if (call->ndr_push_data == NULL) {
     50                talloc_free(call);
     51                return NULL;
     52        }
    4953        call->ndr_push_data->flags = RAPNDR_FLAGS;
     54
     55        call->pull_mem_ctx = mem_ctx;
    5056
    5157        return call;
     
    222228        call->ndr_pull_param = ndr_pull_init_blob(&trans.out.params, call);
    223229        call->ndr_pull_param->flags = RAPNDR_FLAGS;
    224 
     230        call->ndr_pull_param->current_mem_ctx = call->pull_mem_ctx;
    225231        call->ndr_pull_data = ndr_pull_init_blob(&trans.out.data, call);
    226232        call->ndr_pull_data->flags = RAPNDR_FLAGS;
     233        call->ndr_pull_data->current_mem_ctx = call->pull_mem_ctx;
    227234
    228235        return result;
  • vendor/current/source4/libcli/rap/rap.h

    r740 r988  
    6161        const char *auxdatadesc;
    6262
    63         uint16_t status;
    64         uint16_t convert;
    65 
    6663        uint16_t rcv_paramlen, rcv_datalen;
    6764
    6865        struct ndr_push *ndr_push_param;
    6966        struct ndr_push *ndr_push_data;
     67
     68        TALLOC_CTX *pull_mem_ctx;
    7069        struct ndr_pull *ndr_pull_param;
    7170        struct ndr_pull *ndr_pull_data;
  • vendor/current/source4/libcli/rap/wscript_build

    r740 r988  
    33bld.SAMBA_SUBSYSTEM('LIBCLI_RAP',
    44        source='rap.c',
    5         public_deps='LIBCLI_RAW NDR_RAP',
     5        public_deps='smbclient-raw NDR_RAP',
    66        autoproto='proto.h'
    77        )
  • 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
  • vendor/current/source4/libcli/resolve/bcast.c

    r740 r988  
    4848        struct resolve_bcast_data *data = talloc_get_type(userdata, struct resolve_bcast_data);
    4949
    50         num_interfaces = iface_count(data->ifaces);
     50        num_interfaces = iface_list_count(data->ifaces);
    5151
    5252        address_list = talloc_array(mem_ctx, const char *, num_interfaces+1);
     
    5454
    5555        for (i=0;i<num_interfaces;i++) {
    56                 const char *bcast = iface_n_bcast(data->ifaces, i);
    57                 if (bcast == NULL) continue;
     56                bool ipv4 = iface_list_n_is_v4(data->ifaces, i);
     57                const char *bcast;
     58
     59                if (!ipv4) {
     60                        continue;
     61                }
     62
     63                bcast = iface_list_n_bcast(data->ifaces, i);
     64                if (bcast == NULL) {
     65                        continue;
     66                }
     67
    5868                address_list[count] = talloc_strdup(address_list, bcast);
    5969                if (address_list[count] == NULL) {
     
    102112{
    103113        struct interface *ifaces;
    104         load_interfaces(ctx, lpcfg_interfaces(lp_ctx), &ifaces);
     114        load_interface_list(ctx, lp_ctx, &ifaces);
    105115        return resolve_context_add_bcast_method(ctx, ifaces, lpcfg_nbt_port(lp_ctx), lpcfg_parm_int(lp_ctx, NULL, "nbt", "timeout", 1));
    106116}
  • vendor/current/source4/libcli/resolve/dns_ex.c

    r740 r988  
    66   Copyright (C) Andrew Tridgell 2005
    77   Copyright (C) Stefan Metzmacher 2008
     8   Copyright (C) Matthieu Patou 2011
    89
    910   This program is free software; you can redistribute it and/or modify
     
    3839#include "librpc/gen_ndr/ndr_nbt.h"
    3940#include "libcli/resolve/resolve.h"
    40 
    41 #ifdef class
    42 #undef class
    43 #endif
    44 
    45 #include "heimdal/lib/roken/resolve.h"
     41#include "lib/util/util_net.h"
     42#include "lib/addns/dnsquery.h"
     43#include "lib/addns/dns.h"
     44#include <arpa/nameser.h>
     45#include <resolv.h>
    4646
    4747struct dns_ex_state {
     
    7676}
    7777
     78struct dns_records_container {
     79        char **list;
     80        uint32_t count;
     81};
     82
     83static int reply_to_addrs(TALLOC_CTX *mem_ctx, uint32_t *a_num,
     84                          char ***cur_addrs, uint32_t total,
     85                          struct dns_request *reply, int port)
     86{
     87        char addrstr[INET6_ADDRSTRLEN];
     88        struct dns_rrec *rr;
     89        char **addrs;
     90        uint32_t i;
     91        const char *addr;
     92
     93        /* at most we over-allocate here, but not by much */
     94        addrs = talloc_realloc(mem_ctx, *cur_addrs, char *,
     95                                total + reply->num_answers);
     96        if (!addrs) {
     97                return 0;
     98        }
     99        *cur_addrs = addrs;
     100
     101        for (i = 0; i < reply->num_answers; i++) {
     102                rr = reply->answers[i];
     103
     104                /* we are only interested in the IN class */
     105                if (rr->r_class != DNS_CLASS_IN) {
     106                        continue;
     107                }
     108
     109                if (rr->type == QTYPE_NS) {
     110                        /*
     111                         * After the record for NS will come the A or AAAA
     112                         * record of the NS.
     113                         */
     114                        break;
     115                }
     116
     117                /* verify we actually have a record here */
     118                if (!rr->data) {
     119                        continue;
     120                }
     121
     122                /* we are only interested in A and AAAA records */
     123                switch (rr->type) {
     124                case QTYPE_A:
     125                        addr = inet_ntop(AF_INET,
     126                                         (struct in_addr *)rr->data,
     127                                         addrstr, sizeof(addrstr));
     128                        if (addr == NULL) {
     129                                continue;
     130                        }
     131                        break;
     132                case QTYPE_AAAA:
     133#ifdef HAVE_IPV6
     134                        addr = inet_ntop(AF_INET6,
     135                                         (struct in6_addr *)rr->data,
     136                                         addrstr, sizeof(addrstr));
     137#else
     138                        addr = NULL;
     139#endif
     140                        if (addr == NULL) {
     141                                continue;
     142                        }
     143                        break;
     144                default:
     145                        continue;
     146                }
     147
     148                addrs[total] = talloc_asprintf(addrs, "%s@%u/%s",
     149                                                addrstr, port,
     150                                                rr->name->pLabelList->label);
     151                if (addrs[total]) {
     152                        total++;
     153                        if (rr->type == QTYPE_A) {
     154                                (*a_num)++;
     155                        }
     156                }
     157        }
     158
     159        return total;
     160}
     161
     162static DNS_ERROR dns_lookup(TALLOC_CTX *mem_ctx, const char* name,
     163                            uint16_t q_type, struct dns_request **reply)
     164{
     165        int len, rlen;
     166        uint8_t *answer;
     167        bool loop;
     168        struct dns_buffer buf;
     169        DNS_ERROR err;
     170
     171        /* give space for a good sized answer by default */
     172        answer = NULL;
     173        len = 1500;
     174        do {
     175                answer = talloc_realloc(mem_ctx, answer, uint8_t, len);
     176                if (!answer) {
     177                        return ERROR_DNS_NO_MEMORY;
     178                }
     179                rlen = res_search(name, DNS_CLASS_IN, q_type, answer, len);
     180                if (rlen == -1) {
     181                        if (len >= 65535) {
     182                                return ERROR_DNS_SOCKET_ERROR;
     183                        }
     184                        /* retry once with max packet size */
     185                        len = 65535;
     186                        loop = true;
     187                } else if (rlen > len) {
     188                        len = rlen;
     189                        loop = true;
     190                } else {
     191                        loop = false;
     192                }
     193        } while(loop);
     194
     195        buf.data = answer;
     196        buf.size = rlen;
     197        buf.offset = 0;
     198        buf.error = ERROR_DNS_SUCCESS;
     199
     200        err = dns_unmarshall_request(mem_ctx, &buf, reply);
     201
     202        TALLOC_FREE(answer);
     203        return err;
     204}
     205
     206static struct dns_records_container get_a_aaaa_records(TALLOC_CTX *mem_ctx,
     207                                                        const char* name,
     208                                                        int port)
     209{
     210        struct dns_request *reply;
     211        struct dns_records_container ret;
     212        char **addrs = NULL;
     213        uint32_t a_num, total;
     214        uint16_t qtype;
     215        TALLOC_CTX *tmp_ctx;
     216        DNS_ERROR err;
     217
     218        memset(&ret, 0, sizeof(struct dns_records_container));
     219
     220        tmp_ctx = talloc_new(mem_ctx);
     221        if (!tmp_ctx) {
     222                return ret;
     223        }
     224
     225        qtype = QTYPE_AAAA;
     226
     227        /* this is the blocking call we are going to lots of trouble
     228           to avoid them in the parent */
     229        err = dns_lookup(tmp_ctx, name, qtype, &reply);
     230        if (!ERR_DNS_IS_OK(err)) {
     231                qtype = QTYPE_A;
     232                err = dns_lookup(tmp_ctx, name, qtype, &reply);
     233                if (!ERR_DNS_IS_OK(err)) {
     234                        goto done;
     235                }
     236        }
     237
     238        a_num = total = 0;
     239        total = reply_to_addrs(tmp_ctx, &a_num, &addrs, total, reply, port);
     240
     241        if (qtype == QTYPE_AAAA && a_num == 0) {
     242                /*
     243                * DNS server didn't returned A when asked for AAAA records.
     244                * Most of the server do it, let's ask for A specificaly.
     245                */
     246                err = dns_lookup(tmp_ctx, name, QTYPE_A, &reply);
     247                if (!ERR_DNS_IS_OK(err)) {
     248                        goto done;
     249                }
     250
     251                total = reply_to_addrs(tmp_ctx, &a_num, &addrs, total,
     252                                        reply, port);
     253
     254        }
     255
     256        if (total) {
     257                talloc_steal(mem_ctx, addrs);
     258                ret.count = total;
     259                ret.list = addrs;
     260        }
     261
     262done:
     263        TALLOC_FREE(tmp_ctx);
     264        return ret;
     265}
     266
     267static struct dns_records_container get_srv_records(TALLOC_CTX *mem_ctx,
     268                                                        const char* name)
     269{
     270        struct dns_records_container ret;
     271        char **addrs = NULL;
     272        struct dns_rr_srv *dclist;
     273        NTSTATUS status;
     274        uint32_t total;
     275        unsigned i;
     276        int count;
     277
     278        memset(&ret, 0, sizeof(struct dns_records_container));
     279        /* this is the blocking call we are going to lots of trouble
     280           to avoid them in the parent */
     281        status = ads_dns_lookup_srv(mem_ctx, name, &dclist, &count);
     282        if (!NT_STATUS_IS_OK(status)) {
     283                return ret;
     284        }
     285        total = 0;
     286        if (count == 0) {
     287                return ret;
     288        }
     289
     290        /* Loop over all returned records and pick the records */
     291        for (i = 0; i < count; i++) {
     292                struct dns_records_container c;
     293                const char* tmp_str;
     294
     295                tmp_str = dclist[i].hostname;
     296                if (strchr(tmp_str, '.') && tmp_str[strlen(tmp_str)-1] != '.') {
     297                        /* we are asking for a fully qualified name, but the
     298                        name doesn't end in a '.'. We need to prevent the
     299                        DNS library trying the search domains configured in
     300                        resolv.conf */
     301                        tmp_str = talloc_asprintf(mem_ctx, "%s.", tmp_str);
     302                }
     303
     304                c = get_a_aaaa_records(mem_ctx, tmp_str, dclist[i].port);
     305                total += c.count;
     306                if (addrs == NULL) {
     307                        addrs = c.list;
     308                } else {
     309                        unsigned j;
     310
     311                        addrs = talloc_realloc(mem_ctx, addrs, char*, total);
     312                        for (j=0; j < c.count; j++) {
     313                                addrs[total - j - 1] = talloc_steal(addrs, c.list[j]);
     314                        }
     315                }
     316        }
     317
     318        if (total) {
     319                ret.count = total;
     320                ret.list = addrs;
     321        }
     322
     323        return ret;
     324}
    78325/*
    79326  the blocking child
     
    81328static void run_child_dns_lookup(struct dns_ex_state *state, int fd)
    82329{
    83         struct rk_dns_reply *reply;
    84         struct rk_resource_record *rr;
    85         uint32_t count = 0;
    86         uint32_t srv_valid = 0;
    87         struct rk_resource_record **srv_rr;
    88         uint32_t addrs_valid = 0;
    89         struct rk_resource_record **addrs_rr;
    90         char *addrs;
    91330        bool first;
    92         uint32_t i;
    93331        bool do_srv = (state->flags & RESOLVE_NAME_FLAG_DNS_SRV);
     332        struct dns_records_container c;
     333        char* addrs = NULL;
     334        unsigned int i;
    94335
    95336        if (strchr(state->name.name, '.') && state->name.name[strlen(state->name.name)-1] != '.') {
     
    102343        }
    103344
    104         /* this is the blocking call we are going to lots of trouble
    105            to avoid in the parent */
    106         reply = rk_dns_lookup(state->name.name, do_srv?"SRV":"A");
    107         if (!reply) {
    108                 goto done;
    109         }
    110345
    111346        if (do_srv) {
    112                 rk_dns_srv_order(reply);
    113         }
    114 
    115         /* Loop over all returned records and pick the "srv" records */
    116         for (rr=reply->head; rr; rr=rr->next) {
    117                 /* we are only interested in the IN class */
    118                 if (rr->class != rk_ns_c_in) {
    119                         continue;
    120                 }
    121 
    122                 if (do_srv) {
    123                         /* we are only interested in SRV records */
    124                         if (rr->type != rk_ns_t_srv) {
    125                                 continue;
    126                         }
    127 
    128                         /* verify we actually have a SRV record here */
    129                         if (!rr->u.srv) {
    130                                 continue;
    131                         }
    132 
    133                         /* Verify we got a port */
    134                         if (rr->u.srv->port == 0) {
    135                                 continue;
    136                         }
    137                 } else {
    138                         /* we are only interested in A records */
    139                         /* TODO: add AAAA support */
    140                         if (rr->type != rk_ns_t_a) {
    141                                 continue;
    142                         }
    143 
    144                         /* verify we actually have a A record here */
    145                         if (!rr->u.a) {
    146                                 continue;
    147                         }
    148                 }
    149                 count++;
    150         }
    151 
    152         if (count == 0) {
    153                 goto done;
    154         }
    155 
    156         srv_rr = talloc_zero_array(state,
    157                                    struct rk_resource_record *,
    158                                    count);
    159         if (!srv_rr) {
    160                 goto done;
    161         }
    162 
    163         addrs_rr = talloc_zero_array(state,
    164                                      struct rk_resource_record *,
    165                                      count);
    166         if (!addrs_rr) {
    167                 goto done;
    168         }
    169 
    170         /* Loop over all returned records and pick the records */
    171         for (rr=reply->head;rr;rr=rr->next) {
    172                 /* we are only interested in the IN class */
    173                 if (rr->class != rk_ns_c_in) {
    174                         continue;
    175                 }
    176 
    177                 if (do_srv) {
    178                         /* we are only interested in SRV records */
    179                         if (rr->type != rk_ns_t_srv) {
    180                                 continue;
    181                         }
    182 
    183                         /* verify we actually have a srv record here */
    184                         if (!rr->u.srv) {
    185                                 continue;
    186                         }
    187 
    188                         /* Verify we got a port */
    189                         if (rr->u.srv->port == 0) {
    190                                 continue;
    191                         }
    192 
    193                         srv_rr[srv_valid] = rr;
    194                         srv_valid++;
    195                 } else {
    196                         /* we are only interested in A records */
    197                         /* TODO: add AAAA support */
    198                         if (rr->type != rk_ns_t_a) {
    199                                 continue;
    200                         }
    201 
    202                         /* verify we actually have a A record here */
    203                         if (!rr->u.a) {
    204                                 continue;
    205                         }
    206 
    207                         addrs_rr[addrs_valid] = rr;
    208                         addrs_valid++;
    209                 }
    210         }
    211 
    212         for (i=0; i < srv_valid; i++) {
    213                 for (rr=reply->head;rr;rr=rr->next) {
    214 
    215                         if (rr->class != rk_ns_c_in) {
    216                                 continue;
    217                         }
    218 
    219                         /* we are only interested in A records */
    220                         if (rr->type != rk_ns_t_a) {
    221                                 continue;
    222                         }
    223 
    224                         /* verify we actually have a srv record here */
    225                         if (strcmp(&srv_rr[i]->u.srv->target[0], rr->domain) != 0) {
    226                                 continue;
    227                         }
    228 
    229                         addrs_rr[i] = rr;
    230                         addrs_valid++;
    231                         break;
    232                 }
    233         }
    234 
    235         if (addrs_valid == 0) {
     347                c = get_srv_records(state, state->name.name);
     348        } else {
     349                c = get_a_aaaa_records(state, state->name.name, state->port);
     350        }
     351
     352        /* This line in critical - if we return without writing to the
     353         * pipe, this is the signal that the name did not exist */
     354        if (c.count == 0) {
    236355                goto done;
    237356        }
     
    242361        }
    243362        first = true;
    244         for (i=0; i < count; i++) {
    245                 uint16_t port;
    246                 if (!addrs_rr[i]) {
    247                         continue;
    248                 }
    249 
    250                 if (srv_rr[i] &&
    251                     (state->flags & RESOLVE_NAME_FLAG_OVERWRITE_PORT)) {
    252                         port = srv_rr[i]->u.srv->port;
    253                 } else {
    254                         port = state->port;
    255                 }
    256 
    257                 addrs = talloc_asprintf_append_buffer(addrs, "%s%s:%u/%s",
    258                                                       first?"":",",
    259                                                       inet_ntoa(*addrs_rr[i]->u.a),
    260                                                       port,
    261                                                       addrs_rr[i]->domain);
    262                 if (!addrs) {
    263                         goto done;
    264                 }
     363
     364        for (i=0; i < c.count; i++) {
     365                addrs = talloc_asprintf_append_buffer(addrs, "%s%s",
     366                                                        first?"":",",
     367                                                        c.list[i]);
    265368                first = false;
    266369        }
    267370
    268371        if (addrs) {
     372                DEBUG(11, ("Addrs = %s\n", addrs));
    269373                write(fd, addrs, talloc_get_size(addrs));
    270374        }
     
    288392        ZERO_STRUCT(hints);
    289393        hints.ai_socktype = SOCK_STREAM;
    290         hints.ai_family = AF_INET;/* TODO: add AF_INET6 support */
    291394        hints.ai_flags = AI_ADDRCONFIG | AI_NUMERICSERV;
    292395
     
    298401                case EAI_NODATA:
    299402#endif
     403                case EAI_FAIL:
     404                        /* Linux returns EAI_NODATA on non-RFC1034-compliant names. FreeBSD returns EAI_FAIL */
    300405                case EAI_NONAME:
    301                         /* getaddrinfo() doesn't handle CNAME records */
     406                        /* getaddrinfo() doesn't handle CNAME or non-RFC1034 compatible records */
    302407                        run_child_dns_lookup(state, fd);
    303408                        return;
     
    316421        first = true;
    317422        for (res = res_list; res; res = res->ai_next) {
    318                 struct sockaddr_in *in;
    319 
    320                 if (res->ai_family != AF_INET) {
     423                char addrstr[INET6_ADDRSTRLEN];
     424                if (!print_sockaddr_len(addrstr, sizeof(addrstr), (struct sockaddr *)res->ai_addr, res->ai_addrlen)) {
    321425                        continue;
    322426                }
    323                 in = (struct sockaddr_in *)res->ai_addr;
    324 
    325                 addrs = talloc_asprintf_append_buffer(addrs, "%s%s:%u/%s",
     427                addrs = talloc_asprintf_append_buffer(addrs, "%s%s@%u/%s",
    326428                                                      first?"":",",
    327                                                       inet_ntoa(in->sin_addr),
     429                                                      addrstr,
    328430                                                      state->port,
    329431                                                      state->name.name);
     
    384486
    385487        if (ret <= 0) {
     488                /* The check for ret == 0 here is important, if the
     489                 * name does not exist, then no bytes are written to
     490                 * the pipe */
    386491                DEBUG(3,("dns child failed to find name '%s' of type %s\n",
    387492                         state->name.name, (state->flags & RESOLVE_NAME_FLAG_DNS_SRV)?"SRV":"A"));
     
    390495        }
    391496
    392         /* enusre the address looks good */
     497        /* ensure the address looks good */
    393498        address[ret] = 0;
    394499
     
    407512        for (i=0; i < num_addrs; i++) {
    408513                uint32_t port = 0;
    409                 char *p = strrchr(addrs[i], ':');
     514                char *p = strrchr(addrs[i], '@');
    410515                char *n;
    411516
     
    427532                n++;
    428533
    429                 if (strcmp(addrs[i], "0.0.0.0") == 0 ||
    430                     inet_addr(addrs[i]) == INADDR_NONE) {
     534                if (strcmp(addrs[i], "0.0.0.0") == 0) {
    431535                        composite_error(c, NT_STATUS_OBJECT_NAME_NOT_FOUND);
    432536                        return;
     
    438542                }
    439543                state->addrs[i] = socket_address_from_strings(state->addrs,
    440                                                               "ipv4",
     544                                                              "ip",
    441545                                                              addrs[i],
    442546                                                              port);
     
    486590        ret = pipe(fd);
    487591        if (ret == -1) {
    488                 composite_error(c, map_nt_error_from_unix(errno));
     592                composite_error(c, map_nt_error_from_unix_common(errno));
    489593                return c;
    490594        }
     
    499603        /* we need to put the child in our event context so
    500604           we know when the dns_lookup() has finished */
    501         state->fde = event_add_fd(c->event_ctx, c, state->child_fd, EVENT_FD_READ,
     605        state->fde = tevent_add_fd(c->event_ctx, c, state->child_fd, TEVENT_FD_READ,
    502606                                  pipe_handler, c);
    503607        if (composite_nomem(state->fde, c)) {
     
    510614        state->child = fork();
    511615        if (state->child == (pid_t)-1) {
    512                 composite_error(c, map_nt_error_from_unix(errno));
     616                composite_error(c, map_nt_error_from_unix_common(errno));
    513617                return c;
    514618        }
  • vendor/current/source4/libcli/resolve/nbtlist.c

    r740 r988  
    112112                                                    uint16_t port,
    113113                                                    struct nbt_name *name,
    114                                                     const char **address_list,
     114                                                    const char * const *address_list,
    115115                                                    struct interface *ifaces,
    116116                                                    uint16_t nbt_port,
  • vendor/current/source4/libcli/resolve/resolve.c

    r740 r988  
    7676        method->recv_fn = recv_fn;
    7777        method->privdata = userdata;
    78         DLIST_ADD_END(ctx->methods, method, struct resolve_method *);
     78        DLIST_ADD_END(ctx->methods, method);
    7979        return true;
    8080}
     
    172172        if (is_ipaddress(state->name.name) ||
    173173            strcasecmp(state->name.name, "localhost") == 0) {
    174                 struct in_addr ip = interpret_addr2(state->name.name);
    175 
    176174                state->addrs = talloc_array(state, struct socket_address *, 2);
    177175                if (composite_nomem(state->addrs, c)) return c;
    178                 state->addrs[0] = socket_address_from_strings(state->addrs, "ipv4",
    179                                                               inet_ntoa(ip), 0);
     176                state->addrs[0] = socket_address_from_strings(state->addrs, "ip",
     177                                                              state->name.name, 0);
    180178                if (composite_nomem(state->addrs[0], c)) return c;
    181179                state->addrs[1] = NULL;
     
    317315
    318316
    319 /*
    320   general name resolution - sync call
    321  */
    322 NTSTATUS resolve_name(struct resolve_context *ctx,
    323                       struct nbt_name *name,
    324                       TALLOC_CTX *mem_ctx,
    325                       const char **reply_addr,
    326                       struct tevent_context *ev)
    327 {
    328         return resolve_name_ex(ctx, 0, 0, name, mem_ctx, reply_addr, ev);
    329 }
    330 
    331317/* Initialise a struct nbt_name with a NULL scope */
    332318
  • vendor/current/source4/libcli/resolve/resolve_lp.c

    r740 r988  
    3333        for (i = 0; methods != NULL && methods[i] != NULL; i++) {
    3434                if (!strcmp(methods[i], "wins")) {
    35                         resolve_context_add_wins_method_lp(ret, lp_ctx);
     35                        if (lpcfg_disable_netbios(lp_ctx) == false) {
     36                                resolve_context_add_wins_method_lp(ret, lp_ctx);
     37                        }
    3638                } else if (!strcmp(methods[i], "bcast")) {
    37                         resolve_context_add_bcast_method_lp(ret, lp_ctx);
    38                 } else if (!strcmp(methods[i], "file")) {
    39                         resolve_context_add_file_method_lp(ret, lp_ctx);
     39                        if (lpcfg_disable_netbios(lp_ctx) == false) {
     40                                resolve_context_add_bcast_method_lp(ret, lp_ctx);
     41                        }
     42                } else if (!strcmp(methods[i], "lmhosts")) {
     43                        resolve_context_add_lmhosts_method(ret);
    4044                } else if (!strcmp(methods[i], "host")) {
    4145                        resolve_context_add_host_method(ret);
  • vendor/current/source4/libcli/resolve/testsuite.c

    r740 r988  
    2424#include "libcli/resolve/resolve.h"
    2525#include "torture/torture.h"
     26#include "torture/local/proto.h"
    2627#include "system/network.h"
    2728#include "lib/util/util_net.h"
  • vendor/current/source4/libcli/resolve/wins.c

    r740 r988  
    2828
    2929struct resolve_wins_data {
    30         const char **address_list;
     30        char **address_list;
    3131        struct interface *ifaces;
    3232        uint16_t nbt_port;
     
    4848        if (wins_data->address_list == NULL) return NULL;
    4949        return resolve_name_nbtlist_send(mem_ctx, event_ctx, flags, port, name,
    50                                          wins_data->address_list, wins_data->ifaces,
     50                                         (const char * const *)wins_data->address_list,
     51                                         wins_data->ifaces,
    5152                                         wins_data->nbt_port, wins_data->nbt_timeout,
    5253                                         false, true);
     
    6768{
    6869        struct resolve_wins_data *wins_data = talloc(ctx, struct resolve_wins_data);
    69         wins_data->address_list = (const char **)str_list_copy(wins_data, address_list);
     70        wins_data->address_list = str_list_copy(wins_data, address_list);
    7071        wins_data->ifaces = talloc_reference(wins_data, ifaces);
    7172        wins_data->nbt_port = nbt_port;
     
    7879{
    7980        struct interface *ifaces;
    80         load_interfaces(ctx, lpcfg_interfaces(lp_ctx), &ifaces);
     81        load_interface_list(ctx, lp_ctx, &ifaces);
    8182        return resolve_context_add_wins_method(ctx, lpcfg_wins_server_list(lp_ctx), ifaces, lpcfg_nbt_port(lp_ctx), lpcfg_parm_int(lp_ctx, NULL, "nbt", "timeout", 1));
    8283}
  • vendor/current/source4/libcli/security/tests/sddl.c

    r740 r988  
    2323#include "libcli/security/security.h"
    2424#include "torture/torture.h"
     25#include "torture/local/proto.h"
    2526#include "librpc/gen_ndr/ndr_security.h"
    2627
  • vendor/current/source4/libcli/smb2/cancel.c

    r740 r988  
    2121
    2222#include "includes.h"
     23#include <tevent.h>
    2324#include "libcli/raw/libcliraw.h"
    2425#include "libcli/smb2/smb2.h"
     
    3031NTSTATUS smb2_cancel(struct smb2_request *r)
    3132{
    32         NTSTATUS status;
    33         struct smb2_request *c;
    34         uint32_t old_timeout;
    35         uint64_t old_seqnum;
     33        bool ok;
    3634
    37         /*
    38          * if we don't get a pending id yet, we just
    39          * mark the request for pending, so that we directly
    40          * send the cancel after getting the pending id
    41          */
    42         if (!r->cancel.can_cancel) {
    43                 r->cancel.do_cancel++;
     35        if (r->subreq == NULL) {
    4436                return NT_STATUS_OK;
    4537        }
    4638
    47         /* we don't want a seqmun for a SMB2 Cancel */
    48         old_seqnum = r->transport->seqnum;
    49         c = smb2_request_init(r->transport, SMB2_OP_CANCEL, 0x04, false, 0);
    50         r->transport->seqnum = old_seqnum;
    51         NT_STATUS_HAVE_NO_MEMORY(c);
    52         c->seqnum = 0;
    53 
    54         SIVAL(c->out.hdr, SMB2_HDR_FLAGS,       0x00000002);
    55         SSVAL(c->out.hdr, SMB2_HDR_CREDIT,      0x0030);
    56         SBVAL(c->out.hdr, SMB2_HDR_ASYNC_ID,    r->cancel.async_id);
    57         SBVAL(c->out.hdr, SMB2_HDR_MESSAGE_ID,  c->seqnum);
    58         if (r->session) {
    59                 SBVAL(c->out.hdr, SMB2_HDR_SESSION_ID,  r->session->uid);
     39        ok = tevent_req_cancel(r->subreq);
     40        if (!ok) {
     41                return NT_STATUS_INTERNAL_ERROR;
    6042        }
    6143
    62         SSVAL(c->out.body, 0x02, 0);
    63 
    64         old_timeout = c->transport->options.request_timeout;
    65         c->transport->options.request_timeout = 0;
    66         smb2_transport_send(c);
    67         c->transport->options.request_timeout = old_timeout;
    68 
    69         if (c->state == SMB2_REQUEST_ERROR) {
    70                 status = c->status;
    71         } else {
    72                 status = NT_STATUS_OK;
    73         }
    74 
    75         talloc_free(c);
    76         return status;
     44        return NT_STATUS_OK;
    7745}
  • vendor/current/source4/libcli/smb2/connect.c

    r414 r988  
    2121
    2222#include "includes.h"
     23#include <tevent.h>
     24#include "lib/util/tevent_ntstatus.h"
    2325#include "libcli/raw/libcliraw.h"
    2426#include "libcli/raw/raw_proto.h"
     
    2830#include "libcli/resolve/resolve.h"
    2931#include "param/param.h"
     32#include "auth/credentials/credentials.h"
     33#include "../libcli/smb/smbXcli_base.h"
    3034
    3135struct smb2_connect_state {
     36        struct tevent_context *ev;
    3237        struct cli_credentials *credentials;
     38        uint64_t previous_session_id;
    3339        struct resolve_context *resolve_ctx;
    3440        const char *host;
    3541        const char *share;
     42        const char *unc;
    3643        const char **ports;
    3744        const char *socket_options;
     45        struct nbt_name calling, called;
    3846        struct gensec_settings *gensec_settings;
    3947        struct smbcli_options options;
    40         struct smb2_negprot negprot;
    41         struct smb2_tree_connect tcon;
     48        struct smb2_transport *transport;
    4249        struct smb2_session *session;
    4350        struct smb2_tree *tree;
    4451};
    4552
    46 /*
    47   continue after tcon reply
    48 */
    49 static void continue_tcon(struct smb2_request *req)
    50 {
    51         struct composite_context *c = talloc_get_type(req->async.private_data,
    52                                                       struct composite_context);
    53         struct smb2_connect_state *state = talloc_get_type(c->private_data,
    54                                                            struct smb2_connect_state);
    55 
    56         c->status = smb2_tree_connect_recv(req, &state->tcon);
    57         if (!composite_is_ok(c)) return;
    58        
    59         state->tree->tid = state->tcon.out.tid;
    60 
    61         composite_done(c);
    62 }
    63 
    64 /*
    65   continue after a session setup
    66 */
    67 static void continue_session(struct composite_context *creq)
    68 {
    69         struct composite_context *c = talloc_get_type(creq->async.private_data,
    70                                                       struct composite_context);
    71         struct smb2_connect_state *state = talloc_get_type(c->private_data,
    72                                                            struct smb2_connect_state);
    73         struct smb2_request *req;
    74 
    75         c->status = smb2_session_setup_spnego_recv(creq);
    76         if (!composite_is_ok(c)) return;
    77 
    78         state->tree = smb2_tree_init(state->session, state, true);
    79         if (composite_nomem(state->tree, c)) return;
    80 
    81         state->tcon.in.reserved = 0;
    82         state->tcon.in.path     = talloc_asprintf(state, "\\\\%s\\%s",
    83                                                   state->host, state->share);
    84         if (composite_nomem(state->tcon.in.path, c)) return;
    85        
    86         req = smb2_tree_connect_send(state->tree, &state->tcon);
    87         if (composite_nomem(req, c)) return;
    88 
    89         req->async.fn = continue_tcon;
    90         req->async.private_data = c;   
    91 }
    92 
    93 /*
    94   continue after negprot reply
    95 */
    96 static void continue_negprot(struct smb2_request *req)
    97 {
    98         struct composite_context *c = talloc_get_type(req->async.private_data,
    99                                                       struct composite_context);
    100         struct smb2_connect_state *state = talloc_get_type(c->private_data,
    101                                                            struct smb2_connect_state);
    102         struct smb2_transport *transport = req->transport;
    103         struct composite_context *creq;
    104 
    105         c->status = smb2_negprot_recv(req, c, &state->negprot);
    106         if (!composite_is_ok(c)) return;
    107 
    108         transport->negotiate.secblob = state->negprot.out.secblob;
    109         talloc_steal(transport, transport->negotiate.secblob.data);
    110         transport->negotiate.system_time = state->negprot.out.system_time;
    111         transport->negotiate.server_start_time = state->negprot.out.server_start_time;
    112         transport->negotiate.security_mode = state->negprot.out.security_mode;
    113         transport->negotiate.dialect_revision = state->negprot.out.dialect_revision;
    114 
    115         switch (transport->options.signing) {
    116         case SMB_SIGNING_OFF:
    117                 if (transport->negotiate.security_mode & SMB2_NEGOTIATE_SIGNING_REQUIRED) {
    118                         composite_error(c, NT_STATUS_ACCESS_DENIED);
    119                         return;
    120                 }
    121                 transport->signing_required = false;
    122                 break;
    123         case SMB_SIGNING_SUPPORTED:
    124                 if (transport->negotiate.security_mode & SMB2_NEGOTIATE_SIGNING_REQUIRED) {
    125                         transport->signing_required = true;
    126                 } else {
    127                         transport->signing_required = false;
    128                 }
    129                 break;
    130         case SMB_SIGNING_AUTO:
    131                 if (transport->negotiate.security_mode & SMB2_NEGOTIATE_SIGNING_ENABLED) {
    132                         transport->signing_required = true;
    133                 } else {
    134                         transport->signing_required = false;
    135                 }
    136                 break;
    137         case SMB_SIGNING_REQUIRED:
    138                 if (transport->negotiate.security_mode & SMB2_NEGOTIATE_SIGNING_ENABLED) {
    139                         transport->signing_required = true;
    140                 } else {
    141                         composite_error(c, NT_STATUS_ACCESS_DENIED);
    142                         return;
    143                 }
    144                 break;
    145         }
    146 
    147         state->session = smb2_session_init(transport, state->gensec_settings, state, true);
    148         if (composite_nomem(state->session, c)) return;
    149 
    150         creq = smb2_session_setup_spnego_send(state->session, state->credentials);
    151 
    152         composite_continue(c, creq, continue_session, c);
    153 }
    154 
    155 /*
    156   continue after a socket connect completes
    157 */
    158 static void continue_socket(struct composite_context *creq)
    159 {
    160         struct composite_context *c = talloc_get_type(creq->async.private_data,
    161                                                       struct composite_context);
    162         struct smb2_connect_state *state = talloc_get_type(c->private_data,
    163                                                            struct smb2_connect_state);
    164         struct smbcli_socket *sock;
    165         struct smb2_transport *transport;
    166         struct smb2_request *req;
    167         uint16_t dialects[3] = {
    168                 SMB2_DIALECT_REVISION_000,
    169                 SMB2_DIALECT_REVISION_202,
    170                 SMB2_DIALECT_REVISION_210
    171         };
    172 
    173         c->status = smbcli_sock_connect_recv(creq, state, &sock);
    174         if (!composite_is_ok(c)) return;
    175 
    176         transport = smb2_transport_init(sock, state, &state->options);
    177         if (composite_nomem(transport, c)) return;
    178 
    179         ZERO_STRUCT(state->negprot);
    180         state->negprot.in.dialect_count = sizeof(dialects) / sizeof(dialects[0]);
    181         switch (transport->options.signing) {
    182         case SMB_SIGNING_OFF:
    183                 state->negprot.in.security_mode = 0;
    184                 break;
    185         case SMB_SIGNING_SUPPORTED:
    186         case SMB_SIGNING_AUTO:
    187                 state->negprot.in.security_mode = SMB2_NEGOTIATE_SIGNING_ENABLED;
    188                 break;
    189         case SMB_SIGNING_REQUIRED:
    190                 state->negprot.in.security_mode =
    191                         SMB2_NEGOTIATE_SIGNING_ENABLED | SMB2_NEGOTIATE_SIGNING_REQUIRED;
    192                 break;
    193         }
    194         state->negprot.in.capabilities  = 0;
    195         unix_to_nt_time(&state->negprot.in.start_time, time(NULL));
    196         state->negprot.in.dialects = dialects;
    197 
    198         req = smb2_negprot_send(transport, &state->negprot);
    199         if (composite_nomem(req, c)) return;
    200 
    201         req->async.fn = continue_negprot;
    202         req->async.private_data = c;
    203 }
    204 
    205 
    206 /*
    207   continue after a resolve finishes
    208 */
    209 static void continue_resolve(struct composite_context *creq)
    210 {
    211         struct composite_context *c = talloc_get_type(creq->async.private_data,
    212                                                       struct composite_context);
    213         struct smb2_connect_state *state = talloc_get_type(c->private_data,
    214                                                            struct smb2_connect_state);
    215         const char *addr;
    216         const char **ports;
    217         const char *default_ports[] = { "445", NULL };
    218 
    219         c->status = resolve_name_recv(creq, state, &addr);
    220         if (!composite_is_ok(c)) return;
    221 
    222         if (state->ports == NULL) {
    223                 ports = default_ports;
    224         } else {
    225                 ports = state->ports;
    226         }
    227 
    228         creq = smbcli_sock_connect_send(state, addr, ports, state->host, state->resolve_ctx, c->event_ctx, state->socket_options);
    229 
    230         composite_continue(c, creq, continue_socket, c);
    231 }
     53static void smb2_connect_socket_done(struct composite_context *creq);
    23254
    23355/*
     
    23557  a connected smb2_tree
    23658 */
    237 struct composite_context *smb2_connect_send(TALLOC_CTX *mem_ctx,
    238                                             const char *host,
    239                                                 const char **ports,
    240                                             const char *share,
    241                                             struct resolve_context *resolve_ctx,
    242                                             struct cli_credentials *credentials,
    243                                             struct tevent_context *ev,
    244                                             struct smbcli_options *options,
    245                                                 const char *socket_options,
    246                                                 struct gensec_settings *gensec_settings)
    247 {
    248         struct composite_context *c;
     59struct tevent_req *smb2_connect_send(TALLOC_CTX *mem_ctx,
     60                                     struct tevent_context *ev,
     61                                     const char *host,
     62                                     const char **ports,
     63                                     const char *share,
     64                                     struct resolve_context *resolve_ctx,
     65                                     struct cli_credentials *credentials,
     66                                     uint64_t previous_session_id,
     67                                     const struct smbcli_options *options,
     68                                     const char *socket_options,
     69                                     struct gensec_settings *gensec_settings)
     70{
     71        struct tevent_req *req;
    24972        struct smb2_connect_state *state;
    250         struct nbt_name name;
    25173        struct composite_context *creq;
    252 
    253         c = composite_create(mem_ctx, ev);
    254         if (c == NULL) return NULL;
    255 
    256         state = talloc(c, struct smb2_connect_state);
    257         if (composite_nomem(state, c)) return c;
    258         c->private_data = state;
    259 
     74        static const char *default_ports[] = { "445", "139", NULL };
     75
     76        req = tevent_req_create(mem_ctx, &state,
     77                                struct smb2_connect_state);
     78        if (req == NULL) {
     79                return NULL;
     80        }
     81
     82        state->ev = ev;
    26083        state->credentials = credentials;
     84        state->previous_session_id = previous_session_id;
    26185        state->options = *options;
    262         state->host = talloc_strdup(c, host);
    263         if (composite_nomem(state->host, c)) return c;
    264         state->ports = talloc_reference(state, ports);
    265         state->share = talloc_strdup(c, share);
    266         if (composite_nomem(state->share, c)) return c;
    267         state->resolve_ctx = talloc_reference(state, resolve_ctx);
    268         state->socket_options = talloc_reference(state, socket_options);
    269         state->gensec_settings = talloc_reference(state, gensec_settings);
    270 
    271         ZERO_STRUCT(name);
    272         name.name = host;
    273 
    274         creq = resolve_name_send(resolve_ctx, state, &name, c->event_ctx);
    275         composite_continue(c, creq, continue_resolve, c);
    276         return c;
    277 }
    278 
    279 /*
    280   receive a connect reply
    281 */
    282 NTSTATUS smb2_connect_recv(struct composite_context *c, TALLOC_CTX *mem_ctx,
     86        state->host = host;
     87        state->ports = ports;
     88        state->share = share;
     89        state->resolve_ctx = resolve_ctx;
     90        state->socket_options = socket_options;
     91        state->gensec_settings = gensec_settings;
     92
     93        if (state->ports == NULL) {
     94                state->ports = default_ports;
     95        }
     96
     97        make_nbt_name_client(&state->calling,
     98                             cli_credentials_get_workstation(credentials));
     99
     100        nbt_choose_called_name(state, &state->called,
     101                               host, NBT_NAME_SERVER);
     102
     103        state->unc = talloc_asprintf(state, "\\\\%s\\%s",
     104                                    state->host, state->share);
     105        if (tevent_req_nomem(state->unc, req)) {
     106                return tevent_req_post(req, ev);
     107        }
     108
     109        creq = smbcli_sock_connect_send(state, NULL, state->ports,
     110                                        state->host, state->resolve_ctx,
     111                                        state->ev, state->socket_options,
     112                                        &state->calling,
     113                                        &state->called);
     114        if (tevent_req_nomem(creq, req)) {
     115                return tevent_req_post(req, ev);
     116        }
     117        creq->async.fn = smb2_connect_socket_done;
     118        creq->async.private_data = req;
     119
     120        return req;
     121}
     122
     123static void smb2_connect_negprot_done(struct tevent_req *subreq);
     124
     125static void smb2_connect_socket_done(struct composite_context *creq)
     126{
     127        struct tevent_req *req =
     128                talloc_get_type_abort(creq->async.private_data,
     129                struct tevent_req);
     130        struct smb2_connect_state *state =
     131                tevent_req_data(req,
     132                struct smb2_connect_state);
     133        struct smbcli_socket *sock;
     134        struct tevent_req *subreq;
     135        NTSTATUS status;
     136        uint32_t timeout_msec;
     137        enum protocol_types min_protocol;
     138
     139        status = smbcli_sock_connect_recv(creq, state, &sock);
     140        if (tevent_req_nterror(req, status)) {
     141                return;
     142        }
     143
     144        state->transport = smb2_transport_init(sock, state, &state->options);
     145        if (tevent_req_nomem(state->transport, req)) {
     146                return;
     147        }
     148
     149        timeout_msec = state->transport->options.request_timeout * 1000;
     150        min_protocol = state->transport->options.min_protocol;
     151        if (min_protocol < PROTOCOL_SMB2_02) {
     152                min_protocol = PROTOCOL_SMB2_02;
     153        }
     154
     155        subreq = smbXcli_negprot_send(state, state->ev,
     156                                      state->transport->conn, timeout_msec,
     157                                      min_protocol,
     158                                      state->transport->options.max_protocol);
     159        if (tevent_req_nomem(subreq, req)) {
     160                return;
     161        }
     162        tevent_req_set_callback(subreq, smb2_connect_negprot_done, req);
     163}
     164
     165static void smb2_connect_session_done(struct tevent_req *subreq);
     166
     167static void smb2_connect_negprot_done(struct tevent_req *subreq)
     168{
     169        struct tevent_req *req =
     170                tevent_req_callback_data(subreq,
     171                struct tevent_req);
     172        struct smb2_connect_state *state =
     173                tevent_req_data(req,
     174                struct smb2_connect_state);
     175        struct smb2_transport *transport = state->transport;
     176        NTSTATUS status;
     177
     178        status = smbXcli_negprot_recv(subreq);
     179        TALLOC_FREE(subreq);
     180        if (tevent_req_nterror(req, status)) {
     181                return;
     182        }
     183
     184        /* This is a hack... */
     185        smb2cli_conn_set_max_credits(transport->conn, 30);
     186
     187        state->session = smb2_session_init(transport, state->gensec_settings, state);
     188        if (tevent_req_nomem(state->session, req)) {
     189                return;
     190        }
     191
     192        subreq = smb2_session_setup_spnego_send(state, state->ev,
     193                                                state->session,
     194                                                state->credentials,
     195                                                state->previous_session_id);
     196        if (tevent_req_nomem(subreq, req)) {
     197                return;
     198        }
     199        tevent_req_set_callback(subreq, smb2_connect_session_done, req);
     200}
     201
     202static void smb2_connect_tcon_done(struct tevent_req *subreq);
     203
     204static void smb2_connect_session_done(struct tevent_req *subreq)
     205{
     206        struct tevent_req *req =
     207                tevent_req_callback_data(subreq,
     208                struct tevent_req);
     209        struct smb2_connect_state *state =
     210                tevent_req_data(req,
     211                struct smb2_connect_state);
     212        NTSTATUS status;
     213        uint32_t timeout_msec;
     214
     215        status = smb2_session_setup_spnego_recv(subreq);
     216        TALLOC_FREE(subreq);
     217        if (tevent_req_nterror(req, status)) {
     218                return;
     219        }
     220
     221        state->tree = smb2_tree_init(state->session, state, true);
     222        if (tevent_req_nomem(state->tree, req)) {
     223                return;
     224        }
     225
     226        timeout_msec = state->transport->options.request_timeout * 1000;
     227
     228        subreq = smb2cli_tcon_send(state, state->ev,
     229                                   state->transport->conn,
     230                                   timeout_msec,
     231                                   state->session->smbXcli,
     232                                   state->tree->smbXcli,
     233                                   0, /* flags */
     234                                   state->unc);
     235        if (tevent_req_nomem(subreq, req)) {
     236                return;
     237        }
     238        tevent_req_set_callback(subreq, smb2_connect_tcon_done, req);
     239}
     240
     241static void smb2_connect_tcon_done(struct tevent_req *subreq)
     242{
     243        struct tevent_req *req =
     244                tevent_req_callback_data(subreq,
     245                struct tevent_req);
     246        NTSTATUS status;
     247
     248        status = smb2cli_tcon_recv(subreq);
     249        if (tevent_req_nterror(req, status)) {
     250                return;
     251        }
     252
     253        tevent_req_done(req);
     254}
     255
     256NTSTATUS smb2_connect_recv(struct tevent_req *req,
     257                           TALLOC_CTX *mem_ctx,
    283258                           struct smb2_tree **tree)
    284259{
    285         NTSTATUS status;
    286         struct smb2_connect_state *state = talloc_get_type(c->private_data,
    287                                                            struct smb2_connect_state);
    288         status = composite_wait(c);
    289         if (NT_STATUS_IS_OK(status)) {
    290                 *tree = talloc_steal(mem_ctx, state->tree);
    291         }
    292         talloc_free(c);
    293         return status;
     260        struct smb2_connect_state *state =
     261                tevent_req_data(req,
     262                struct smb2_connect_state);
     263        NTSTATUS status;
     264
     265        if (tevent_req_is_nterror(req, &status)) {
     266                tevent_req_received(req);
     267                return status;
     268        }
     269
     270        *tree = talloc_move(mem_ctx, &state->tree);
     271
     272        tevent_req_received(req);
     273        return NT_STATUS_OK;
    294274}
    295275
     
    297277  sync version of smb2_connect
    298278*/
    299 NTSTATUS smb2_connect(TALLOC_CTX *mem_ctx,
    300                       const char *host, const char **ports,
     279NTSTATUS smb2_connect_ext(TALLOC_CTX *mem_ctx,
     280                          const char *host,
     281                          const char **ports,
    301282                          const char *share,
     283                          struct resolve_context *resolve_ctx,
     284                          struct cli_credentials *credentials,
     285                          uint64_t previous_session_id,
     286                          struct smb2_tree **tree,
     287                          struct tevent_context *ev,
     288                          const struct smbcli_options *options,
     289                          const char *socket_options,
     290                          struct gensec_settings *gensec_settings)
     291{
     292        struct tevent_req *subreq;
     293        NTSTATUS status;
     294        bool ok;
     295        TALLOC_CTX *frame = talloc_stackframe();
     296
     297        if (frame == NULL) {
     298                return NT_STATUS_NO_MEMORY;
     299        }
     300
     301        subreq = smb2_connect_send(frame,
     302                                   ev,
     303                                   host,
     304                                   ports,
     305                                   share,
     306                                   resolve_ctx,
     307                                   credentials,
     308                                   previous_session_id,
     309                                   options,
     310                                   socket_options,
     311                                   gensec_settings);
     312        if (subreq == NULL) {
     313                TALLOC_FREE(frame);
     314                return NT_STATUS_NO_MEMORY;
     315        }
     316
     317        ok = tevent_req_poll(subreq, ev);
     318        if (!ok) {
     319                status = map_nt_error_from_unix_common(errno);
     320                TALLOC_FREE(frame);
     321                return status;
     322        }
     323
     324        status = smb2_connect_recv(subreq, mem_ctx, tree);
     325        TALLOC_FREE(subreq);
     326        if (!NT_STATUS_IS_OK(status)) {
     327                TALLOC_FREE(frame);
     328                return status;
     329        }
     330
     331        TALLOC_FREE(frame);
     332        return NT_STATUS_OK;
     333}
     334
     335NTSTATUS smb2_connect(TALLOC_CTX *mem_ctx,
     336                      const char *host,
     337                      const char **ports,
     338                      const char *share,
    302339                      struct resolve_context *resolve_ctx,
    303340                      struct cli_credentials *credentials,
     
    305342                      struct tevent_context *ev,
    306343                      struct smbcli_options *options,
    307                           const char *socket_options,
    308                           struct gensec_settings *gensec_settings)
    309 {
    310         struct composite_context *c = smb2_connect_send(mem_ctx, host, ports,
    311                                                                                                         share, resolve_ctx,
    312                                                                                                         credentials, ev, options,
    313                                                                                                         socket_options,
    314                                                                                                         gensec_settings);
    315         return smb2_connect_recv(c, mem_ctx, tree);
    316 }
     344                      const char *socket_options,
     345                      struct gensec_settings *gensec_settings)
     346{
     347        NTSTATUS status;
     348
     349        status = smb2_connect_ext(mem_ctx, host, ports, share, resolve_ctx,
     350                                  credentials,
     351                                  0, /* previous_session_id */
     352                                  tree, ev, options, socket_options,
     353                                  gensec_settings);
     354
     355        return status;
     356}
  • vendor/current/source4/libcli/smb2/create.c

    r740 r988  
    107107        }
    108108
     109        if (io->in.durable_open_v2) {
     110                uint8_t data[32];
     111                uint32_t flags = 0;
     112                DATA_BLOB guid_blob;
     113
     114                SIVAL(data, 0, io->in.timeout);
     115                if (io->in.persistent_open) {
     116                        flags = SMB2_DHANDLE_FLAG_PERSISTENT;
     117                }
     118                SIVAL(data, 4, flags);
     119                SBVAL(data, 8, 0x0); /* reserved */
     120                status = GUID_to_ndr_blob(&io->in.create_guid, req, /* TALLOC_CTX */
     121                                          &guid_blob);
     122                if (!NT_STATUS_IS_OK(status)) {
     123                        talloc_free(req);
     124                        return NULL;
     125                }
     126                memcpy(data+16, guid_blob.data, 16);
     127
     128                status = smb2_create_blob_add(req, &blobs,
     129                                              SMB2_CREATE_TAG_DH2Q,
     130                                              data_blob_const(data, 32));
     131                if (!NT_STATUS_IS_OK(status)) {
     132                        talloc_free(req);
     133                        return NULL;
     134                }
     135        }
     136
    109137        if (io->in.durable_handle) {
    110138                uint8_t data[16];
     
    112140                status = smb2_create_blob_add(req, &blobs,
    113141                                              SMB2_CREATE_TAG_DHNC, data_blob_const(data, 16));
     142                if (!NT_STATUS_IS_OK(status)) {
     143                        talloc_free(req);
     144                        return NULL;
     145                }
     146        }
     147
     148        if (io->in.durable_handle_v2) {
     149                uint8_t data[36];
     150                DATA_BLOB guid_blob;
     151                uint32_t flags = 0;
     152
     153                smb2_push_handle(data, io->in.durable_handle_v2);
     154                status = GUID_to_ndr_blob(&io->in.create_guid, req, /* TALLOC_CTX */
     155                                          &guid_blob);
     156                if (!NT_STATUS_IS_OK(status)) {
     157                        talloc_free(req);
     158                        return NULL;
     159                }
     160                memcpy(data+16, guid_blob.data, 16);
     161                if (io->in.persistent_open) {
     162                        flags = SMB2_DHANDLE_FLAG_PERSISTENT;
     163                }
     164                SIVAL(data, 32, flags);
     165
     166                status = smb2_create_blob_add(req, &blobs,
     167                                              SMB2_CREATE_TAG_DH2C,
     168                                              data_blob_const(data, 36));
    114169                if (!NT_STATUS_IS_OK(status)) {
    115170                        talloc_free(req);
     
    158213                uint8_t data[32];
    159214
    160                 memcpy(&data[0], &io->in.lease_request->lease_key, 16);
    161                 SIVAL(data, 16, io->in.lease_request->lease_state);
    162                 SIVAL(data, 20, io->in.lease_request->lease_flags);
    163                 SBVAL(data, 24, io->in.lease_request->lease_duration);
    164 
    165                 status = smb2_create_blob_add(req, &blobs,
    166                                               SMB2_CREATE_TAG_RQLS,
    167                                               data_blob_const(data, 32));
     215                if (!smb2_lease_push(io->in.lease_request, data,
     216                                     sizeof(data))) {
     217                        TALLOC_FREE(req);
     218                        return NULL;
     219                }
     220
     221                status = smb2_create_blob_add(
     222                        req, &blobs, SMB2_CREATE_TAG_RQLS,
     223                        data_blob_const(data, sizeof(data)));
     224                if (!NT_STATUS_IS_OK(status)) {
     225                        talloc_free(req);
     226                        return NULL;
     227                }
     228        }
     229
     230        if (io->in.lease_request_v2) {
     231                uint8_t data[52];
     232
     233                if (!smb2_lease_push(io->in.lease_request_v2, data,
     234                                     sizeof(data))) {
     235                        TALLOC_FREE(req);
     236                        return NULL;
     237                }
     238
     239                status = smb2_create_blob_add(
     240                        req, &blobs, SMB2_CREATE_TAG_RQLS,
     241                        data_blob_const(data, sizeof(data)));
     242                if (!NT_STATUS_IS_OK(status)) {
     243                        talloc_free(req);
     244                        return NULL;
     245                }
     246        }
     247
     248        if (io->in.app_instance_id) {
     249                uint8_t data[20];
     250                DATA_BLOB guid_blob;
     251
     252                SSVAL(data, 0, 20); /* structure size */
     253                SSVAL(data, 2, 0);  /* reserved */
     254
     255                status = GUID_to_ndr_blob(io->in.app_instance_id,
     256                                          req, /* TALLOC_CTX */
     257                                          &guid_blob);
     258                if (!NT_STATUS_IS_OK(status)) {
     259                        talloc_free(req);
     260                        return NULL;
     261                }
     262                memcpy(data+4, guid_blob.data, 16);
     263
     264                status = smb2_create_blob_add(req, &blobs,
     265                                              SMB2_CREATE_TAG_APP_INSTANCE_ID,
     266                                              data_blob_const(data, 20));
    168267                if (!NT_STATUS_IS_OK(status)) {
    169268                        talloc_free(req);
     
    194293                talloc_free(req);
    195294                return NULL;
     295        }
     296
     297        if (((io->in.fname == NULL) || (strlen(io->in.fname) == 0)) &&
     298            (blob.length == 0)) {
     299                struct smb2_request_buffer *buf = &req->out;
     300
     301                status = smb2_grow_buffer(buf, 1);
     302                if (!NT_STATUS_IS_OK(status)) {
     303                        talloc_free(req);
     304                        return NULL;
     305                }
     306                buf->dynamic[0] = 0;
     307                buf->dynamic += 1;
     308                buf->body_size += 1;
     309                buf->size += 1;
    196310        }
    197311
     
    263377                }
    264378                if (strcmp(io->out.blobs.blobs[i].tag, SMB2_CREATE_TAG_RQLS) == 0) {
     379                        struct smb2_lease *ls = NULL;
    265380                        uint8_t *data;
    266                         if (io->out.blobs.blobs[i].data.length != 32) {
     381
     382                        ZERO_STRUCT(io->out.lease_response);
     383                        ZERO_STRUCT(io->out.lease_response_v2);
     384
     385                        switch (io->out.blobs.blobs[i].data.length) {
     386                        case 32:
     387                                ls = &io->out.lease_response;
     388                                ls->lease_version = 1;
     389                                break;
     390                        case 52:
     391                                ls = &io->out.lease_response_v2;
     392                                ls->lease_version = 2;
     393                                break;
     394                        default:
    267395                                smb2_request_destroy(req);
    268396                                return NT_STATUS_INVALID_NETWORK_RESPONSE;
     
    270398
    271399                        data = io->out.blobs.blobs[i].data.data;
    272                         memcpy(&io->out.lease_response.lease_key, data, 16);
    273                         io->out.lease_response.lease_state = IVAL(data, 16);
    274                         io->out.lease_response.lease_flags = IVAL(data, 20);
    275                         io->out.lease_response.lease_duration = BVAL(data, 24);
     400                        memcpy(&ls->lease_key, data, 16);
     401                        ls->lease_state = IVAL(data, 16);
     402                        ls->lease_flags = IVAL(data, 20);
     403                        ls->lease_duration = BVAL(data, 24);
     404
     405                        if (io->out.blobs.blobs[i].data.length == 52) {
     406                                memcpy(&ls->parent_lease_key, data+32, 16);
     407                                ls->lease_epoch = SVAL(data, 48);
     408                        }
     409                }
     410                if (strcmp(io->out.blobs.blobs[i].tag, SMB2_CREATE_TAG_DHNQ) == 0) {
     411                        if (io->out.blobs.blobs[i].data.length != 8) {
     412                                smb2_request_destroy(req);
     413                                return NT_STATUS_INVALID_NETWORK_RESPONSE;
     414                        }
     415                        io->out.durable_open = true;
     416                }
     417                if (strcmp(io->out.blobs.blobs[i].tag, SMB2_CREATE_TAG_DH2Q) == 0) {
     418                        uint32_t flags;
     419                        uint8_t *data;
     420
     421                        if (io->out.blobs.blobs[i].data.length != 8) {
     422                                smb2_request_destroy(req);
     423                                return NT_STATUS_INVALID_NETWORK_RESPONSE;
     424                        }
     425
     426                        io->out.durable_open = false;
     427                        io->out.durable_open_v2 = true;
     428
     429                        data = io->out.blobs.blobs[i].data.data;
     430                        io->out.timeout = IVAL(data, 0);
     431                        flags = IVAL(data, 4);
     432                        if ((flags & SMB2_DHANDLE_FLAG_PERSISTENT) != 0) {
     433                                io->out.persistent_open = true;
     434                        }
    276435                }
    277436        }
  • vendor/current/source4/libcli/smb2/find.c

    r740 r988  
    3434        NTSTATUS status;
    3535
    36         req = smb2_request_init_tree(tree, SMB2_OP_FIND, 0x20, true, 0);
     36        req = smb2_request_init_tree(tree, SMB2_OP_QUERY_DIRECTORY, 0x20, true, 0);
    3737        if (req == NULL) return NULL;
    3838
  • vendor/current/source4/libcli/smb2/ioctl.c

    r414 r988  
    2323#include "libcli/smb2/smb2.h"
    2424#include "libcli/smb2/smb2_calls.h"
     25#include "librpc/gen_ndr/ioctl.h"
    2526
    2627/*
     
    6263}
    6364
     65/*
     66 * 3.3.4.4 Sending an Error Response
     67 */
     68static bool smb2_ioctl_is_failure(uint32_t ctl_code, NTSTATUS status,
     69                                  size_t data_size)
     70{
     71        if (NT_STATUS_IS_OK(status)) {
     72                return false;
     73        }
     74
     75        if (NT_STATUS_EQUAL(status, STATUS_BUFFER_OVERFLOW)
     76         && ((ctl_code == FSCTL_PIPE_TRANSCEIVE)
     77          || (ctl_code == FSCTL_PIPE_PEEK)
     78          || (ctl_code == FSCTL_DFS_GET_REFERRALS))) {
     79                return false;
     80        }
     81
     82        if (((ctl_code == FSCTL_SRV_COPYCHUNK)
     83                                || (ctl_code == FSCTL_SRV_COPYCHUNK_WRITE))
     84         && (data_size == sizeof(struct srv_copychunk_rsp))) {
     85                /*
     86                 * copychunk responses may come with copychunk data or error
     87                 * response data, independent of status.
     88                 */
     89                return false;
     90        }
     91
     92        return true;
     93}
    6494
    6595/*
    6696  recv a ioctl reply
    6797*/
    68 NTSTATUS smb2_ioctl_recv(struct smb2_request *req, 
     98NTSTATUS smb2_ioctl_recv(struct smb2_request *req,
    6999                         TALLOC_CTX *mem_ctx, struct smb2_ioctl *io)
    70100{
    71101        NTSTATUS status;
    72102
    73         if (!smb2_request_receive(req) ||
    74             smb2_request_is_error(req)) {
     103        if (!smb2_request_receive(req) ||
     104            smb2_ioctl_is_failure(io->in.function, req->status,
     105                                  req->in.bufinfo.data_size)) {
    75106                return smb2_request_destroy(req);
    76107        }
  • vendor/current/source4/libcli/smb2/logoff.c

    r414 r988  
    3636        req->session = session;
    3737
    38         SBVAL(req->out.hdr,  SMB2_HDR_SESSION_ID, session->uid);
    39 
    4038        SSVAL(req->out.body, 0x02, 0);
    4139
  • vendor/current/source4/libcli/smb2/read.c

    r414 r988  
    4545        SSVAL(req->out.body, 0x2E, io->in.channel_length);
    4646
     47        req->credit_charge = (MAX(io->in.length, 1) - 1)/ 65536 + 1;
     48
    4749        smb2_transport_send(req);
    4850
  • vendor/current/source4/libcli/smb2/request.c

    r740 r988  
    4343}
    4444
    45 
    46 /* destroy a request structure */
    47 static int smb2_request_destructor(struct smb2_request *req)
    48 {
    49         if (req->transport) {
    50                 /* remove it from the list of pending requests (a null op if
    51                    its not in the list) */
    52                 DLIST_REMOVE(req->transport->pending_recv, req);
    53         }
    54         return 0;
    55 }
    56 
    5745/*
    5846  initialise a smb2 request
     
    6351{
    6452        struct smb2_request *req;
    65         uint64_t seqnum;
    6653        uint32_t hdr_offset;
    67         uint32_t flags = 0;
    6854        bool compound = false;
    6955
     
    7662        }
    7763
    78         req = talloc(transport, struct smb2_request);
     64        req = talloc_zero(transport, struct smb2_request);
    7965        if (req == NULL) return NULL;
    80 
    81         seqnum = transport->seqnum;
    82         if (transport->credits.charge > 0) {
    83                 transport->seqnum += transport->credits.charge;
    84         } else {
    85                 transport->seqnum += 1;
    86         }
    8766
    8867        req->state     = SMB2_REQUEST_INIT;
    8968        req->transport = transport;
    90         req->session   = NULL;
    91         req->tree      = NULL;
    92         req->seqnum    = seqnum;
    93         req->status    = NT_STATUS_OK;
    94         req->async.fn  = NULL;
    95         req->next = req->prev = NULL;
    96 
    97         ZERO_STRUCT(req->cancel);
    98         ZERO_STRUCT(req->in);
    99 
    100         if (transport->compound.missing > 0) {
    101                 compound = true;
    102                 transport->compound.missing -= 1;
    103                 req->out = transport->compound.buffer;
    104                 ZERO_STRUCT(transport->compound.buffer);
    105                 if (transport->compound.related) {
    106                         flags |= SMB2_HDR_FLAG_CHAINED;
    107                 }
    108         } else {
    109                 ZERO_STRUCT(req->out);
    110         }
    111 
    112         if (req->out.size > 0) {
    113                 hdr_offset = req->out.size;
    114         } else {
    115                 hdr_offset = NBT_HDR_SIZE;
    116         }
     69
     70        hdr_offset = NBT_HDR_SIZE;
    11771
    11872        req->out.size      = hdr_offset + SMB2_HDR_BODY + body_fixed_size;
     
    13488        SIVAL(req->out.hdr, 0,                          SMB2_MAGIC);
    13589        SSVAL(req->out.hdr, SMB2_HDR_LENGTH,            SMB2_HDR_BODY);
    136         SSVAL(req->out.hdr, SMB2_HDR_EPOCH,             transport->credits.charge);
     90        SSVAL(req->out.hdr, SMB2_HDR_CREDIT_CHARGE,     0);
    13791        SIVAL(req->out.hdr, SMB2_HDR_STATUS,            0);
    13892        SSVAL(req->out.hdr, SMB2_HDR_OPCODE,            opcode);
    139         SSVAL(req->out.hdr, SMB2_HDR_CREDIT,            transport->credits.ask_num);
    140         SIVAL(req->out.hdr, SMB2_HDR_FLAGS,             flags);
     93        SSVAL(req->out.hdr, SMB2_HDR_CREDIT,            0);
     94        SIVAL(req->out.hdr, SMB2_HDR_FLAGS,             0);
    14195        SIVAL(req->out.hdr, SMB2_HDR_NEXT_COMMAND,      0);
    142         SBVAL(req->out.hdr, SMB2_HDR_MESSAGE_ID,        req->seqnum);
     96        SBVAL(req->out.hdr, SMB2_HDR_MESSAGE_ID,        0);
    14397        SIVAL(req->out.hdr, SMB2_HDR_PID,               0);
    14498        SIVAL(req->out.hdr, SMB2_HDR_TID,               0);
     
    158112        }
    159113
    160         talloc_set_destructor(req, smb2_request_destructor);
    161 
    162114        return req;
    163115}
     
    175127        if (req == NULL) return NULL;
    176128
    177         SBVAL(req->out.hdr,  SMB2_HDR_SESSION_ID, tree->session->uid);
    178         SIVAL(req->out.hdr,  SMB2_HDR_PID, tree->session->pid);
    179         SIVAL(req->out.hdr,  SMB2_HDR_TID, tree->tid);
    180129        req->session = tree->session;
    181130        req->tree = tree;
     
    215164        /* keep receiving packets until this one is replied to */
    216165        while (req->state <= SMB2_REQUEST_RECV) {
    217                 if (event_loop_once(req->transport->socket->event.ctx) != 0) {
     166                if (tevent_loop_once(req->transport->ev) != 0) {
    218167                        return false;
    219168                }
     
    687636        NTSTATUS status;
    688637        void *vstr;
     638        size_t converted_size = 0;
    689639        bool ret;
    690640
     
    706656
    707657        ret = convert_string_talloc(mem_ctx, CH_UTF16, CH_UNIX,
    708                                      blob.data, blob.length, &vstr, NULL, false);
     658                                     blob.data, blob.length, &vstr, &converted_size);
    709659        data_blob_free(&blob);
    710660        (*str) = (char *)vstr;
     
    725675        NTSTATUS status;
    726676        bool ret;
     677        void *ptr = NULL;
    727678
    728679        if (str == NULL) {
     
    737688
    738689        ret = convert_string_talloc(buf->buffer, CH_UNIX, CH_UTF16,
    739                                      str, strlen(str), (void **)&blob.data, &blob.length,
    740                                          false);
     690                                    str, strlen(str), &ptr, &blob.length);
    741691        if (!ret) {
    742692                return NT_STATUS_ILLEGAL_CHARACTER;
    743693        }
     694        blob.data = (uint8_t *)ptr;
    744695
    745696        status = smb2_push_o16s16_blob(buf, ofs, blob);
  • vendor/current/source4/libcli/smb2/session.c

    r740 r988  
    2121
    2222#include "includes.h"
     23#include "system/network.h"
     24#include <tevent.h>
     25#include "lib/util/tevent_ntstatus.h"
    2326#include "libcli/raw/libcliraw.h"
    2427#include "libcli/smb2/smb2.h"
    2528#include "libcli/smb2/smb2_calls.h"
    26 #include "libcli/composite/composite.h"
    2729#include "auth/gensec/gensec.h"
    28 
    29 #include <unistd.h>
     30#include "auth/credentials/credentials.h"
     31#include "../libcli/smb/smbXcli_base.h"
    3032
    3133/**
     
    3436struct smb2_session *smb2_session_init(struct smb2_transport *transport,
    3537                                       struct gensec_settings *settings,
    36                                        TALLOC_CTX *parent_ctx, bool primary)
     38                                       TALLOC_CTX *parent_ctx)
    3739{
    3840        struct smb2_session *session;
     
    4345                return NULL;
    4446        }
    45         if (primary) {
    46                 session->transport = talloc_steal(session, transport);
    47         } else {
    48                 session->transport = talloc_reference(session, transport);
    49         }
    50 
    51         session->pid = getpid();
     47        session->transport = talloc_steal(session, transport);
     48
     49        session->smbXcli = smbXcli_session_create(session, transport->conn);
     50        if (session->smbXcli == NULL) {
     51                talloc_free(session);
     52                return NULL;
     53        }
    5254
    5355        /* prepare a gensec context for later use */
    54         status = gensec_client_start(session, &session->gensec,
    55                                      session->transport->socket->event.ctx,
     56        status = gensec_client_start(session, &session->gensec,
    5657                                     settings);
    5758        if (!NT_STATUS_IS_OK(status)) {
     
    6566}
    6667
    67 /**
    68   send a session setup request
    69 */
    70 struct smb2_request *smb2_session_setup_send(struct smb2_session *session,
    71                                              struct smb2_session_setup *io)
    72 {
    73         struct smb2_request *req;
    74         NTSTATUS status;
    75        
    76         req = smb2_request_init(session->transport, SMB2_OP_SESSSETUP,
    77                                 0x18, true, io->in.secblob.length);
    78         if (req == NULL) return NULL;
    79 
    80         SBVAL(req->out.hdr,  SMB2_HDR_SESSION_ID, session->uid);
    81         SCVAL(req->out.body, 0x02, io->in.vc_number);
    82         SCVAL(req->out.body, 0x03, io->in.security_mode);
    83         SIVAL(req->out.body, 0x04, io->in.capabilities);
    84         SIVAL(req->out.body, 0x08, io->in.channel);
    85         SBVAL(req->out.body, 0x10, io->in.previous_sessionid);
    86 
    87         req->session = session;
    88 
    89         status = smb2_push_o16s16_blob(&req->out, 0x0C, io->in.secblob);
     68/*
     69 * Note: that the caller needs to keep 'transport' around as
     70 *       long as the returned session is active!
     71 */
     72struct smb2_session *smb2_session_channel(struct smb2_transport *transport,
     73                                          struct gensec_settings *settings,
     74                                          TALLOC_CTX *parent_ctx,
     75                                          struct smb2_session *base_session)
     76{
     77        struct smb2_session *session;
     78        NTSTATUS status;
     79
     80        session = talloc_zero(parent_ctx, struct smb2_session);
     81        if (!session) {
     82                return NULL;
     83        }
     84        session->transport = transport;
     85
     86        status = smb2cli_session_create_channel(session,
     87                                                base_session->smbXcli,
     88                                                transport->conn,
     89                                                &session->smbXcli);
    9090        if (!NT_STATUS_IS_OK(status)) {
    91                 talloc_free(req);
    92                 return NULL;
    93         }
    94 
    95         smb2_transport_send(req);
    96 
    97         return req;
    98 }
    99 
    100 
    101 /**
    102   recv a session setup reply
    103 */
    104 NTSTATUS smb2_session_setup_recv(struct smb2_request *req, TALLOC_CTX *mem_ctx,
    105                                  struct smb2_session_setup *io)
    106 {
    107         NTSTATUS status;
    108 
    109         if (!smb2_request_receive(req) ||
    110             (smb2_request_is_error(req) &&
    111              !NT_STATUS_EQUAL(req->status, NT_STATUS_MORE_PROCESSING_REQUIRED))) {
    112                 return smb2_request_destroy(req);
    113         }
    114 
    115         SMB2_CHECK_PACKET_RECV(req, 0x08, true);
    116 
    117         io->out.session_flags = SVAL(req->in.body, 0x02);
    118         io->out.uid           = BVAL(req->in.hdr,  SMB2_HDR_SESSION_ID);
    119        
    120         status = smb2_pull_o16s16_blob(&req->in, mem_ctx, req->in.body+0x04, &io->out.secblob);
     91                talloc_free(session);
     92                return NULL;
     93        }
     94
     95        session->needs_bind = true;
     96
     97        /* prepare a gensec context for later use */
     98        status = gensec_client_start(session, &session->gensec,
     99                                     settings);
    121100        if (!NT_STATUS_IS_OK(status)) {
    122                 smb2_request_destroy(req);
    123                 return status;
    124         }
    125 
    126         return smb2_request_destroy(req);
    127 }
    128 
    129 /*
    130   sync session setup request
    131 */
    132 NTSTATUS smb2_session_setup(struct smb2_session *session,
    133                             TALLOC_CTX *mem_ctx, struct smb2_session_setup *io)
    134 {
    135         struct smb2_request *req = smb2_session_setup_send(session, io);
    136         return smb2_session_setup_recv(req, mem_ctx, io);
    137 }
    138 
    139 
    140 struct smb2_session_state {
    141         struct smb2_session_setup io;
    142         struct smb2_request *req;
     101                talloc_free(session);
     102                return NULL;
     103        }
     104
     105        gensec_want_feature(session->gensec, GENSEC_FEATURE_SESSION_KEY);
     106
     107        return session;
     108}
     109
     110struct smb2_session_setup_spnego_state {
     111        struct tevent_context *ev;
     112        struct smb2_session *session;
     113        struct cli_credentials *credentials;
     114        uint64_t previous_session_id;
     115        bool session_bind;
     116        bool reauth;
    143117        NTSTATUS gensec_status;
     118        DATA_BLOB in_secblob;
     119        DATA_BLOB out_secblob;
    144120};
    145121
    146 /*
    147   handle continuations of the spnego session setup
    148 */
    149 static void session_request_handler(struct smb2_request *req)
    150 {
    151         struct composite_context *c = talloc_get_type(req->async.private_data,
    152                                                       struct composite_context);
    153         struct smb2_session_state *state = talloc_get_type(c->private_data,
    154                                                            struct smb2_session_state);
    155         struct smb2_session *session = req->session;
    156         NTSTATUS session_key_err;
    157         DATA_BLOB session_key;
    158         NTSTATUS peer_status;
    159 
    160         c->status = smb2_session_setup_recv(req, c, &state->io);
    161         peer_status = c->status;
    162 
    163         if (NT_STATUS_EQUAL(peer_status, NT_STATUS_MORE_PROCESSING_REQUIRED) ||
    164             (NT_STATUS_IS_OK(peer_status) &&
    165              NT_STATUS_EQUAL(state->gensec_status, NT_STATUS_MORE_PROCESSING_REQUIRED))) {
    166                 c->status = gensec_update(session->gensec, c,
    167                                           state->io.out.secblob,
    168                                           &state->io.in.secblob);
    169                 state->gensec_status = c->status;
    170 
    171                 session->uid = state->io.out.uid;
    172         }
    173 
    174         if (!NT_STATUS_IS_OK(c->status) &&
    175             !NT_STATUS_EQUAL(c->status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
    176                 composite_error(c, c->status);
    177                 return;
    178         }
    179 
    180         if (NT_STATUS_EQUAL(peer_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
    181                 state->req = smb2_session_setup_send(session, &state->io);
    182                 if (state->req == NULL) {
    183                         composite_error(c, NT_STATUS_NO_MEMORY);
    184                         return;
    185                 }
    186 
    187                 state->req->async.fn = session_request_handler;
    188                 state->req->async.private_data = c;
    189                 return;
    190         }
    191 
    192         session_key_err = gensec_session_key(session->gensec, &session_key);
    193         if (NT_STATUS_IS_OK(session_key_err)) {
    194                 session->session_key = session_key;
    195         }
    196 
    197         if (session->transport->signing_required) {
    198                 if (session->session_key.length == 0) {
    199                         DEBUG(0,("Wrong session key length %u for SMB2 signing\n",
    200                                  (unsigned)session->session_key.length));
    201                         composite_error(c, NT_STATUS_ACCESS_DENIED);
    202                         return;
    203                 }
    204                 session->signing_active = true;
    205         }
    206 
    207         composite_done(c);
    208 }
     122static void smb2_session_setup_spnego_done(struct tevent_req *subreq);
    209123
    210124/*
    211125  a composite function that does a full SPNEGO session setup
    212126 */
    213 struct composite_context *smb2_session_setup_spnego_send(struct smb2_session *session,
    214                                                          struct cli_credentials *credentials)
    215 {
    216         struct composite_context *c;
    217         struct smb2_session_state *state;
     127struct tevent_req *smb2_session_setup_spnego_send(
     128                                TALLOC_CTX *mem_ctx,
     129                                struct tevent_context *ev,
     130                                struct smb2_session *session,
     131                                struct cli_credentials *credentials,
     132                                uint64_t previous_session_id)
     133{
     134        struct tevent_req *req;
     135        struct smb2_session_setup_spnego_state *state;
     136        uint64_t current_session_id;
    218137        const char *chosen_oid;
    219 
    220         c = composite_create(session, session->transport->socket->event.ctx);
    221         if (c == NULL) return NULL;
    222 
    223         state = talloc(c, struct smb2_session_state);
    224         if (composite_nomem(state, c)) return c;
    225         c->private_data = state;
    226 
    227         ZERO_STRUCT(state->io);
    228         state->io.in.vc_number          = 0;
    229         if (session->transport->signing_required) {
    230                 state->io.in.security_mode =
    231                         SMB2_NEGOTIATE_SIGNING_ENABLED | SMB2_NEGOTIATE_SIGNING_REQUIRED;
    232         }
    233         state->io.in.capabilities       = 0;
    234         state->io.in.channel            = 0;
    235         state->io.in.previous_sessionid = 0;
    236 
    237         c->status = gensec_set_credentials(session->gensec, credentials);
    238         if (!composite_is_ok(c)) return c;
    239 
    240         c->status = gensec_set_target_hostname(session->gensec,
    241                                                session->transport->socket->hostname);
    242         if (!composite_is_ok(c)) return c;
    243 
    244         c->status = gensec_set_target_service(session->gensec, "cifs");
    245         if (!composite_is_ok(c)) return c;
    246 
    247         if (session->transport->negotiate.secblob.length > 0) {
     138        struct tevent_req *subreq;
     139        NTSTATUS status;
     140        const DATA_BLOB *server_gss_blob;
     141        DATA_BLOB negprot_secblob = data_blob_null;
     142        uint32_t timeout_msec;
     143        uint8_t in_flags = 0;
     144
     145        timeout_msec = session->transport->options.request_timeout * 1000;
     146
     147        req = tevent_req_create(mem_ctx, &state,
     148                                struct smb2_session_setup_spnego_state);
     149        if (req == NULL) {
     150                return NULL;
     151        }
     152        state->ev = ev;
     153        state->session = session;
     154        state->credentials = credentials;
     155        state->previous_session_id = previous_session_id;
     156
     157        current_session_id = smb2cli_session_current_id(state->session->smbXcli);
     158        if (state->session->needs_bind) {
     159                state->session_bind = true;
     160        } else if (current_session_id != 0) {
     161                state->reauth = true;
     162        }
     163        server_gss_blob = smbXcli_conn_server_gss_blob(session->transport->conn);
     164        if (server_gss_blob) {
     165                negprot_secblob = *server_gss_blob;
     166        }
     167
     168        status = gensec_set_credentials(session->gensec, credentials);
     169        if (tevent_req_nterror(req, status)) {
     170                return tevent_req_post(req, ev);
     171        }
     172
     173        status = gensec_set_target_hostname(session->gensec,
     174                                            smbXcli_conn_remote_name(session->transport->conn));
     175        if (tevent_req_nterror(req, status)) {
     176                return tevent_req_post(req, ev);
     177        }
     178
     179        status = gensec_set_target_service(session->gensec, "cifs");
     180        if (tevent_req_nterror(req, status)) {
     181                return tevent_req_post(req, ev);
     182        }
     183
     184        if (negprot_secblob.length > 0) {
    248185                chosen_oid = GENSEC_OID_SPNEGO;
    249186        } else {
     
    251188        }
    252189
    253         c->status = gensec_start_mech_by_oid(session->gensec, chosen_oid);
    254         if (!composite_is_ok(c)) return c;
    255 
    256         c->status = gensec_update(session->gensec, c,
    257                                   session->transport->negotiate.secblob,
    258                                   &state->io.in.secblob);
    259         if (!NT_STATUS_EQUAL(c->status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
    260                 composite_error(c, c->status);
    261                 return c;
    262         }
    263         state->gensec_status = c->status;
    264                
    265         state->req = smb2_session_setup_send(session, &state->io);
    266         composite_continue_smb2(c, state->req, session_request_handler, c);
    267         return c;
     190        status = gensec_start_mech_by_oid(session->gensec, chosen_oid);
     191        if (tevent_req_nterror(req, status)) {
     192                return tevent_req_post(req, ev);
     193        }
     194
     195        status = gensec_update_ev(session->gensec, state,
     196                               state->ev,
     197                               negprot_secblob,
     198                               &state->in_secblob);
     199        if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
     200                tevent_req_nterror(req, status);
     201                return tevent_req_post(req, ev);
     202        }
     203        state->gensec_status = status;
     204
     205        if (state->session_bind) {
     206                in_flags |= SMB2_SESSION_FLAG_BINDING;
     207        }
     208
     209        subreq = smb2cli_session_setup_send(state, state->ev,
     210                                            session->transport->conn,
     211                                            timeout_msec,
     212                                            session->smbXcli,
     213                                            in_flags,
     214                                            0, /* in_capabilities */
     215                                            0, /* in_channel */
     216                                            state->previous_session_id,
     217                                            &state->in_secblob);
     218        if (tevent_req_nomem(subreq, req)) {
     219                return tevent_req_post(req, ev);
     220        }
     221        tevent_req_set_callback(subreq, smb2_session_setup_spnego_done, req);
     222
     223        return req;
     224}
     225
     226/*
     227  handle continuations of the spnego session setup
     228*/
     229static void smb2_session_setup_spnego_done(struct tevent_req *subreq)
     230{
     231        struct tevent_req *req =
     232                tevent_req_callback_data(subreq,
     233                struct tevent_req);
     234        struct smb2_session_setup_spnego_state *state =
     235                tevent_req_data(req,
     236                struct smb2_session_setup_spnego_state);
     237        struct smb2_session *session = state->session;
     238        NTSTATUS peer_status;
     239        NTSTATUS status;
     240        struct iovec *recv_iov;
     241        uint32_t timeout_msec;
     242        uint8_t in_flags = 0;
     243
     244        timeout_msec = session->transport->options.request_timeout * 1000;
     245
     246        status = smb2cli_session_setup_recv(subreq, state,
     247                                            &recv_iov,
     248                                            &state->out_secblob);
     249        if (!NT_STATUS_IS_OK(status) &&
     250            !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
     251                tevent_req_nterror(req, status);
     252                return;
     253        }
     254        peer_status = status;
     255
     256        if (NT_STATUS_EQUAL(state->gensec_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
     257                status = gensec_update_ev(session->gensec, state,
     258                                       state->ev,
     259                                       state->out_secblob,
     260                                       &state->in_secblob);
     261                state->gensec_status = status;
     262        }
     263
     264        if (!NT_STATUS_IS_OK(status) &&
     265            !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
     266                tevent_req_nterror(req, status);
     267                return;
     268        }
     269
     270        if (NT_STATUS_IS_OK(peer_status) && NT_STATUS_IS_OK(state->gensec_status)) {
     271                DATA_BLOB session_key;
     272
     273                if (state->reauth) {
     274                        tevent_req_done(req);
     275                        return;
     276                }
     277
     278                if (cli_credentials_is_anonymous(state->credentials)) {
     279                        /*
     280                         * Windows server does not set the
     281                         * SMB2_SESSION_FLAG_IS_GUEST nor
     282                         * SMB2_SESSION_FLAG_IS_NULL flag.
     283                         *
     284                         * This fix makes sure we do not try
     285                         * to verify a signature on the final
     286                         * session setup response.
     287                         */
     288                        tevent_req_done(req);
     289                        return;
     290                }
     291
     292                status = gensec_session_key(session->gensec, state,
     293                                            &session_key);
     294                if (tevent_req_nterror(req, status)) {
     295                        return;
     296                }
     297
     298                if (state->session_bind) {
     299                        status = smb2cli_session_set_channel_key(session->smbXcli,
     300                                                                 session_key,
     301                                                                 recv_iov);
     302                        if (tevent_req_nterror(req, status)) {
     303                                return;
     304                        }
     305                        session->needs_bind = false;
     306                } else {
     307                        status = smb2cli_session_set_session_key(session->smbXcli,
     308                                                                 session_key,
     309                                                                 recv_iov);
     310                        if (tevent_req_nterror(req, status)) {
     311                                return;
     312                        }
     313                }
     314                tevent_req_done(req);
     315                return;
     316        }
     317
     318        if (state->session_bind) {
     319                in_flags |= SMB2_SESSION_FLAG_BINDING;
     320        }
     321
     322        subreq = smb2cli_session_setup_send(state, state->ev,
     323                                            session->transport->conn,
     324                                            timeout_msec,
     325                                            session->smbXcli,
     326                                            in_flags,
     327                                            0, /* in_capabilities */
     328                                            0, /* in_channel */
     329                                            state->previous_session_id,
     330                                            &state->in_secblob);
     331        if (tevent_req_nomem(subreq, req)) {
     332                return;
     333        }
     334        tevent_req_set_callback(subreq, smb2_session_setup_spnego_done, req);
    268335}
    269336
     
    271338  receive a composite session setup reply
    272339*/
    273 NTSTATUS smb2_session_setup_spnego_recv(struct composite_context *c)
    274 {
    275         NTSTATUS status;
    276         status = composite_wait(c);
    277         talloc_free(c);
    278         return status;
     340NTSTATUS smb2_session_setup_spnego_recv(struct tevent_req *req)
     341{
     342        return tevent_req_simple_recv_ntstatus(req);
    279343}
    280344
     
    283347*/
    284348NTSTATUS smb2_session_setup_spnego(struct smb2_session *session,
    285                                    struct cli_credentials *credentials)
    286 {
    287         struct composite_context *c = smb2_session_setup_spnego_send(session, credentials);
    288         return smb2_session_setup_spnego_recv(c);
    289 }
     349                                   struct cli_credentials *credentials,
     350                                   uint64_t previous_session_id)
     351{
     352        struct tevent_req *subreq;
     353        NTSTATUS status;
     354        bool ok;
     355        TALLOC_CTX *frame = talloc_stackframe();
     356        struct tevent_context *ev = session->transport->ev;
     357
     358        if (frame == NULL) {
     359                return NT_STATUS_NO_MEMORY;
     360        }
     361
     362        subreq = smb2_session_setup_spnego_send(frame, ev,
     363                                                session, credentials,
     364                                                previous_session_id);
     365        if (subreq == NULL) {
     366                TALLOC_FREE(frame);
     367                return NT_STATUS_NO_MEMORY;
     368        }
     369
     370        ok = tevent_req_poll(subreq, ev);
     371        if (!ok) {
     372                status = map_nt_error_from_unix_common(errno);
     373                TALLOC_FREE(frame);
     374                return status;
     375        }
     376
     377        status = smb2_session_setup_spnego_recv(subreq);
     378        TALLOC_FREE(subreq);
     379        if (!NT_STATUS_IS_OK(status)) {
     380                TALLOC_FREE(frame);
     381                return status;
     382        }
     383
     384        TALLOC_FREE(frame);
     385        return NT_STATUS_OK;
     386}
  • vendor/current/source4/libcli/smb2/smb2.h

    r740 r988  
    2828struct smb2_handle;
    2929struct smb2_lease_break;
    30 
    31 /*
    32   information returned from the negotiate process
    33 */
    34 struct smb2_negotiate {
    35         DATA_BLOB secblob;
    36         NTTIME system_time;
    37         NTTIME server_start_time;
    38         uint16_t security_mode;
    39         uint16_t dialect_revision;
    40 };
    4130
    4231struct smb2_request_buffer {
     
    7160/* this is the context for the smb2 transport layer */
    7261struct smb2_transport {
    73         /* socket level info */
    74         struct smbcli_socket *socket;
    75 
    76         struct smb2_negotiate negotiate;
    77 
    78         /* next seqnum to allocate */
    79         uint64_t seqnum;
     62        struct tevent_context *ev; /* TODO: remove this !!! */
     63        struct smbXcli_conn *conn;
    8064
    8165        /* the details for coumpounded requests */
    8266        struct {
    83                 uint32_t missing;
    8467                bool related;
    85                 struct smb2_request_buffer buffer;
     68                struct tevent_req **reqs;
    8669        } compound;
    87 
    88         struct {
    89                 uint16_t charge;
    90                 uint16_t ask_num;
    91         } credits;
    92 
    93         /* a list of requests that are pending for receive on this
    94            connection */
    95         struct smb2_request *pending_recv;
    96 
    97         /* context of the stream -> packet parser */
    98         struct packet_context *packet;
    9970
    10071        /* an idle function - if this is defined then it will be
     
    10576                void *private_data;
    10677                unsigned int period;
     78                struct tevent_timer *te;
    10779        } idle;
    10880
     
    12496                void *private_data;
    12597        } lease;
     98        struct tevent_req *break_subreq;
    12699
    127100        struct smbcli_options options;
    128 
    129         bool signing_required;
    130101};
    131102
     
    136107struct smb2_tree {
    137108        struct smb2_session *session;
    138         uint32_t tid;
     109        struct smbXcli_tcon *smbXcli;
    139110};
    140111
     
    145116        struct smb2_transport *transport;
    146117        struct gensec_security *gensec;
    147         uint64_t uid;
    148         uint32_t pid;
    149         DATA_BLOB session_key;
    150         bool signing_active;
     118        struct smbXcli_session *smbXcli;
     119        bool needs_bind;
    151120};
    152121
     
    163132/* the context for a single SMB2 request */
    164133struct smb2_request {
    165         /* allow a request to be part of a list of requests */
    166         struct smb2_request *next, *prev;
    167 
    168134        /* each request is in one of 3 possible states */
    169135        enum smb2_request_state state;
     136
     137        struct tevent_req *subreq;
    170138
    171139        struct smb2_transport *transport;
     
    173141        struct smb2_tree      *tree;
    174142
    175         uint64_t seqnum;
    176 
    177143        struct {
    178                 bool do_cancel;
    179144                bool can_cancel;
    180                 uint64_t async_id;
    181145        } cancel;
    182146
     
    187151        struct smb2_request_buffer in;
    188152        struct smb2_request_buffer out;
     153        struct iovec *recv_iov;
     154
     155        uint16_t credit_charge;
    189156
    190157        /* information on what to do with a reply when it is received
  • vendor/current/source4/libcli/smb2/tcon.c

    r414 r988  
    2323#include "libcli/smb2/smb2.h"
    2424#include "libcli/smb2/smb2_calls.h"
     25#include "../libcli/smb/smbXcli_base.h"
    2526
    2627/*
     
    4142                tree->session = talloc_reference(tree, session);
    4243        }
    43         return tree;
    44 }
    4544
    46 /*
    47   send a tree connect
    48 */
    49 struct smb2_request *smb2_tree_connect_send(struct smb2_tree *tree,
    50                                             struct smb2_tree_connect *io)
    51 {
    52         struct smb2_request *req;
    53         NTSTATUS status;
    54 
    55         req = smb2_request_init(tree->session->transport, SMB2_OP_TCON,
    56                                 0x08, true, 0);
    57         if (req == NULL) return NULL;
    58 
    59         SBVAL(req->out.hdr,  SMB2_HDR_SESSION_ID, tree->session->uid);
    60         req->session = tree->session;
    61 
    62         SSVAL(req->out.body, 0x02, io->in.reserved);
    63         status = smb2_push_o16s16_string(&req->out, 0x04, io->in.path);
    64         if (!NT_STATUS_IS_OK(status)) {
    65                 talloc_free(req);
     45        tree->smbXcli = smbXcli_tcon_create(tree);
     46        if (tree->smbXcli == NULL) {
     47                talloc_free(tree);
    6648                return NULL;
    6749        }
    6850
    69         smb2_transport_send(req);
    70 
    71         return req;
     51        return tree;
    7252}
    73 
    74 
    75 /*
    76   recv a tree connect reply
    77 */
    78 NTSTATUS smb2_tree_connect_recv(struct smb2_request *req, struct smb2_tree_connect *io)
    79 {
    80         if (!smb2_request_receive(req) ||
    81             smb2_request_is_error(req)) {
    82                 return smb2_request_destroy(req);
    83         }
    84 
    85         SMB2_CHECK_PACKET_RECV(req, 0x10, false);
    86 
    87         io->out.tid      = IVAL(req->in.hdr,  SMB2_HDR_TID);
    88 
    89         io->out.share_type  = CVAL(req->in.body, 0x02);
    90         io->out.reserved    = CVAL(req->in.body, 0x03);
    91         io->out.flags       = IVAL(req->in.body, 0x04);
    92         io->out.capabilities= IVAL(req->in.body, 0x08);
    93         io->out.access_mask = IVAL(req->in.body, 0x0C);
    94 
    95         if (io->out.capabilities & ~SMB2_CAP_ALL) {
    96                 DEBUG(0,("Unknown capabilities mask 0x%x\n", io->out.capabilities));
    97         }
    98         if (io->out.flags & ~SMB2_SHAREFLAG_ALL) {
    99                 DEBUG(0,("Unknown tcon shareflag 0x%x\n", io->out.flags));
    100         }
    101        
    102         return smb2_request_destroy(req);
    103 }
    104 
    105 /*
    106   sync tree connect request
    107 */
    108 NTSTATUS smb2_tree_connect(struct smb2_tree *tree, struct smb2_tree_connect *io)
    109 {
    110         struct smb2_request *req = smb2_tree_connect_send(tree, io);
    111         return smb2_tree_connect_recv(req, io);
    112 }
  • vendor/current/source4/libcli/smb2/transport.c

    r740 r988  
    2121
    2222#include "includes.h"
     23#include "system/network.h"
    2324#include "libcli/raw/libcliraw.h"
    2425#include "libcli/raw/raw_proto.h"
     
    2728#include "lib/socket/socket.h"
    2829#include "lib/events/events.h"
    29 #include "lib/stream/packet.h"
    3030#include "../lib/util/dlinklist.h"
    31 
    32 
    33 /*
    34   an event has happened on the socket
    35 */
    36 static void smb2_transport_event_handler(struct tevent_context *ev,
    37                                          struct tevent_fd *fde,
    38                                          uint16_t flags, void *private_data)
    39 {
    40         struct smb2_transport *transport = talloc_get_type(private_data,
    41                                                            struct smb2_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 }
     31#include "../libcli/smb/smbXcli_base.h"
     32#include "librpc/ndr/libndr.h"
    5033
    5134/*
     
    5740        return 0;
    5841}
    59 
    60 
    61 /*
    62   handle receive errors
    63 */
    64 static void smb2_transport_error(void *private_data, NTSTATUS status)
    65 {
    66         struct smb2_transport *transport = talloc_get_type(private_data,
    67                                                            struct smb2_transport);
    68         smb2_transport_dead(transport, status);
    69 }
    70 
    71 static NTSTATUS smb2_transport_finish_recv(void *private_data, DATA_BLOB blob);
    7242
    7343/*
     
    8353        if (!transport) return NULL;
    8454
    85         transport->socket = talloc_steal(transport, sock);
     55        transport->ev = sock->event.ctx;
    8656        transport->options = *options;
    87         transport->credits.charge = 0;
    88         transport->credits.ask_num = 1;
    89 
    90         /* setup the stream -> packet parser */
    91         transport->packet = packet_init(transport);
    92         if (transport->packet == NULL) {
     57
     58        if (transport->options.max_protocol == PROTOCOL_DEFAULT) {
     59                transport->options.max_protocol = PROTOCOL_LATEST;
     60        }
     61
     62        if (transport->options.max_protocol < PROTOCOL_SMB2_02) {
     63                transport->options.max_protocol = PROTOCOL_LATEST;
     64        }
     65
     66        TALLOC_FREE(sock->event.fde);
     67        TALLOC_FREE(sock->event.te);
     68
     69        transport->conn = smbXcli_conn_create(transport,
     70                                              sock->sock->fd,
     71                                              sock->hostname,
     72                                              options->signing,
     73                                              0, /* smb1_capabilities */
     74                                              &options->client_guid,
     75                                              options->smb2_capabilities);
     76        if (transport->conn == NULL) {
    9377                talloc_free(transport);
    9478                return NULL;
    9579        }
    96         packet_set_private(transport->packet, transport);
    97         packet_set_socket(transport->packet, transport->socket->sock);
    98         packet_set_callback(transport->packet, smb2_transport_finish_recv);
    99         packet_set_full_request(transport->packet, packet_full_request_nbt);
    100         packet_set_error_handler(transport->packet, smb2_transport_error);
    101         packet_set_event_context(transport->packet, transport->socket->event.ctx);
    102         packet_set_nofree(transport->packet);
    103 
    104         /* take over event handling from the socket layer - it only
    105            handles events up until we are connected */
    106         talloc_free(transport->socket->event.fde);
    107         transport->socket->event.fde = event_add_fd(transport->socket->event.ctx,
    108                                                     transport->socket,
    109                                                     socket_get_fd(transport->socket->sock),
    110                                                     EVENT_FD_READ,
    111                                                     smb2_transport_event_handler,
    112                                                     transport);
    113 
    114         packet_set_fde(transport->packet, transport->socket->event.fde);
    115         packet_set_serialise(transport->packet);
     80        sock->sock->fd = -1;
     81        TALLOC_FREE(sock);
    11682
    11783        talloc_set_destructor(transport, transport_destructor);
     
    12591void smb2_transport_dead(struct smb2_transport *transport, NTSTATUS status)
    12692{
    127         smbcli_sock_dead(transport->socket);
    128 
    12993        if (NT_STATUS_EQUAL(NT_STATUS_UNSUCCESSFUL, status)) {
    13094                status = NT_STATUS_UNEXPECTED_NETWORK_ERROR;
    13195        }
    132 
    133         /* kill all pending receives */
    134         while (transport->pending_recv) {
    135                 struct smb2_request *req = transport->pending_recv;
     96        if (NT_STATUS_IS_OK(status)) {
     97                status = NT_STATUS_LOCAL_DISCONNECT;
     98        }
     99
     100        smbXcli_conn_disconnect(transport->conn, status);
     101}
     102
     103static void smb2_request_done(struct tevent_req *subreq);
     104static void smb2_transport_break_handler(struct tevent_req *subreq);
     105
     106/*
     107  put a request into the send queue
     108*/
     109void smb2_transport_send(struct smb2_request *req)
     110{
     111        NTSTATUS status;
     112        struct smb2_transport *transport = req->transport;
     113        struct tevent_req **reqs = transport->compound.reqs;
     114        size_t num_reqs = talloc_array_length(reqs);
     115        size_t i;
     116        uint16_t cmd = SVAL(req->out.hdr, SMB2_HDR_OPCODE);
     117        uint32_t additional_flags = IVAL(req->out.hdr, SMB2_HDR_FLAGS);
     118        uint32_t clear_flags = 0;
     119        struct smbXcli_tcon *tcon = NULL;
     120        struct smbXcli_session *session = NULL;
     121        bool need_pending_break = false;
     122        size_t hdr_ofs;
     123        size_t pdu_len;
     124        DATA_BLOB body = data_blob_null;
     125        DATA_BLOB dyn = data_blob_null;
     126        uint32_t timeout_msec = transport->options.request_timeout * 1000;
     127
     128        if (transport->oplock.handler) {
     129                need_pending_break = true;
     130        }
     131
     132        if (transport->lease.handler) {
     133                need_pending_break = true;
     134        }
     135
     136        if (transport->break_subreq) {
     137                need_pending_break = false;
     138        }
     139
     140        if (need_pending_break) {
     141                struct tevent_req *subreq;
     142
     143                subreq = smb2cli_req_create(transport,
     144                                            transport->ev,
     145                                            transport->conn,
     146                                            SMB2_OP_BREAK,
     147                                            0, /* additional_flags */
     148                                            0, /*clear_flags */
     149                                            0, /* timeout_msec */
     150                                            NULL, /* tcon */
     151                                            NULL, /* session */
     152                                            NULL, /* body */
     153                                            0, /* body_fixed */
     154                                            NULL, /* dyn */
     155                                            0, /* dyn_len */
     156                                            0); /* max_dyn_len */
     157                if (subreq != NULL) {
     158                        smbXcli_req_set_pending(subreq);
     159                        tevent_req_set_callback(subreq,
     160                                                smb2_transport_break_handler,
     161                                                transport);
     162                        transport->break_subreq = subreq;
     163                }
     164        }
     165
     166        if (req->session) {
     167                session = req->session->smbXcli;
     168        }
     169
     170        if (req->tree) {
     171                tcon = req->tree->smbXcli;
     172        }
     173
     174        if (transport->compound.related) {
     175                additional_flags |= SMB2_HDR_FLAG_CHAINED;
     176        }
     177
     178        hdr_ofs = PTR_DIFF(req->out.hdr, req->out.buffer);
     179        pdu_len = req->out.size - hdr_ofs;
     180        body.data = req->out.body;
     181        body.length = req->out.body_fixed;
     182        dyn.data = req->out.body + req->out.body_fixed;
     183        dyn.length = pdu_len - (SMB2_HDR_BODY + req->out.body_fixed);
     184
     185        req->subreq = smb2cli_req_create(req,
     186                                         transport->ev,
     187                                         transport->conn,
     188                                         cmd,
     189                                         additional_flags,
     190                                         clear_flags,
     191                                         timeout_msec,
     192                                         tcon,
     193                                         session,
     194                                         body.data, body.length,
     195                                         dyn.data, dyn.length,
     196                                         0); /* max_dyn_len */
     197        if (req->subreq == NULL) {
    136198                req->state = SMB2_REQUEST_ERROR;
     199                req->status = NT_STATUS_NO_MEMORY;
     200                return;
     201        }
     202
     203        if (!tevent_req_is_in_progress(req->subreq)) {
     204                req->state = SMB2_REQUEST_ERROR;
     205                req->status = NT_STATUS_INTERNAL_ERROR;/* TODO */
     206                return;
     207        }
     208
     209        tevent_req_set_callback(req->subreq, smb2_request_done, req);
     210
     211        smb2cli_req_set_notify_async(req->subreq);
     212        if (req->credit_charge) {
     213                smb2cli_req_set_credit_charge(req->subreq, req->credit_charge);
     214        }
     215
     216        ZERO_STRUCT(req->out);
     217        req->state = SMB2_REQUEST_RECV;
     218
     219        if (num_reqs > 0) {
     220                for (i=0; i < num_reqs; i++) {
     221                        if (reqs[i] != NULL) {
     222                                continue;
     223                        }
     224
     225                        reqs[i] = req->subreq;
     226                        i++;
     227                        break;
     228                }
     229
     230                if (i < num_reqs) {
     231                        return;
     232                }
     233        } else {
     234                reqs = &req->subreq;
     235                num_reqs = 1;
     236        }
     237        status = smb2cli_req_compound_submit(reqs, num_reqs);
     238
     239        TALLOC_FREE(transport->compound.reqs);
     240        transport->compound.related = false;
     241
     242        if (!NT_STATUS_IS_OK(status)) {
    137243                req->status = status;
    138                 DLIST_REMOVE(transport->pending_recv, req);
    139                 if (req->async.fn) {
    140                         req->async.fn(req);
    141                 }
    142         }
    143 }
    144 
    145 static NTSTATUS smb2_handle_oplock_break(struct smb2_transport *transport,
    146                                          const DATA_BLOB *blob)
    147 {
    148         uint8_t *hdr;
     244                req->state = SMB2_REQUEST_ERROR;
     245                smbXcli_conn_disconnect(transport->conn, status);
     246        }
     247}
     248
     249static void smb2_request_done(struct tevent_req *subreq)
     250{
     251        struct smb2_request *req =
     252                tevent_req_callback_data(subreq,
     253                struct smb2_request);
     254        ssize_t len;
     255        size_t i;
     256
     257        req->recv_iov = NULL;
     258
     259        req->status = smb2cli_req_recv(req->subreq, req, &req->recv_iov, NULL, 0);
     260        if (NT_STATUS_EQUAL(req->status, STATUS_PENDING)) {
     261                req->cancel.can_cancel = true;
     262                return;
     263        }
     264        TALLOC_FREE(req->subreq);
     265        if (!NT_STATUS_IS_OK(req->status)) {
     266                if (req->recv_iov == NULL) {
     267                        req->state = SMB2_REQUEST_ERROR;
     268                        if (req->async.fn) {
     269                                req->async.fn(req);
     270                        }
     271                        return;
     272                }
     273        }
     274
     275        len = req->recv_iov[0].iov_len;
     276        for (i=1; i < 3; i++) {
     277                uint8_t *p = req->recv_iov[i-1].iov_base;
     278                uint8_t *c1 = req->recv_iov[i].iov_base;
     279                uint8_t *c2 = p + req->recv_iov[i-1].iov_len;
     280
     281                len += req->recv_iov[i].iov_len;
     282
     283                if (req->recv_iov[i].iov_len == 0) {
     284                        continue;
     285                }
     286
     287                if (c1 != c2) {
     288                        req->status = NT_STATUS_INTERNAL_ERROR;
     289                        req->state = SMB2_REQUEST_ERROR;
     290                        if (req->async.fn) {
     291                                req->async.fn(req);
     292                        }
     293                        return;
     294                }
     295        }
     296
     297        req->in.buffer = req->recv_iov[0].iov_base;
     298        req->in.size = len;
     299        req->in.allocated = req->in.size;
     300
     301        req->in.hdr        =  req->recv_iov[0].iov_base;
     302        req->in.body       =  req->recv_iov[1].iov_base;
     303        req->in.dynamic    =  req->recv_iov[2].iov_base;
     304        req->in.body_fixed =  req->recv_iov[1].iov_len;
     305        req->in.body_size  =  req->in.body_fixed;
     306        req->in.body_size  += req->recv_iov[2].iov_len;
     307
     308        smb2_setup_bufinfo(req);
     309
     310        req->state = SMB2_REQUEST_DONE;
     311        if (req->async.fn) {
     312                req->async.fn(req);
     313        }
     314}
     315
     316static void smb2_transport_break_handler(struct tevent_req *subreq)
     317{
     318        struct smb2_transport *transport =
     319                tevent_req_callback_data(subreq,
     320                struct smb2_transport);
     321        NTSTATUS status;
    149322        uint8_t *body;
    150         uint16_t len, bloblen;
     323        uint16_t len = 0;
    151324        bool lease;
    152 
    153         hdr = blob->data+NBT_HDR_SIZE;
    154         body = hdr+SMB2_HDR_BODY;
    155         bloblen = blob->length - SMB2_HDR_BODY;
    156 
    157         if (bloblen < 2) {
    158                 DEBUG(1,("Discarding smb2 oplock reply of size %u\n",
    159                         (unsigned)blob->length));
    160                 return NT_STATUS_INVALID_NETWORK_RESPONSE;
    161         }
    162 
    163         len = CVAL(body, 0x00);
    164         if (len > bloblen) {
    165                 DEBUG(1,("Discarding smb2 oplock reply,"
    166                         "packet claims %u byte body, only %u bytes seen\n",
    167                         len, bloblen));
    168                 return NT_STATUS_INVALID_NETWORK_RESPONSE;
     325        struct iovec *recv_iov = NULL;
     326
     327        transport->break_subreq = NULL;
     328
     329        status = smb2cli_req_recv(subreq, transport, &recv_iov, NULL, 0);
     330        TALLOC_FREE(subreq);
     331        if (!NT_STATUS_IS_OK(status)) {
     332                TALLOC_FREE(recv_iov);
     333                smb2_transport_dead(transport, status);
     334                return;
     335        }
     336
     337        /*
     338         * Setup the subreq to handle the
     339         * next incoming SMB2 Break.
     340         */
     341        subreq = smb2cli_req_create(transport,
     342                                    transport->ev,
     343                                    transport->conn,
     344                                    SMB2_OP_BREAK,
     345                                    0, /* additional_flags */
     346                                    0, /*clear_flags */
     347                                    0, /* timeout_msec */
     348                                    NULL, /* tcon */
     349                                    NULL, /* session */
     350                                    NULL, /* body */
     351                                    0, /* body_fixed */
     352                                    NULL, /* dyn */
     353                                    0, /* dyn_len */
     354                                    0); /* max_dyn_len */
     355        if (subreq != NULL) {
     356                smbXcli_req_set_pending(subreq);
     357                tevent_req_set_callback(subreq,
     358                                        smb2_transport_break_handler,
     359                                        transport);
     360                transport->break_subreq = subreq;
     361        }
     362
     363        body = recv_iov[1].iov_base;
     364
     365        len = recv_iov[1].iov_len;
     366        if (recv_iov[1].iov_len >= 2) {
     367                len = CVAL(body, 0x00);
     368                if (len != recv_iov[1].iov_len) {
     369                        len = recv_iov[1].iov_len;
     370                }
    169371        }
    170372
     
    175377        } else {
    176378                DEBUG(1,("Discarding smb2 oplock reply of invalid size %u\n",
    177                         (unsigned)blob->length));
    178                 return NT_STATUS_INVALID_NETWORK_RESPONSE;
     379                        (unsigned)len));
     380                TALLOC_FREE(recv_iov);
     381                status = NT_STATUS_INVALID_NETWORK_RESPONSE;
     382                smb2_transport_dead(transport, status);
     383                return;
    179384        }
    180385
     
    185390                level = CVAL(body, 0x02);
    186391                smb2_pull_handle(body+0x08, &h);
     392
     393                TALLOC_FREE(recv_iov);
    187394
    188395                transport->oplock.handler(transport, &h, level,
     
    192399
    193400                ZERO_STRUCT(lb);
     401                lb.new_epoch =                  SVAL(body, 0x2);
    194402                lb.break_flags =                SVAL(body, 0x4);
    195403                memcpy(&lb.current_lease.lease_key, body+0x8,
     
    201409                lb.share_mask_hint =            SVAL(body, 0x28);
    202410
     411                TALLOC_FREE(recv_iov);
     412
    203413                transport->lease.handler(transport, &lb,
    204414                    transport->lease.private_data);
     
    207417                        lease ? "lease" : "oplock"));
    208418        }
    209 
    210         return NT_STATUS_OK;
    211 }
    212 
    213 struct smb2_transport_compount_response_state {
    214         struct smb2_transport *transport;
    215         DATA_BLOB blob;
    216 };
    217 
    218 static void smb2_transport_compound_response_handler(struct tevent_context *ctx,
    219                                                      struct tevent_immediate *im,
    220                                                      void *private_data)
    221 {
    222         struct smb2_transport_compount_response_state *state =
    223                 talloc_get_type_abort(private_data,
    224                 struct smb2_transport_compount_response_state);
    225         struct smb2_transport *transport = state->transport;
    226         NTSTATUS status;
    227 
    228         status = smb2_transport_finish_recv(transport, state->blob);
    229         TALLOC_FREE(state);
    230         if (!NT_STATUS_IS_OK(status)) {
    231                 smb2_transport_error(transport, status);
    232         }
    233 }
    234 
    235 /*
    236   we have a full request in our receive buffer - match it to a pending request
    237   and process
    238  */
    239 static NTSTATUS smb2_transport_finish_recv(void *private_data, DATA_BLOB blob)
    240 {
    241         struct smb2_transport *transport = talloc_get_type(private_data,
    242                                                              struct smb2_transport);
    243         uint8_t *buffer, *hdr;
    244         int len;
    245         struct smb2_request *req = NULL;
    246         uint64_t seqnum;
    247         uint32_t flags;
    248         uint16_t buffer_code;
    249         uint32_t dynamic_size;
    250         uint32_t i;
    251         uint16_t opcode;
    252         NTSTATUS status;
    253         uint32_t next_ofs;
    254 
    255         buffer = blob.data;
    256         len = blob.length;
    257 
    258         hdr = buffer+NBT_HDR_SIZE;
    259 
    260         if (len < SMB2_MIN_SIZE) {
    261                 DEBUG(1,("Discarding smb2 reply of size %d\n", len));
    262                 goto error;
    263         }
    264 
    265         flags   = IVAL(hdr, SMB2_HDR_FLAGS);
    266         seqnum  = BVAL(hdr, SMB2_HDR_MESSAGE_ID);
    267         opcode  = SVAL(hdr, SMB2_HDR_OPCODE);
    268 
    269         /* see MS-SMB2 3.2.5.19 */
    270         if (seqnum == UINT64_MAX) {
    271                 if (opcode != SMB2_OP_BREAK) {
    272                         DEBUG(1,("Discarding packet with invalid seqnum, "
    273                                 "opcode %u\n", opcode));
    274                         return NT_STATUS_INVALID_NETWORK_RESPONSE;
    275                 }
    276 
    277                 return smb2_handle_oplock_break(transport, &blob);
    278         }
    279 
    280         /* match the incoming request against the list of pending requests */
    281         for (req=transport->pending_recv; req; req=req->next) {
    282                 if (req->seqnum == seqnum) break;
    283         }
    284 
    285         if (!req) {
    286                 DEBUG(1,("Discarding unmatched reply with seqnum 0x%llx op %d\n",
    287                          (long long)seqnum, SVAL(hdr, SMB2_HDR_OPCODE)));
    288                 goto error;
    289         }
    290 
    291         /* fill in the 'in' portion of the matching request */
    292         req->in.buffer = buffer;
    293         talloc_steal(req, buffer);
    294         req->in.size = len;
    295         req->in.allocated = req->in.size;
    296 
    297         req->in.hdr       = hdr;
    298         req->in.body      = hdr+SMB2_HDR_BODY;
    299         req->in.body_size = req->in.size - (SMB2_HDR_BODY+NBT_HDR_SIZE);
    300         req->status       = NT_STATUS(IVAL(hdr, SMB2_HDR_STATUS));
    301 
    302         if ((flags & SMB2_HDR_FLAG_ASYNC) &&
    303             NT_STATUS_EQUAL(req->status, STATUS_PENDING)) {
    304                 req->cancel.can_cancel = true;
    305                 req->cancel.async_id = BVAL(hdr, SMB2_HDR_ASYNC_ID);
    306                 for (i=0; i< req->cancel.do_cancel; i++) {
    307                         smb2_cancel(req);
    308                 }
    309                 talloc_free(buffer);
    310                 return NT_STATUS_OK;
    311         }
    312 
    313         next_ofs = IVAL(req->in.hdr, SMB2_HDR_NEXT_COMMAND);
    314         if (next_ofs > 0) {
    315                 if (smb2_oob(&req->in, req->in.hdr + next_ofs, SMB2_HDR_BODY + 2)) {
    316                         DEBUG(1,("SMB2 request invalid next offset 0x%x\n",
    317                                  next_ofs));
    318                         goto error;
    319                 }
    320 
    321                 req->in.size = NBT_HDR_SIZE + next_ofs;
    322                 req->in.body_size = req->in.size - (SMB2_HDR_BODY+NBT_HDR_SIZE);
    323         }
    324 
    325         if (req->session && req->session->signing_active) {
    326                 status = smb2_check_signature(&req->in,
    327                                               req->session->session_key);
    328                 if (!NT_STATUS_IS_OK(status)) {
    329                         /* the spec says to ignore packets with a bad signature */
    330                         talloc_free(buffer);
    331                         return status;
    332                 }
    333         }
    334 
    335         buffer_code = SVAL(req->in.body, 0);
    336         req->in.body_fixed = (buffer_code & ~1);
    337         req->in.dynamic = NULL;
    338         dynamic_size = req->in.body_size - req->in.body_fixed;
    339         if (dynamic_size != 0 && (buffer_code & 1)) {
    340                 req->in.dynamic = req->in.body + req->in.body_fixed;
    341                 if (smb2_oob(&req->in, req->in.dynamic, dynamic_size)) {
    342                         DEBUG(1,("SMB2 request invalid dynamic size 0x%x\n",
    343                                  dynamic_size));
    344                         goto error;
    345                 }
    346         }
    347 
    348         smb2_setup_bufinfo(req);
    349 
    350         DEBUG(2, ("SMB2 RECV seqnum=0x%llx\n", (long long)req->seqnum));
    351         dump_data(5, req->in.body, req->in.body_size);
    352 
    353         if (next_ofs > 0) {
    354                 struct tevent_immediate *im;
    355                 struct smb2_transport_compount_response_state *state;
    356 
    357                 state = talloc(transport,
    358                                struct smb2_transport_compount_response_state);
    359                 if (!state) {
    360                         goto error;
    361                 }
    362                 state->transport = transport;
    363 
    364                 state->blob = data_blob_talloc(state, NULL,
    365                                                blob.length - next_ofs);
    366                 if (!state->blob.data) {
    367                         goto error;
    368                 }
    369                 im = tevent_create_immediate(state);
    370                 if (!im) {
    371                         TALLOC_FREE(state);
    372                         goto error;
    373                 }
    374                 _smb2_setlen(state->blob.data, state->blob.length - NBT_HDR_SIZE);
    375                 memcpy(state->blob.data + NBT_HDR_SIZE,
    376                        req->in.hdr + next_ofs,
    377                        req->in.allocated - req->in.size);
    378                 tevent_schedule_immediate(im, transport->socket->event.ctx,
    379                                           smb2_transport_compound_response_handler,
    380                                           state);
    381         }
    382 
    383         /* if this request has an async handler then call that to
    384            notify that the reply has been received. This might destroy
    385            the request so it must happen last */
    386         DLIST_REMOVE(transport->pending_recv, req);
    387         req->state = SMB2_REQUEST_DONE;
    388         if (req->async.fn) {
    389                 req->async.fn(req);
    390         }
    391         return NT_STATUS_OK;
    392 
    393 error:
    394         dump_data(5, buffer, len);
    395         if (req) {
    396                 DLIST_REMOVE(transport->pending_recv, req);
    397                 req->state = SMB2_REQUEST_ERROR;
    398                 if (req->async.fn) {
    399                         req->async.fn(req);
    400                 }
    401         } else {
    402                 talloc_free(buffer);
    403         }
    404         return NT_STATUS_UNSUCCESSFUL;
    405 }
    406 
    407 /*
    408   handle timeouts of individual smb requests
    409 */
    410 static void smb2_timeout_handler(struct tevent_context *ev, struct tevent_timer *te,
    411                                  struct timeval t, void *private_data)
    412 {
    413         struct smb2_request *req = talloc_get_type(private_data, struct smb2_request);
    414 
    415         if (req->state == SMB2_REQUEST_RECV) {
    416                 DLIST_REMOVE(req->transport->pending_recv, req);
    417         }
    418         req->status = NT_STATUS_IO_TIMEOUT;
    419         req->state = SMB2_REQUEST_ERROR;
    420         if (req->async.fn) {
    421                 req->async.fn(req);
    422         }
    423 }
    424 
    425 
    426 /*
    427   destroy a request
    428 */
    429 static int smb2_request_destructor(struct smb2_request *req)
    430 {
    431         if (req->state == SMB2_REQUEST_RECV) {
    432                 DLIST_REMOVE(req->transport->pending_recv, req);
    433         }
    434         return 0;
    435 }
    436 
    437 static NTSTATUS smb2_transport_raw_send(struct smb2_transport *transport,
    438                                         struct smb2_request_buffer *buffer)
    439 {
    440         DATA_BLOB blob;
    441         NTSTATUS status;
    442 
    443         /* check if the transport is dead */
    444         if (transport->socket->sock == NULL) {
    445                 return NT_STATUS_NET_WRITE_FAULT;
    446         }
    447 
    448         _smb2_setlen(buffer->buffer, buffer->size - NBT_HDR_SIZE);
    449         blob = data_blob_const(buffer->buffer, buffer->size);
    450         status = packet_send(transport->packet, blob);
    451         if (!NT_STATUS_IS_OK(status)) {
    452                 return status;
    453         }
    454 
    455         return NT_STATUS_OK;
    456 }
    457 
    458 /*
    459   put a request into the send queue
    460 */
    461 void smb2_transport_send(struct smb2_request *req)
    462 {
    463         NTSTATUS status;
    464 
    465         DEBUG(2, ("SMB2 send seqnum=0x%llx\n", (long long)req->seqnum));
    466         dump_data(5, req->out.body, req->out.body_size);
    467 
    468         if (req->transport->compound.missing > 0) {
    469                 off_t next_ofs;
    470                 size_t pad = 0;
    471                 uint8_t *end;
    472 
    473                 end = req->out.buffer + req->out.size;
    474 
    475                 /*
    476                  * we need to set dynamic otherwise
    477                  * smb2_grow_buffer segfaults
    478                  */
    479                 if (req->out.dynamic == NULL) {
    480                         req->out.dynamic = end;
    481                 }
    482 
    483                 next_ofs = end - req->out.hdr;
    484                 if ((next_ofs % 8) > 0) {
    485                         pad = 8 - (next_ofs % 8);
    486                 }
    487                 next_ofs += pad;
    488 
    489                 status = smb2_grow_buffer(&req->out, pad);
    490                 if (!NT_STATUS_IS_OK(status)) {
    491                         req->state = SMB2_REQUEST_ERROR;
    492                         req->status = status;
    493                         return;
    494                 }
    495                 req->out.size += pad;
    496 
    497                 SIVAL(req->out.hdr, SMB2_HDR_NEXT_COMMAND, next_ofs);
    498         }
    499 
    500         /* possibly sign the message */
    501         if (req->session && req->session->signing_active) {
    502                 status = smb2_sign_message(&req->out, req->session->session_key);
    503                 if (!NT_STATUS_IS_OK(status)) {
    504                         req->state = SMB2_REQUEST_ERROR;
    505                         req->status = status;
    506                         return;
    507                 }
    508         }
    509 
    510         if (req->transport->compound.missing > 0) {
    511                 req->transport->compound.buffer = req->out;
    512         } else {
    513                 status = smb2_transport_raw_send(req->transport,
    514                                                  &req->out);
    515                 if (!NT_STATUS_IS_OK(status)) {
    516                         req->state = SMB2_REQUEST_ERROR;
    517                         req->status = status;
    518                         return;
    519                 }
    520         }
    521         ZERO_STRUCT(req->out);
    522 
    523         req->state = SMB2_REQUEST_RECV;
    524         DLIST_ADD(req->transport->pending_recv, req);
    525 
    526         /* add a timeout */
    527         if (req->transport->options.request_timeout) {
    528                 event_add_timed(req->transport->socket->event.ctx, req,
    529                                 timeval_current_ofs(req->transport->options.request_timeout, 0),
    530                                 smb2_timeout_handler, req);
    531         }
    532 
    533         talloc_set_destructor(req, smb2_request_destructor);
     419        TALLOC_FREE(recv_iov);
    534420}
    535421
     
    537423                                       uint32_t num)
    538424{
     425        TALLOC_FREE(transport->compound.reqs);
    539426        ZERO_STRUCT(transport->compound);
    540         transport->compound.missing = num;
     427
     428        transport->compound.reqs = talloc_zero_array(transport,
     429                                                     struct tevent_req *,
     430                                                     num);
     431        if (transport->compound.reqs == NULL) {
     432                return NT_STATUS_NO_MEMORY;
     433        }
     434
    541435        return NT_STATUS_OK;
    542436}
     
    551445                                    uint16_t ask_num)
    552446{
    553         transport->credits.ask_num = ask_num;
    554 }
    555 
    556 void smb2_transport_credits_set_charge(struct smb2_transport *transport,
    557                                        uint16_t charge)
    558 {
    559         transport->credits.charge = charge;
     447        smb2cli_conn_set_max_credits(transport->conn, ask_num);
    560448}
    561449
     
    565453        struct smb2_transport *transport = talloc_get_type(private_data,
    566454                                                           struct smb2_transport);
    567         struct timeval next = timeval_add(&t, 0, transport->idle.period);
    568         transport->socket->event.te = event_add_timed(transport->socket->event.ctx,
    569                                                       transport,
    570                                                       next,
    571                                                       idle_handler, transport);
     455        struct timeval next;
     456
    572457        transport->idle.func(transport, transport->idle.private_data);
     458
     459        next = timeval_current_ofs_usec(transport->idle.period);
     460        transport->idle.te = tevent_add_timer(transport->ev,
     461                                              transport,
     462                                              next,
     463                                              idle_handler,
     464                                              transport);
    573465}
    574466
     
    582474                                 void *private_data)
    583475{
     476        TALLOC_FREE(transport->idle.te);
     477
    584478        transport->idle.func = idle_func;
    585479        transport->idle.private_data = private_data;
    586480        transport->idle.period = period;
    587481
    588         if (transport->socket->event.te != NULL) {
    589                 talloc_free(transport->socket->event.te);
    590         }
    591 
    592         transport->socket->event.te = event_add_timed(transport->socket->event.ctx,
    593                                                       transport,
    594                                                       timeval_current_ofs(0, period),
    595                                                       idle_handler, transport);
    596 }
     482        transport->idle.te = tevent_add_timer(transport->ev,
     483                                              transport,
     484                                              timeval_current_ofs_usec(period),
     485                                              idle_handler,
     486                                              transport);
     487}
  • vendor/current/source4/libcli/smb2/util.c

    r740 r988  
    231231        return (h1.data[0] == h2.data[0]) && (h1.data[1] == h2.data[1]);
    232232}
     233
     234bool smb2_util_handle_empty(const struct smb2_handle h)
     235{
     236        struct smb2_handle empty;
     237
     238        ZERO_STRUCT(empty);
     239
     240        return smb2_util_handle_equal(h, empty);
     241}
  • vendor/current/source4/libcli/smb2/write.c

    r414 r988  
    5959{
    6060        if (!smb2_request_receive(req) ||
    61             smb2_request_is_error(req)) {
     61            !smb2_request_is_ok(req)) {
    6262                return smb2_request_destroy(req);
    6363        }
  • vendor/current/source4/libcli/smb2/wscript_build

    r740 r988  
    22
    33bld.SAMBA_SUBSYSTEM('LIBCLI_SMB2',
    4         source='transport.c request.c negprot.c session.c tcon.c create.c close.c connect.c getinfo.c write.c read.c setinfo.c find.c ioctl.c logoff.c tdis.c flush.c lock.c notify.c cancel.c keepalive.c break.c util.c signing.c lease_break.c',
     4        source='transport.c request.c session.c tcon.c create.c close.c connect.c getinfo.c write.c read.c setinfo.c find.c ioctl.c logoff.c tdis.c flush.c lock.c notify.c cancel.c keepalive.c break.c util.c signing.c lease_break.c',
    55        autoproto='smb2_proto.h',
    6         public_deps='LIBCLI_RAW LIBPACKET gensec'
     6        deps='tevent-util cli_smb_common',
     7        public_deps='smbclient-raw gensec samba-credentials tevent',
     8        private_headers='smb2.h',
    79        )
    810
  • vendor/current/source4/libcli/smb_composite/appendacl.c

    r740 r988  
    248248        c->private_data = state;
    249249        c->state = COMPOSITE_STATE_IN_PROGRESS;
    250         c->event_ctx = tree->session->transport->socket->event.ctx;
     250        c->event_ctx = tree->session->transport->ev;
    251251
    252252        /* setup structures for opening file */
  • vendor/current/source4/libcli/smb_composite/connect.c

    r740 r988  
    3232#include "param/param.h"
    3333#include "lib/util/util_net.h"
     34#include "libcli/smb/smbXcli_base.h"
    3435
    3536/* the stages of this call */
    3637enum connect_stage {CONNECT_SOCKET,
    37                     CONNECT_SESSION_REQUEST,
    3838                    CONNECT_NEGPROT,
    3939                    CONNECT_SESSION_SETUP,
     
    5353        struct smbcli_request *req;
    5454        struct composite_context *creq;
     55        struct tevent_req *subreq;
     56        struct nbt_name calling, called;
    5557};
    5658
     
    5860static void request_handler(struct smbcli_request *);
    5961static void composite_handler(struct composite_context *);
     62static void subreq_handler(struct tevent_req *subreq);
    6063
    6164/*
     
    7073        status = smb_raw_tcon_recv(state->req, c, state->io_tcon);
    7174        NT_STATUS_NOT_OK_RETURN(status);
     75
     76        if (state->io_tcon->tconx.out.options & SMB_EXTENDED_SIGNATURES) {
     77                smb1cli_session_protect_session_key(io->out.tree->session->smbXcli);
     78        }
    7279
    7380        io->out.tree->tid = state->io_tcon->tconx.out.tid;
     
    109116        /* connect to a share using a tree connect */
    110117        state->io_tcon->generic.level = RAW_TCON_TCONX;
    111         state->io_tcon->tconx.in.flags = 0;
     118        state->io_tcon->tconx.in.flags = TCONX_FLAG_EXTENDED_RESPONSE;
    112119        state->io_tcon->tconx.in.password = data_blob(NULL, 0);
    113120       
     
    162169                 * would lead to an invalid uid in the anonymous fallback */
    163170                state->session->vuid = 0;
    164                 data_blob_free(&state->session->user_session_key);
    165171                talloc_free(state->session->gensec);
    166172                state->session->gensec = NULL;
     
    195201        /* connect to a share using a tree connect */
    196202        state->io_tcon->generic.level = RAW_TCON_TCONX;
    197         state->io_tcon->tconx.in.flags = 0;
     203        state->io_tcon->tconx.in.flags = TCONX_FLAG_EXTENDED_RESPONSE;
     204        state->io_tcon->tconx.in.flags |= TCONX_FLAG_EXTENDED_SIGNATURES;
    198205        state->io_tcon->tconx.in.password = data_blob(NULL, 0);
    199206       
     
    231238        NTSTATUS status;
    232239
    233         status = smb_raw_negotiate_recv(state->req);
     240        status = smb_raw_negotiate_recv(state->subreq);
     241        TALLOC_FREE(state->subreq);
    234242        NT_STATUS_NOT_OK_RETURN(status);
    235243
     
    282290        struct connect_state *state = talloc_get_type(c->private_data, struct connect_state);
    283291
    284         state->req = smb_raw_negotiate_send(state->transport, io->in.options.unicode, io->in.options.max_protocol);
    285         NT_STATUS_HAVE_NO_MEMORY(state->req);
    286 
    287         state->req->async.fn = request_handler;
    288         state->req->async.private_data = c;
     292        /* the socket is up - we can initialise the smbcli transport layer */
     293        state->transport = smbcli_transport_init(state->sock, state, true,
     294                                                 &io->in.options);
     295        NT_STATUS_HAVE_NO_MEMORY(state->transport);
     296
     297        state->subreq = smb_raw_negotiate_send(state,
     298                                               state->transport->ev,
     299                                               state->transport,
     300                                               state->transport->options.min_protocol,
     301                                               state->transport->options.max_protocol);
     302        NT_STATUS_HAVE_NO_MEMORY(state->subreq);
     303        tevent_req_set_callback(state->subreq, subreq_handler, c);
    289304        state->stage = CONNECT_NEGPROT;
    290        
     305
    291306        return NT_STATUS_OK;
    292 }
    293 
    294 
    295 /*
    296   a session request operation has completed
    297 */
    298 static NTSTATUS connect_session_request(struct composite_context *c,
    299                                         struct smb_composite_connect *io)
    300 {
    301         struct connect_state *state = talloc_get_type(c->private_data, struct connect_state);
    302         NTSTATUS status;
    303 
    304         status = smbcli_transport_connect_recv(state->req);
    305         NT_STATUS_NOT_OK_RETURN(status);
    306 
    307         /* next step is a negprot */
    308         return connect_send_negprot(c, io);
    309307}
    310308
     
    317315        struct connect_state *state = talloc_get_type(c->private_data, struct connect_state);
    318316        NTSTATUS status;
    319         struct nbt_name calling, called;
    320317
    321318        status = smbcli_sock_connect_recv(state->creq, state, &state->sock);
    322319        NT_STATUS_NOT_OK_RETURN(status);
    323 
    324         /* the socket is up - we can initialise the smbcli transport layer */
    325         state->transport = smbcli_transport_init(state->sock, state, true,
    326                                                  &io->in.options);
    327         NT_STATUS_HAVE_NO_MEMORY(state->transport);
    328320
    329321        if (is_ipaddress(state->sock->hostname) &&
     
    337329        }
    338330
    339         make_nbt_name_client(&calling, cli_credentials_get_workstation(io->in.credentials));
    340 
    341         nbt_choose_called_name(state, &called, io->in.called_name, NBT_NAME_SERVER);
    342 
    343         /* we have a connected socket - next step is a session
    344            request, if needed. Port 445 doesn't need it, so it goes
    345            straight to the negprot */
    346         if (state->sock->port == 445) {
    347                 status = nbt_name_dup(state->transport, &called,
    348                                       &state->transport->called);
    349                 NT_STATUS_NOT_OK_RETURN(status);
    350                 return connect_send_negprot(c, io);
    351         }
    352 
    353         state->req = smbcli_transport_connect_send(state->transport, &calling, &called);
    354         NT_STATUS_HAVE_NO_MEMORY(state->req);
    355 
    356         state->req->async.fn = request_handler;
    357         state->req->async.private_data = c;
    358         state->stage = CONNECT_SESSION_REQUEST;
    359 
    360         return NT_STATUS_OK;
     331        /* next step is a negprot */
     332        return connect_send_negprot(c, io);
    361333}
    362334
     
    372344        case CONNECT_SOCKET:
    373345                c->status = connect_socket(c, state->io);
    374                 break;
    375         case CONNECT_SESSION_REQUEST:
    376                 c->status = connect_session_request(c, state->io);
    377346                break;
    378347        case CONNECT_NEGPROT:
     
    422391
    423392/*
     393  handler for completion of a tevent_req sub-request
     394*/
     395static void subreq_handler(struct tevent_req *subreq)
     396{
     397        struct composite_context *c =
     398                tevent_req_callback_data(subreq,
     399                struct composite_context);
     400        state_handler(c);
     401}
     402
     403/*
    424404  a function to establish a smbcli_tree from scratch
    425405*/
     
    446426        c->state = COMPOSITE_STATE_IN_PROGRESS;
    447427        c->private_data = state;
     428
     429        make_nbt_name_client(&state->calling,
     430                             cli_credentials_get_workstation(io->in.credentials));
     431
     432        nbt_choose_called_name(state, &state->called,
     433                               io->in.called_name, NBT_NAME_SERVER);
    448434
    449435        state->creq = smbcli_sock_connect_send(state,
     
    452438                                               io->in.dest_host,
    453439                                               resolve_ctx, c->event_ctx,
    454                                                io->in.socket_options);
     440                                               io->in.socket_options,
     441                                               &state->calling,
     442                                               &state->called);
    455443        if (state->creq == NULL) goto failed;
    456444
  • vendor/current/source4/libcli/smb_composite/fsinfo.c

    r740 r988  
    128128struct composite_context *smb_composite_fsinfo_send(struct smbcli_tree *tree,
    129129                                                    struct smb_composite_fsinfo *io,
    130                                                     struct resolve_context *resolve_ctx)
     130                                                    struct resolve_context *resolve_ctx,
     131                                                    struct tevent_context *event_ctx)
    131132{
    132133        struct composite_context *c;
     
    136137        if (c == NULL) goto failed;
    137138
     139        c->event_ctx = event_ctx;
     140        if (c->event_ctx == NULL) goto failed;
     141
    138142        state = talloc(c, struct fsinfo_state);
    139143        if (state == NULL) goto failed;
     
    141145        state->io = io;
    142146
    143         state->connect = talloc(state, struct smb_composite_connect);
     147        state->connect = talloc_zero(state, struct smb_composite_connect);
    144148
    145149        if (state->connect == NULL) goto failed;
     
    202206                              TALLOC_CTX *mem_ctx,
    203207                              struct smb_composite_fsinfo *io,
    204                               struct resolve_context *resolve_ctx)
    205 {
    206         struct composite_context *c = smb_composite_fsinfo_send(tree, io, resolve_ctx);
     208                              struct resolve_context *resolve_ctx,
     209                              struct tevent_context *ev)
     210{
     211        struct composite_context *c = smb_composite_fsinfo_send(tree, io, resolve_ctx, ev);
    207212        return smb_composite_fsinfo_recv(c, mem_ctx);
    208213}
  • vendor/current/source4/libcli/smb_composite/loadfile.c

    r414 r988  
    230230        c->private_data = state;
    231231        c->state = COMPOSITE_STATE_IN_PROGRESS;
    232         c->event_ctx = tree->session->transport->socket->event.ctx;
     232        c->event_ctx = tree->session->transport->ev;
    233233
    234234        /* setup for the open */
  • vendor/current/source4/libcli/smb_composite/savefile.c

    r414 r988  
    226226
    227227        c->state = COMPOSITE_STATE_IN_PROGRESS;
    228         c->event_ctx = tree->session->transport->socket->event.ctx;
     228        c->event_ctx = tree->session->transport->ev;
    229229
    230230        state = talloc(c, struct savefile_state);
  • vendor/current/source4/libcli/smb_composite/sesssetup.c

    r414 r988  
    2626#include "libcli/composite/composite.h"
    2727#include "libcli/smb_composite/smb_composite.h"
    28 #include "libcli/smb_composite/proto.h"
    2928#include "libcli/auth/libcli_auth.h"
    3029#include "auth/auth.h"
     
    3332#include "version.h"
    3433#include "param/param.h"
     34#include "libcli/smb/smbXcli_base.h"
    3535
    3636struct sesssetup_state {
     
    4040        struct smb_composite_sesssetup *io;
    4141        struct smbcli_request *req;
     42        unsigned int logon_retries;
    4243};
    4344
     
    6667
    6768/*
    68   store the user session key for a transport
    69 */
    70 static void set_user_session_key(struct smbcli_session *session,
    71                                  const DATA_BLOB *session_key)
    72 {
    73         session->user_session_key = data_blob_talloc(session,
    74                                                      session_key->data,
    75                                                      session_key->length);
    76 }
    77 
    78 /*
    7969  handler for completion of a smbcli_request sub-request
    8070*/
     
    8474        struct sesssetup_state *state = talloc_get_type(c->private_data, struct sesssetup_state);
    8575        struct smbcli_session *session = req->session;
    86         DATA_BLOB session_key = data_blob(NULL, 0);
    8776        DATA_BLOB null_data_blob = data_blob(NULL, 0);
    8877        NTSTATUS session_key_err, nt_status;
     
    136125                state->io->out.vuid = state->setup.nt1.out.vuid;
    137126                if (NT_STATUS_EQUAL(c->status, NT_STATUS_LOGON_FAILURE)) {
    138                         /* we neet to reset the vuid for a new try */
     127                        /* we need to reset the vuid for a new try */
    139128                        session->vuid = 0;
    140129                        if (cli_credentials_wrong_password(state->io->in.credentials)) {
     
    157146                state->io->out.vuid = state->setup.spnego.out.vuid;
    158147                if (NT_STATUS_EQUAL(c->status, NT_STATUS_LOGON_FAILURE)) {
     148                        const char *principal;
     149
    159150                        /* we need to reset the vuid for a new try */
    160151                        session->vuid = 0;
    161                         if (cli_credentials_wrong_password(state->io->in.credentials)) {
     152
     153                        principal = gensec_get_target_principal(session->gensec);
     154                        if (principal == NULL) {
     155                                const char *hostname = gensec_get_target_hostname(session->gensec);
     156                                const char *service  = gensec_get_target_service(session->gensec);
     157                                if (hostname != NULL && service != NULL) {
     158                                        principal = talloc_asprintf(state, "%s/%s", service, hostname);
     159                                }
     160                        }
     161                        if (cli_credentials_failed_kerberos_login(state->io->in.credentials, principal, &state->logon_retries) ||
     162                            cli_credentials_wrong_password(state->io->in.credentials)) {
    162163                                nt_status = session_setup_spnego(c, session,
    163164                                                                      state->io,
     
    184185                         * requirements */
    185186                       
    186                         state->gensec_status = gensec_update(session->gensec, state,
     187                        state->gensec_status = gensec_update_ev(session->gensec, state, c->event_ctx,
    187188                                                         state->setup.spnego.out.secblob,
    188189                                                         &state->setup.spnego.in.secblob);
     
    196197                }
    197198
    198                 if (NT_STATUS_IS_OK(state->remote_status)) {
     199                if (cli_credentials_is_anonymous(state->io->in.credentials)) {
     200                        /*
     201                         * anonymous => no signing
     202                         */
     203                } else if (NT_STATUS_IS_OK(state->remote_status)) {
     204                        DATA_BLOB session_key;
     205
    199206                        if (state->setup.spnego.in.secblob.length) {
    200207                                c->status = NT_STATUS_INTERNAL_ERROR;
    201208                                break;
    202209                        }
    203                         session_key_err = gensec_session_key(session->gensec, &session_key);
     210                        session_key_err = gensec_session_key(session->gensec, session, &session_key);
    204211                        if (NT_STATUS_IS_OK(session_key_err)) {
    205                                 set_user_session_key(session, &session_key);
    206                                 smbcli_transport_simple_set_signing(session->transport, session_key, null_data_blob);
     212                                smb1cli_conn_activate_signing(session->transport->conn,
     213                                                              session_key,
     214                                                              null_data_blob);
     215                        }
     216
     217                        c->status = smb1cli_session_set_session_key(session->smbXcli,
     218                                                                    session_key);
     219                        data_blob_free(&session_key);
     220                        if (!NT_STATUS_IS_OK(c->status)) {
     221                                break;
    207222                        }
    208223                }
     
    217232                        state->req = smb_raw_sesssetup_send(session, &state->setup);
    218233                        session->vuid = vuid;
    219                         if (state->req) {
     234                        if (state->req &&
     235                            !smb1cli_conn_signing_is_active(state->req->transport->conn)) {
    220236                                state->req->sign_caller_checks = true;
    221237                        }
     
    233249
    234250        if (check_req) {
     251                bool ok;
     252
    235253                check_req->sign_caller_checks = false;
    236                 if (!smbcli_request_check_sign_mac(check_req)) {
     254
     255                ok = smb1cli_conn_check_signing(check_req->transport->conn,
     256                                                check_req->in.buffer, 1);
     257                if (!ok) {
    237258                        c->status = NT_STATUS_ACCESS_DENIED;
    238259                }
    239260                talloc_free(check_req);
    240261                check_req = NULL;
    241         }
    242 
    243         /* enforce the local signing required flag */
    244         if (NT_STATUS_IS_OK(c->status) && !cli_credentials_is_anonymous(state->io->in.credentials)) {
    245                 if (!session->transport->negotiate.sign_info.doing_signing
    246                     && session->transport->negotiate.sign_info.mandatory_signing) {
    247                         DEBUG(0, ("SMB signing required, but server does not support it\n"));
    248                         c->status = NT_STATUS_ACCESS_DENIED;
    249                 }
    250262        }
    251263
     
    281293{
    282294        NTSTATUS nt_status = NT_STATUS_INTERNAL_ERROR;
    283         struct sesssetup_state *state = talloc_get_type(c->private_data, struct sesssetup_state);
    284         DATA_BLOB names_blob = NTLMv2_generate_names_blob(state, session->transport->socket->hostname, cli_credentials_get_domain(io->in.credentials));
     295        struct sesssetup_state *state = talloc_get_type(c->private_data,
     296                                                        struct sesssetup_state);
     297        const char *domain = cli_credentials_get_domain(io->in.credentials);
     298
     299        /*
     300         * domain controllers tend to reject the NTLM v2 blob
     301         * if the netbiosname is not valid (e.g. IP address or FQDN)
     302         * so just leave it away (as Windows client do)
     303         */
     304        DATA_BLOB names_blob = NTLMv2_generate_names_blob(state, NULL, domain);
     305
    285306        DATA_BLOB session_key = data_blob(NULL, 0);
    286307        int flags = CLI_CRED_NTLM_AUTH;
    287 
    288         smbcli_temp_set_signing(session->transport);
    289308
    290309        if (session->options.lanman_auth) {
     
    311330
    312331        if (session->transport->negotiate.sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) {
     332                if (!cli_credentials_is_anonymous(io->in.credentials) &&
     333                    session->options.ntlmv2_auth &&
     334                    session->transport->options.use_spnego)
     335                {
     336                        /*
     337                         * Don't send an NTLMv2_RESPONSE without NTLMSSP
     338                         * if we want to use spnego
     339                         */
     340                        return NT_STATUS_INVALID_PARAMETER;
     341                }
     342
    313343                nt_status = cli_credentials_get_ntlm_response(io->in.credentials, state,
    314344                                                              &flags,
    315345                                                              session->transport->negotiate.secblob,
     346                                                              NULL, /* server_timestamp */
    316347                                                              names_blob,
    317348                                                              &state->setup.nt1.in.password1,
     
    333364        }
    334365
    335         if (NT_STATUS_IS_OK(nt_status)) {
    336                 smbcli_transport_simple_set_signing(session->transport, session_key,
    337                                                     state->setup.nt1.in.password2);
    338                 set_user_session_key(session, &session_key);
    339                
    340                 data_blob_free(&session_key);
     366        if (!NT_STATUS_IS_OK(nt_status)) {
     367                /*
     368                 * plain text => no signing
     369                 */
     370                return (*req)->status;
     371        }
     372
     373        if (cli_credentials_is_anonymous(io->in.credentials)) {
     374                /*
     375                 * anonymous => no signing
     376                 */
     377                return (*req)->status;
     378        }
     379
     380        smb1cli_conn_activate_signing(session->transport->conn,
     381                                      session_key,
     382                                      state->setup.nt1.in.password2);
     383
     384        nt_status = smb1cli_session_set_session_key(session->smbXcli,
     385                                                    session_key);
     386        data_blob_free(&session_key);
     387        if (!NT_STATUS_IS_OK(nt_status)) {
     388                return nt_status;
    341389        }
    342390
     
    354402{
    355403        NTSTATUS nt_status;
    356         struct sesssetup_state *state = talloc_get_type(c->private_data, struct sesssetup_state);
     404        struct sesssetup_state *state = talloc_get_type(c->private_data,
     405                                                        struct sesssetup_state);
    357406        const char *password = cli_credentials_get_password(io->in.credentials);
    358         DATA_BLOB names_blob = NTLMv2_generate_names_blob(state, session->transport->socket->hostname, cli_credentials_get_domain(io->in.credentials));
     407
     408        /*
     409         * domain controllers tend to reject the NTLM v2 blob
     410         * if the netbiosname is not valid (e.g. IP address or FQDN)
     411         * so just leave it away (as Windows client do)
     412         */
    359413        DATA_BLOB session_key;
    360         int flags = 0;
    361         if (session->options.lanman_auth) {
    362                 flags |= CLI_CRED_LANMAN_AUTH;
    363         }
    364 
    365         if (session->options.ntlmv2_auth) {
    366                 flags |= CLI_CRED_NTLMv2_AUTH;
    367         }
    368414
    369415        state->setup.old.level      = RAW_SESSSETUP_OLD;
     
    379425       
    380426        if (session->transport->negotiate.sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) {
     427                DATA_BLOB names_blob = data_blob_null;
     428                int flags = 0;
     429
     430                if (!cli_credentials_is_anonymous(io->in.credentials) &&
     431                    !session->options.lanman_auth)
     432                {
     433                        return NT_STATUS_INVALID_PARAMETER;
     434                }
     435
     436                flags |= CLI_CRED_LANMAN_AUTH;
     437
    381438                nt_status = cli_credentials_get_ntlm_response(io->in.credentials, state,
    382439                                                              &flags,
    383440                                                              session->transport->negotiate.secblob,
     441                                                              NULL, /* server_timestamp */
    384442                                                              names_blob,
    385443                                                              &state->setup.old.in.password,
     
    387445                                                              NULL, &session_key);
    388446                NT_STATUS_NOT_OK_RETURN(nt_status);
    389                 set_user_session_key(session, &session_key);
    390                
     447
     448                nt_status = smb1cli_session_set_session_key(session->smbXcli,
     449                                                            session_key);
    391450                data_blob_free(&session_key);
     451                if (!NT_STATUS_IS_OK(nt_status)) {
     452                        return nt_status;
     453                }
    392454        } else if (session->options.plaintext_auth) {
    393455                state->setup.old.in.password = data_blob_talloc(state, password, strlen(password));
     
    427489        state->setup.spnego.in.workgroup    = io->in.workgroup;
    428490
    429         smbcli_temp_set_signing(session->transport);
    430 
    431         status = gensec_client_start(session, &session->gensec, c->event_ctx,
     491        status = gensec_client_start(session, &session->gensec,
    432492                                     io->in.gensec_settings);
    433493        if (!NT_STATUS_IS_OK(status)) {
     
    445505        }
    446506
    447         status = gensec_set_target_hostname(session->gensec, session->transport->socket->hostname);
     507        status = gensec_set_target_hostname(session->gensec,
     508                        smbXcli_conn_remote_name(session->transport->conn));
    448509        if (!NT_STATUS_IS_OK(status)) {
    449510                DEBUG(1, ("Failed to start set GENSEC target hostname: %s\n",
     
    484545        }
    485546
    486         if ((const void *)chosen_oid == (const void *)GENSEC_OID_SPNEGO) {
    487                 status = gensec_update(session->gensec, state,
     547        if (strequal(chosen_oid, GENSEC_OID_SPNEGO)) {
     548                status = gensec_update_ev(session->gensec, state,
     549                                       c->event_ctx,
    488550                                       session->transport->negotiate.secblob,
    489551                                       &state->setup.spnego.in.secblob);
    490552        } else {
    491                 status = gensec_update(session->gensec, state,
     553                status = gensec_update_ev(session->gensec, state,
     554                                       c->event_ctx,
    492555                                       data_blob(NULL, 0),
    493556                                       &state->setup.spnego.in.secblob);
     
    514577         * which comes within the response itself
    515578         */
    516         (*req)->sign_caller_checks = true;
     579        if (!smb1cli_conn_signing_is_active((*req)->transport->conn)) {
     580                (*req)->sign_caller_checks = true;
     581        }
    517582
    518583        return (*req)->status;
     
    532597        NTSTATUS status;
    533598
    534         c = composite_create(session, session->transport->socket->event.ctx);
     599        c = composite_create(session, session->transport->ev);
    535600        if (c == NULL) return NULL;
    536601
  • vendor/current/source4/libcli/smb_composite/smb2.c

    r414 r988  
    2626
    2727#include "includes.h"
     28#include <tevent.h>
     29#include "lib/util/tevent_ntstatus.h"
    2830#include "libcli/raw/libcliraw.h"
    2931#include "libcli/raw/raw_proto.h"
     
    8183        struct smb2_request *req;
    8284
    83         ctx = composite_create(tree, tree->session->transport->socket->event.ctx);
     85        ctx = composite_create(tree, tree->session->transport->ev);
    8486        if (ctx == NULL) return NULL;
    8587
     
    160162        struct smb2_request *req;
    161163
    162         ctx = composite_create(tree, tree->session->transport->socket->event.ctx);
     164        ctx = composite_create(tree, tree->session->transport->ev);
    163165        if (ctx == NULL) return NULL;
    164166
     
    231233        struct smb2_request *req;
    232234
    233         ctx = composite_create(tree, tree->session->transport->socket->event.ctx);
     235        ctx = composite_create(tree, tree->session->transport->ev);
    234236        if (ctx == NULL) return NULL;
    235237
     
    265267}
    266268
    267 
    268 /*
    269   continue after the setfileinfo in a composite setpathinfo
    270  */
    271 static void continue_setpathinfo_close(struct smb2_request *req)
    272 {
    273         struct composite_context *ctx = talloc_get_type(req->async.private_data,
    274                                                         struct composite_context);
    275         struct smb2_tree *tree = req->tree;
    276         struct smb2_close close_parm;
    277         NTSTATUS status;
    278         union smb_setfileinfo *io2 = talloc_get_type(ctx->private_data,
    279                                                      union smb_setfileinfo);
    280 
    281         status = smb2_setinfo_recv(req);
    282         if (!NT_STATUS_IS_OK(status)) {
    283                 composite_error(ctx, status);
    284                 return;
    285         }
    286 
    287         ZERO_STRUCT(close_parm);
    288         close_parm.in.file.handle = io2->generic.in.file.handle;
    289        
    290         req = smb2_close_send(tree, &close_parm);
    291         composite_continue_smb2(ctx, req, continue_close, ctx);
    292 }
    293 
    294 
    295 /*
    296   continue after the create in a composite setpathinfo
    297  */
    298 static void continue_setpathinfo(struct smb2_request *req)
    299 {
    300         struct composite_context *ctx = talloc_get_type(req->async.private_data,
    301                                                         struct composite_context);
    302         struct smb2_tree *tree = req->tree;
    303         struct smb2_create create_parm;
    304         NTSTATUS status;
    305         union smb_setfileinfo *io2 = talloc_get_type(ctx->private_data,
    306                                                      union smb_setfileinfo);
    307 
    308         status = smb2_create_recv(req, ctx, &create_parm);
    309         if (!NT_STATUS_IS_OK(status)) {
    310                 composite_error(ctx, status);
    311                 return;
    312         }
    313 
    314         io2->generic.in.file.handle = create_parm.out.file.handle;
    315 
    316         req = smb2_setinfo_file_send(tree, io2);
    317         composite_continue_smb2(ctx, req, continue_setpathinfo_close, ctx);
    318 }
    319 
     269struct smb2_composite_setpathinfo_state {
     270        struct smb2_tree *tree;
     271        union smb_setfileinfo io;
     272        NTSTATUS set_status;
     273        struct smb2_create cr;
     274        struct smb2_close cl;
     275};
     276
     277static void smb2_composite_setpathinfo_create_done(struct smb2_request *smb2req);
    320278
    321279/*
    322280  composite SMB2 setpathinfo call
    323281*/
    324 struct composite_context *smb2_composite_setpathinfo_send(struct smb2_tree *tree,
    325                                                           union smb_setfileinfo *io)
    326 {
    327         struct composite_context *ctx;
    328         struct smb2_create create_parm;
    329         struct smb2_request *req;
    330         union smb_setfileinfo *io2;
    331 
    332         ctx = composite_create(tree, tree->session->transport->socket->event.ctx);
    333         if (ctx == NULL) return NULL;
    334 
    335         ZERO_STRUCT(create_parm);
    336         create_parm.in.desired_access     = SEC_FLAG_MAXIMUM_ALLOWED;
    337         create_parm.in.create_disposition = NTCREATEX_DISP_OPEN;
    338         create_parm.in.share_access =
     282struct tevent_req *smb2_composite_setpathinfo_send(TALLOC_CTX *mem_ctx,
     283                                                   struct tevent_context *ev,
     284                                                   struct smb2_tree *tree,
     285                                                   const union smb_setfileinfo *io)
     286{
     287        struct tevent_req *req;
     288        struct smb2_composite_setpathinfo_state *state;
     289        struct smb2_request *smb2req;
     290
     291        req = tevent_req_create(mem_ctx, &state,
     292                                struct smb2_composite_setpathinfo_state);
     293        if (req == NULL) {
     294                return NULL;
     295        }
     296
     297        state->tree = tree;
     298        state->io = *io;
     299
     300        state->cr.in.desired_access     = SEC_FLAG_MAXIMUM_ALLOWED;
     301        state->cr.in.create_disposition = NTCREATEX_DISP_OPEN;
     302        state->cr.in.share_access =
    339303                NTCREATEX_SHARE_ACCESS_DELETE|
    340304                NTCREATEX_SHARE_ACCESS_READ|
    341305                NTCREATEX_SHARE_ACCESS_WRITE;
    342         create_parm.in.create_options = 0;
    343         create_parm.in.fname = io->generic.in.file.path;
    344         if (create_parm.in.fname[0] == '\\') {
    345                 create_parm.in.fname++;
    346         }
    347 
    348         req = smb2_create_send(tree, &create_parm);
    349 
    350         io2 = talloc(ctx, union smb_setfileinfo);
    351         if (composite_nomem(io2, ctx)) {
    352                 return ctx;
    353         }
    354         *io2 = *io;
    355 
    356         ctx->private_data = io2;
    357 
    358         composite_continue_smb2(ctx, req, continue_setpathinfo, ctx);
    359         return ctx;
    360 }
    361 
     306        state->cr.in.create_options = 0;
     307        state->cr.in.fname = state->io.generic.in.file.path;
     308        if (state->cr.in.fname[0] == '\\') {
     309                state->cr.in.fname++;
     310        }
     311
     312        smb2req = smb2_create_send(tree, &state->cr);
     313        if (tevent_req_nomem(smb2req, req)) {
     314                return tevent_req_post(req, ev);
     315        }
     316        smb2req->async.fn = smb2_composite_setpathinfo_create_done;
     317        smb2req->async.private_data = req;
     318
     319        return req;
     320}
     321
     322static void smb2_composite_setpathinfo_setinfo_done(struct smb2_request *smb2req);
     323
     324static void smb2_composite_setpathinfo_create_done(struct smb2_request *smb2req)
     325{
     326        struct tevent_req *req =
     327                talloc_get_type_abort(smb2req->async.private_data,
     328                struct tevent_req);
     329        struct smb2_composite_setpathinfo_state *state =
     330                tevent_req_data(req,
     331                struct smb2_composite_setpathinfo_state);
     332        NTSTATUS status;
     333
     334        status = smb2_create_recv(smb2req, state, &state->cr);
     335        if (tevent_req_nterror(req, status)) {
     336                return;
     337        }
     338
     339        state->io.generic.in.file.handle = state->cr.out.file.handle;
     340
     341        smb2req = smb2_setinfo_file_send(state->tree, &state->io);
     342        if (tevent_req_nomem(smb2req, req)) {
     343                return;
     344        }
     345        smb2req->async.fn = smb2_composite_setpathinfo_setinfo_done;
     346        smb2req->async.private_data = req;
     347}
     348
     349static void smb2_composite_setpathinfo_close_done(struct smb2_request *smb2req);
     350
     351static void smb2_composite_setpathinfo_setinfo_done(struct smb2_request *smb2req)
     352{
     353        struct tevent_req *req =
     354                talloc_get_type_abort(smb2req->async.private_data,
     355                struct tevent_req);
     356        struct smb2_composite_setpathinfo_state *state =
     357                tevent_req_data(req,
     358                struct smb2_composite_setpathinfo_state);
     359        NTSTATUS status;
     360
     361        status = smb2_setinfo_recv(smb2req);
     362        state->set_status = status;
     363
     364        state->cl.in.file.handle = state->io.generic.in.file.handle;
     365
     366        smb2req = smb2_close_send(state->tree, &state->cl);
     367        if (tevent_req_nomem(smb2req, req)) {
     368                return;
     369        }
     370        smb2req->async.fn = smb2_composite_setpathinfo_close_done;
     371        smb2req->async.private_data = req;
     372}
     373
     374static void smb2_composite_setpathinfo_close_done(struct smb2_request *smb2req)
     375{
     376        struct tevent_req *req =
     377                talloc_get_type_abort(smb2req->async.private_data,
     378                struct tevent_req);
     379        struct smb2_composite_setpathinfo_state *state =
     380                tevent_req_data(req,
     381                struct smb2_composite_setpathinfo_state);
     382        NTSTATUS status;
     383
     384        status = smb2_close_recv(smb2req, &state->cl);
     385
     386        if (tevent_req_nterror(req, state->set_status)) {
     387                return;
     388        }
     389
     390        if (tevent_req_nterror(req, status)) {
     391                return;
     392        }
     393
     394        tevent_req_done(req);
     395}
     396
     397NTSTATUS smb2_composite_setpathinfo_recv(struct tevent_req *req)
     398{
     399        NTSTATUS status;
     400
     401        if (tevent_req_is_nterror(req, &status)) {
     402                tevent_req_received(req);
     403                return status;
     404        }
     405
     406        tevent_req_received(req);
     407        return NT_STATUS_OK;
     408}
    362409
    363410/*
     
    366413NTSTATUS smb2_composite_setpathinfo(struct smb2_tree *tree, union smb_setfileinfo *io)
    367414{
    368         struct composite_context *c = smb2_composite_setpathinfo_send(tree, io);
    369         return composite_wait_free(c); 
    370 }
     415        struct tevent_req *subreq;
     416        NTSTATUS status;
     417        bool ok;
     418        TALLOC_CTX *frame = talloc_stackframe();
     419        struct tevent_context *ev = tree->session->transport->ev;
     420
     421        if (frame == NULL) {
     422                return NT_STATUS_NO_MEMORY;
     423        }
     424
     425        subreq = smb2_composite_setpathinfo_send(frame, ev, tree, io);
     426        if (subreq == NULL) {
     427                TALLOC_FREE(frame);
     428                return NT_STATUS_NO_MEMORY;
     429        }
     430
     431        ok = tevent_req_poll(subreq, ev);
     432        if (!ok) {
     433                status = map_nt_error_from_unix_common(errno);
     434                TALLOC_FREE(frame);
     435                return status;
     436        }
     437
     438        status = smb2_composite_setpathinfo_recv(subreq);
     439        TALLOC_FREE(subreq);
     440        if (!NT_STATUS_IS_OK(status)) {
     441                TALLOC_FREE(frame);
     442                return status;
     443        }
     444
     445        TALLOC_FREE(frame);
     446        return NT_STATUS_OK;
     447}
  • vendor/current/source4/libcli/smb_composite/smb_composite.h

    r740 r988  
    2828*/
    2929
    30 #include "libcli/raw/signing.h"
     30#ifndef __SMB_COMPOSITE_H__
     31#define __SMB_COMPOSITE_H__
     32
    3133#include "libcli/raw/libcliraw.h"
    3234#include "libcli/smb2/smb2.h"
    3335
    34 
    3536/*
    3637  a composite open/read(s)/close request that loads a whole file
     
    4647        } out;
    4748};
     49
     50struct composite_context *smb_composite_loadfile_send(struct smbcli_tree *tree,
     51                                                     struct smb_composite_loadfile *io);
     52NTSTATUS smb_composite_loadfile_recv(struct composite_context *c, TALLOC_CTX *mem_ctx);
     53NTSTATUS smb_composite_loadfile(struct smbcli_tree *tree,
     54                                TALLOC_CTX *mem_ctx,
     55                                struct smb_composite_loadfile *io);
    4856
    4957struct smb_composite_fetchfile {
     
    6977};
    7078
     79struct composite_context *smb_composite_fetchfile_send(struct smb_composite_fetchfile *io,
     80                                                       struct tevent_context *event_ctx);
     81NTSTATUS smb_composite_fetchfile_recv(struct composite_context *c,
     82                                      TALLOC_CTX *mem_ctx);
     83NTSTATUS smb_composite_fetchfile(struct smb_composite_fetchfile *io,
     84                                 TALLOC_CTX *mem_ctx);
     85
    7186/*
    7287  a composite open/write(s)/close request that saves a whole file from
     
    8196};
    8297
     98struct composite_context *smb_composite_savefile_send(struct smbcli_tree *tree,
     99                                                      struct smb_composite_savefile *io);
     100NTSTATUS smb_composite_savefile_recv(struct composite_context *c);
     101NTSTATUS smb_composite_savefile(struct smbcli_tree *tree,
     102                                struct smb_composite_savefile *io);
    83103
    84104/*
     
    112132};
    113133
     134struct composite_context *smb_composite_connect_send(struct smb_composite_connect *io,
     135                                                     TALLOC_CTX *mem_ctx,
     136                                                     struct resolve_context *resolve_ctx,
     137                                                     struct tevent_context *event_ctx);
     138NTSTATUS smb_composite_connect_recv(struct composite_context *c, TALLOC_CTX *mem_ctx);
     139NTSTATUS smb_composite_connect(struct smb_composite_connect *io, TALLOC_CTX *mem_ctx,
     140                               struct resolve_context *resolve_ctx,
     141                               struct tevent_context *ev);
     142
    114143
    115144/*
     
    129158        } out;         
    130159};
     160
     161struct composite_context *smb_composite_sesssetup_send(struct smbcli_session *session,
     162                                                       struct smb_composite_sesssetup *io);
     163NTSTATUS smb_composite_sesssetup_recv(struct composite_context *c);
     164NTSTATUS smb_composite_sesssetup(struct smbcli_session *session, struct smb_composite_sesssetup *io);
    131165
    132166/*
     
    152186};
    153187
     188struct composite_context *smb_composite_fsinfo_send(struct smbcli_tree *tree,
     189                                                    struct smb_composite_fsinfo *io,
     190                                                    struct resolve_context *resolve_ctx,
     191                                                    struct tevent_context *event_ctx);
     192NTSTATUS smb_composite_fsinfo_recv(struct composite_context *c, TALLOC_CTX *mem_ctx);
     193NTSTATUS smb_composite_fsinfo(struct smbcli_tree *tree,
     194                              TALLOC_CTX *mem_ctx,
     195                              struct smb_composite_fsinfo *io,
     196                              struct resolve_context *resolve_ctx,
     197                              struct tevent_context *ev);
     198
    154199/*
    155200  composite call for appending new acl to the file's security descriptor and get
     
    168213        } out;
    169214};
     215
     216struct composite_context *smb_composite_appendacl_send(struct smbcli_tree *tree,
     217                                                        struct smb_composite_appendacl *io);
     218NTSTATUS smb_composite_appendacl_recv(struct composite_context *c, TALLOC_CTX *mem_ctx);
     219NTSTATUS smb_composite_appendacl(struct smbcli_tree *tree,
     220                                TALLOC_CTX *mem_ctx,
     221                                struct smb_composite_appendacl *io);
    170222
    171223/*
     
    190242struct resolve_context;
    191243
    192 #include "libcli/smb_composite/proto.h"
     244struct composite_context *smb2_composite_unlink_send(struct smb2_tree *tree,
     245                                                     union smb_unlink *io);
     246NTSTATUS smb2_composite_unlink(struct smb2_tree *tree, union smb_unlink *io);
     247struct composite_context *smb2_composite_mkdir_send(struct smb2_tree *tree,
     248                                                     union smb_mkdir *io);
     249NTSTATUS smb2_composite_mkdir(struct smb2_tree *tree, union smb_mkdir *io);
     250struct composite_context *smb2_composite_rmdir_send(struct smb2_tree *tree,
     251                                                    struct smb_rmdir *io);
     252NTSTATUS smb2_composite_rmdir(struct smb2_tree *tree, struct smb_rmdir *io);
     253struct tevent_req *smb2_composite_setpathinfo_send(TALLOC_CTX *mem_ctx,
     254                                                   struct tevent_context *ev,
     255                                                   struct smb2_tree *tree,
     256                                                   const union smb_setfileinfo *io);
     257NTSTATUS smb2_composite_setpathinfo_recv(struct tevent_req *req);
     258NTSTATUS smb2_composite_setpathinfo(struct smb2_tree *tree, union smb_setfileinfo *io);
     259
     260#endif /* __SMB_COMPOSITE_H__ */
  • vendor/current/source4/libcli/util/clilsa.c

    r860 r988  
    3333#include "librpc/gen_ndr/ndr_lsa_c.h"
    3434#include "libcli/util/clilsa.h"
     35#include "libcli/smb/smbXcli_base.h"
    3536
    3637struct smblsa_state {
    37         struct dcerpc_pipe *pipe;
     38        struct dcerpc_binding_handle *binding_handle;
    3839        struct smbcli_tree *ipc_tree;
    3940        struct policy_handle handle;
     
    4647{
    4748        struct smblsa_state *lsa;
     49        struct dcerpc_pipe *lsa_pipe;
    4850        NTSTATUS status;
    4951        struct lsa_OpenPolicy r;
     
    6971        /* connect to IPC$ */
    7072        tcon.generic.level = RAW_TCON_TCONX;
    71         tcon.tconx.in.flags = 0;
     73        tcon.tconx.in.flags = TCONX_FLAG_EXTENDED_RESPONSE;
     74        tcon.tconx.in.flags |= TCONX_FLAG_EXTENDED_SIGNATURES;
    7275        tcon.tconx.in.password = data_blob(NULL, 0);
    7376        tcon.tconx.in.path = "ipc$";
     
    8083        lsa->ipc_tree->tid = tcon.tconx.out.tid;
    8184
    82         lsa->pipe = dcerpc_pipe_init(lsa, cli->transport->socket->event.ctx);
    83         if (lsa->pipe == NULL) {
     85        if (tcon.tconx.out.options & SMB_EXTENDED_SIGNATURES) {
     86                smb1cli_session_protect_session_key(cli->session->smbXcli);
     87        }
     88
     89        lsa_pipe = dcerpc_pipe_init(lsa, cli->transport->ev);
     90        if (lsa_pipe == NULL) {
    8491                talloc_free(lsa);
    8592                return NT_STATUS_NO_MEMORY;
     
    8794
    8895        /* open the LSA pipe */
    89         status = dcerpc_pipe_open_smb(lsa->pipe, lsa->ipc_tree, NDR_LSARPC_NAME);
     96        status = dcerpc_pipe_open_smb(lsa_pipe, lsa->ipc_tree, NDR_LSARPC_NAME);
    9097        if (!NT_STATUS_IS_OK(status)) {
    9198                talloc_free(lsa);
     
    94101
    95102        /* bind to the LSA pipe */
    96         status = dcerpc_bind_auth_none(lsa->pipe, &ndr_table_lsarpc);
     103        status = dcerpc_bind_auth_none(lsa_pipe, &ndr_table_lsarpc);
    97104        if (!NT_STATUS_IS_OK(status)) {
    98105                talloc_free(lsa);
    99106                return status;
    100107        }
    101 
     108        lsa->binding_handle = lsa_pipe->binding_handle;
    102109
    103110        /* open a lsa policy handle */
     
    119126        r.out.handle = &lsa->handle;
    120127
    121         status = dcerpc_lsa_OpenPolicy_r(lsa->pipe->binding_handle, lsa, &r);
     128        status = dcerpc_lsa_OpenPolicy_r(lsa->binding_handle, lsa, &r);
    122129        if (!NT_STATUS_IS_OK(status)) {
    123130                talloc_free(lsa);
     
    155162        r.out.rights = rights;
    156163
    157         status = dcerpc_lsa_EnumAccountRights_r(cli->lsa->pipe->binding_handle, mem_ctx, &r);
     164        status = dcerpc_lsa_EnumAccountRights_r(cli->lsa->binding_handle, mem_ctx, &r);
    158165        if (!NT_STATUS_IS_OK(status)) {
    159166                return status;
     
    244251        r.out.domains = &domains;
    245252
    246         status = dcerpc_lsa_LookupSids_r(cli->lsa->pipe->binding_handle, mem_ctx2, &r);
     253        status = dcerpc_lsa_LookupSids_r(cli->lsa->binding_handle, mem_ctx2, &r);
    247254        if (!NT_STATUS_IS_OK(status)) {
    248255                talloc_free(mem_ctx2);
     
    319326        r.out.domains = &domains;
    320327
    321         status = dcerpc_lsa_LookupNames_r(cli->lsa->pipe->binding_handle, mem_ctx2, &r);
     328        status = dcerpc_lsa_LookupNames_r(cli->lsa->binding_handle, mem_ctx2, &r);
    322329        if (!NT_STATUS_IS_OK(status)) {
    323330                talloc_free(mem_ctx2);
     
    368375        r.in.rights = rights;
    369376
    370         status = dcerpc_lsa_AddAccountRights_r(cli->lsa->pipe->binding_handle, mem_ctx, &r);
     377        status = dcerpc_lsa_AddAccountRights_r(cli->lsa->binding_handle, mem_ctx, &r);
    371378        if (!NT_STATUS_IS_OK(status)) {
    372379                return status;
     
    396403        r.in.rights = rights;
    397404
    398         status = dcerpc_lsa_RemoveAccountRights_r(cli->lsa->pipe->binding_handle, mem_ctx, &r);
     405        status = dcerpc_lsa_RemoveAccountRights_r(cli->lsa->binding_handle, mem_ctx, &r);
    399406        if (!NT_STATUS_IS_OK(status)) {
    400407                return status;
  • vendor/current/source4/libcli/util/pyerrors.h

    r740 r988  
    2323#define PyErr_FromWERROR(err) Py_BuildValue("(i,s)", W_ERROR_V(err), discard_const_p(char, win_errstr(err)))
    2424
     25#define PyErr_FromHRESULT(err) Py_BuildValue("(i,s)", HRES_ERROR_V(err), discard_const_p(char, hresult_errstr_const(err)))
     26
    2527#define PyErr_FromNTSTATUS(status) Py_BuildValue("(i,s)", NT_STATUS_V(status), discard_const_p(char, get_friendly_nt_error_msg(status)))
    2628
     
    3941        }
    4042
    41 #define PyErr_WERROR_IS_ERR_RAISE(status) \
     43#define PyErr_NTSTATUS_NOT_OK_RAISE(status) \
     44        if (!NT_STATUS_IS_OK(status)) { \
     45                PyErr_SetNTSTATUS(status); \
     46                return NULL; \
     47        }
     48
     49#define PyErr_WERROR_NOT_OK_RAISE(status) \
    4250        if (!W_ERROR_IS_OK(status)) { \
    4351                PyErr_SetWERROR(status); \
  • vendor/current/source4/libcli/wbclient/wbclient.c

    r740 r988  
    2222#include "includes.h"
    2323#include <tevent.h>
     24#include "lib/util/tevent_unix.h"
    2425#include "libcli/wbclient/wbclient.h"
    25 
    26 /**
    27  * Initialize the wbclient context, talloc_free() when done.
    28  *
    29  * \param mem_ctx talloc context to allocate memory from
    30  * \param msg_ctx message context to use
    31  * \param
    32  */
    33 struct wbc_context *wbc_init(TALLOC_CTX *mem_ctx,
    34                              struct messaging_context *msg_ctx,
    35                              struct tevent_context *event_ctx)
    36 {
    37         struct wbc_context *ctx;
    38 
    39         ctx = talloc(mem_ctx, struct wbc_context);
    40         if (ctx == NULL) return NULL;
    41 
    42         ctx->event_ctx = event_ctx;
    43 
    44         ctx->irpc_handle = irpc_binding_handle_by_name(ctx, msg_ctx,
    45                                                        "winbind_server",
    46                                                        &ndr_table_winbind);
    47         if (ctx->irpc_handle == NULL) {
    48                 talloc_free(ctx);
     26#include "nsswitch/wb_reqtrans.h"
     27#include "system/network.h"
     28#include "libcli/util/error.h"
     29#include "libcli/security/dom_sid.h"
     30
     31static int wb_simple_trans(struct tevent_context *ev, int fd,
     32                           struct winbindd_request *wb_req,
     33                           TALLOC_CTX *mem_ctx,
     34                           struct winbindd_response **resp, int *err)
     35{
     36        struct tevent_req *req;
     37        bool polled;
     38        int ret;
     39
     40        req = wb_simple_trans_send(ev, ev, NULL, fd, wb_req);
     41        if (req == NULL) {
     42                *err = ENOMEM;
     43                return -1;
     44        }
     45
     46        polled = tevent_req_poll(req, ev);
     47        if (!polled) {
     48                *err = errno;
     49                DEBUG(10, ("tevent_req_poll returned %s\n",
     50                           strerror(*err)));
     51                return -1;
     52        }
     53
     54        ret = wb_simple_trans_recv(req, mem_ctx, resp, err);
     55        TALLOC_FREE(req);
     56        return ret;
     57}
     58
     59static const char *winbindd_socket_dir(void)
     60{
     61#ifdef SOCKET_WRAPPER
     62        const char *env_dir;
     63
     64        env_dir = getenv("SELFTEST_WINBINDD_SOCKET_DIR");
     65        if (env_dir) {
     66                return env_dir;
     67        }
     68#endif
     69
     70        return WINBINDD_SOCKET_DIR;
     71}
     72
     73static int winbindd_pipe_sock(void)
     74{
     75        struct sockaddr_un sunaddr = {};
     76        int ret, fd;
     77        char *path;
     78
     79        ret = asprintf(&path, "%s/%s", winbindd_socket_dir(),
     80                       WINBINDD_SOCKET_NAME);
     81        if (ret == -1) {
     82                errno = ENOMEM;
     83                return -1;
     84        }
     85        sunaddr.sun_family = AF_UNIX;
     86        strlcpy(sunaddr.sun_path, path, sizeof(sunaddr.sun_path));
     87        free(path);
     88
     89        fd = socket(AF_UNIX, SOCK_STREAM, 0);
     90        if (fd == -1) {
     91                return -1;
     92        }
     93
     94        ret = connect(fd, (struct sockaddr *)&sunaddr, sizeof(sunaddr));
     95        if (ret == -1) {
     96                int err = errno;
     97                close(fd);
     98                errno = err;
     99                return -1;
     100        }
     101
     102        return fd;
     103}
     104
     105NTSTATUS wbc_sids_to_xids(struct tevent_context *ev, struct id_map *ids,
     106                          uint32_t count)
     107{
     108        TALLOC_CTX *mem_ctx;
     109        struct winbindd_request req = {};
     110        struct winbindd_response *resp;
     111        uint32_t i;
     112        int fd, ret, err;
     113        char *sids, *p;
     114        size_t sidslen;
     115
     116        fd = winbindd_pipe_sock();
     117        if (fd == -1) {
     118                return map_nt_error_from_unix_common(errno);
     119        }
     120
     121        mem_ctx = talloc_new(NULL);
     122        if (mem_ctx == NULL) {
     123                close(fd);
     124                return NT_STATUS_NO_MEMORY;
     125        }
     126
     127        sidslen = count * (DOM_SID_STR_BUFLEN + 1);
     128
     129        sids = talloc_array(mem_ctx, char, sidslen);
     130        if (sids == NULL) {
     131                close(fd);
     132                TALLOC_FREE(mem_ctx);
     133                return NT_STATUS_NO_MEMORY;
     134        }
     135
     136        p = sids;
     137        for (i=0; i<count; i++) {
     138                p += dom_sid_string_buf(ids[i].sid, p, sidslen - (p - sids));
     139                *p++ = '\n';
     140        }
     141        *p++ = '\0';
     142
     143        DEBUG(10, ("sids=\n%s", sids));
     144
     145        req.length = sizeof(struct winbindd_request);
     146        req.cmd = WINBINDD_SIDS_TO_XIDS;
     147        req.pid = getpid();
     148        req.extra_data.data = sids;
     149        req.extra_len = (p - sids);
     150
     151        ret = wb_simple_trans(ev, fd, &req, mem_ctx, &resp, &err);
     152        if (ret == -1) {
     153                return map_nt_error_from_unix_common(err);
     154        }
     155
     156        close(fd);
     157
     158        if (resp->result != WINBINDD_OK || p == NULL) {
     159                return NT_STATUS_INTERNAL_ERROR;
     160        }
     161
     162        p = resp->extra_data.data;
     163
     164        for (i=0; i<count; i++) {
     165                struct unixid *id = &ids[i].xid;
     166                char *q;
     167
     168                switch (p[0]) {
     169                case 'U':
     170                        id->type = ID_TYPE_UID;
     171                        id->id = strtoul(p+1, &q, 10);
     172                        break;
     173                case 'G':
     174                        id->type = ID_TYPE_GID;
     175                        id->id = strtoul(p+1, &q, 10);
     176                        break;
     177                case 'B':
     178                        id->type = ID_TYPE_BOTH;
     179                        id->id = strtoul(p+1, &q, 10);
     180                        break;
     181                default:
     182                        id->type = ID_TYPE_NOT_SPECIFIED;
     183                        id->id = UINT32_MAX;
     184                        q = strchr(p, '\n');
     185                        break;
     186                };
     187                ids[i].status = ID_MAPPED;
     188
     189                if (q == NULL || q[0] != '\n') {
     190                        TALLOC_FREE(mem_ctx);
     191                        return NT_STATUS_INTERNAL_ERROR;
     192                }
     193                p = q+1;
     194        }
     195
     196        return NT_STATUS_OK;
     197}
     198
     199struct wbc_id_to_sid_state {
     200        struct winbindd_request wbreq;
     201        struct dom_sid sid;
     202};
     203
     204static void wbc_id_to_sid_done(struct tevent_req *subreq);
     205
     206static struct tevent_req *wbc_id_to_sid_send(TALLOC_CTX *mem_ctx,
     207                                             struct tevent_context *ev,
     208                                             int fd, const struct unixid *id)
     209{
     210        struct tevent_req *req, *subreq;
     211        struct wbc_id_to_sid_state *state;
     212
     213        req = tevent_req_create(mem_ctx, &state, struct wbc_id_to_sid_state);
     214        if (req == NULL) {
    49215                return NULL;
    50216        }
    51217
    52         return ctx;
    53 }
    54 
    55 struct wbc_idmap_state {
    56         struct composite_context *ctx;
    57         struct winbind_get_idmap *req;
     218        switch(id->type) {
     219        case ID_TYPE_UID:
     220                state->wbreq.cmd = WINBINDD_UID_TO_SID;
     221                state->wbreq.data.uid = id->id;
     222                break;
     223        case ID_TYPE_GID:
     224                state->wbreq.cmd = WINBINDD_GID_TO_SID;
     225                state->wbreq.data.gid = id->id;
     226                break;
     227        default:
     228                tevent_req_error(req, ENOENT);
     229                return tevent_req_post(req, ev);
     230        }
     231
     232        subreq = wb_simple_trans_send(state, ev, NULL, fd, &state->wbreq);
     233        if (tevent_req_nomem(subreq, req)) {
     234                return tevent_req_post(req, ev);
     235        }
     236        tevent_req_set_callback(subreq, wbc_id_to_sid_done, req);
     237        return req;
     238}
     239
     240static void wbc_id_to_sid_done(struct tevent_req *subreq)
     241{
     242        struct tevent_req *req = tevent_req_callback_data(
     243                subreq, struct tevent_req);
     244        struct wbc_id_to_sid_state *state = tevent_req_data(
     245                req, struct wbc_id_to_sid_state);
     246        struct winbindd_response *wbresp;
     247        int ret, err;
     248
     249        ret = wb_simple_trans_recv(subreq, state, &wbresp, &err);
     250        TALLOC_FREE(subreq);
     251        if (ret == -1) {
     252                tevent_req_error(req, err);
     253                return;
     254        }
     255        if ((wbresp->result != WINBINDD_OK) ||
     256            !dom_sid_parse(wbresp->data.sid.sid, &state->sid)) {
     257                tevent_req_error(req, ENOENT);
     258                return;
     259        }
     260        tevent_req_done(req);
     261}
     262
     263static int wbc_id_to_sid_recv(struct tevent_req *req, struct dom_sid *sid)
     264{
     265        struct wbc_id_to_sid_state *state = tevent_req_data(
     266                req, struct wbc_id_to_sid_state);
     267        int err;
     268
     269        if (tevent_req_is_unix_error(req, &err)) {
     270                return err;
     271        }
     272        sid_copy(sid, &state->sid);
     273        return 0;
     274}
     275
     276struct wbc_ids_to_sids_state {
     277        struct tevent_context *ev;
     278        int fd;
    58279        struct id_map *ids;
     280        uint32_t count;
     281        uint32_t idx;
    59282};
    60283
    61 static void sids_to_xids_recv_ids(struct tevent_req *subreq);
    62 
    63 struct composite_context *wbc_sids_to_xids_send(struct wbc_context *wbc_ctx,
    64                                                 TALLOC_CTX *mem_ctx,
    65                                                 uint32_t count,
    66                                                 struct id_map *ids)
    67 {
    68         struct composite_context *ctx;
    69         struct wbc_idmap_state *state;
    70         struct tevent_req *subreq;
    71 
    72         DEBUG(5, ("wbc_sids_to_xids called\n"));
    73 
    74         ctx = composite_create(mem_ctx, wbc_ctx->event_ctx);
    75         if (ctx == NULL) return NULL;
    76 
    77         state = talloc(ctx, struct wbc_idmap_state);
    78         if (composite_nomem(state, ctx)) return ctx;
    79         ctx->private_data = state;
    80 
    81         state->req = talloc(state, struct winbind_get_idmap);
    82         if (composite_nomem(state->req, ctx)) return ctx;
    83 
    84         state->req->in.count = count;
    85         state->req->in.level = WINBIND_IDMAP_LEVEL_SIDS_TO_XIDS;
    86         state->req->in.ids = ids;
    87         state->ctx = ctx;
    88 
    89         subreq = dcerpc_winbind_get_idmap_r_send(state,
    90                                                  wbc_ctx->event_ctx,
    91                                                  wbc_ctx->irpc_handle,
    92                                                  state->req);
    93         if (composite_nomem(subreq, ctx)) return ctx;
    94 
    95         tevent_req_set_callback(subreq, sids_to_xids_recv_ids, state);
    96 
    97         return ctx;
    98 }
    99 
    100 static void sids_to_xids_recv_ids(struct tevent_req *subreq)
    101 {
    102         struct wbc_idmap_state *state =
    103                 tevent_req_callback_data(subreq,
    104                 struct wbc_idmap_state);
    105 
    106         state->ctx->status = dcerpc_winbind_get_idmap_r_recv(subreq, state);
     284static void wbc_ids_to_sids_done(struct tevent_req *subreq);
     285
     286static struct tevent_req *wbc_ids_to_sids_send(
     287        TALLOC_CTX *mem_ctx, struct tevent_context *ev,
     288        int fd, struct id_map *ids, uint32_t count)
     289{
     290        struct tevent_req *req, *subreq;
     291        struct wbc_ids_to_sids_state *state;
     292
     293        req = tevent_req_create(mem_ctx, &state,
     294                                struct wbc_ids_to_sids_state);
     295        if (req == NULL) {
     296                return NULL;
     297        }
     298        state->ev = ev;
     299        state->fd = fd;
     300        state->ids = ids;
     301        state->count = count;
     302
     303        if (count == 0) {
     304                tevent_req_done(req);
     305                return tevent_req_post(req, ev);
     306        }
     307
     308        subreq = wbc_id_to_sid_send(state, state->ev, state->fd,
     309                                    &state->ids[state->idx].xid);
     310        if (tevent_req_nomem(subreq, req)) {
     311                return tevent_req_post(req, ev);
     312        }
     313        tevent_req_set_callback(subreq, wbc_ids_to_sids_done, req);
     314        return req;
     315}
     316
     317static void wbc_ids_to_sids_done(struct tevent_req *subreq)
     318{
     319        struct tevent_req *req = tevent_req_callback_data(
     320                subreq, struct tevent_req);
     321        struct wbc_ids_to_sids_state *state = tevent_req_data(
     322                req, struct wbc_ids_to_sids_state);
     323        struct id_map *id;
     324        struct dom_sid sid;
     325        int ret;
     326
     327        ret = wbc_id_to_sid_recv(subreq, &sid);
    107328        TALLOC_FREE(subreq);
    108         if (!composite_is_ok(state->ctx)) return;
    109 
    110         state->ids = state->req->out.ids;
    111         composite_done(state->ctx);
    112 }
    113 
    114 NTSTATUS wbc_sids_to_xids_recv(struct composite_context *ctx,
    115                                struct id_map **ids)
    116 {
    117         NTSTATUS status = composite_wait(ctx);
    118                 DEBUG(5, ("wbc_sids_to_xids_recv called\n"));
    119         if (NT_STATUS_IS_OK(status)) {
    120                 struct wbc_idmap_state *state = talloc_get_type_abort(
    121                                                         ctx->private_data,
    122                                                         struct wbc_idmap_state);
    123                 *ids = state->ids;
    124         }
    125 
     329
     330        id = &state->ids[state->idx];
     331        if (ret == 0) {
     332                id->status = ID_MAPPED;
     333                id->sid = dom_sid_dup(state->ids, &sid);
     334                if (id->sid == NULL) {
     335                        tevent_req_error(req, ENOMEM);
     336                        return;
     337                }
     338        } else {
     339                id->status = ID_UNMAPPED;
     340                id->sid = NULL;
     341        }
     342
     343        state->idx += 1;
     344        if (state->idx == state->count) {
     345                tevent_req_done(req);
     346                return;
     347        }
     348
     349        subreq = wbc_id_to_sid_send(state, state->ev, state->fd,
     350                                    &state->ids[state->idx].xid);
     351        if (tevent_req_nomem(subreq, req)) {
     352                return;
     353        }
     354        tevent_req_set_callback(subreq, wbc_ids_to_sids_done, req);
     355}
     356
     357static int wbc_ids_to_sids_recv(struct tevent_req *req)
     358{
     359        int err;
     360        if (tevent_req_is_unix_error(req, &err)) {
     361                return err;
     362        }
     363        return 0;
     364}
     365
     366NTSTATUS wbc_xids_to_sids(struct tevent_context *ev, struct id_map *ids,
     367                          uint32_t count)
     368{
     369        struct tevent_req *req;
     370        NTSTATUS status;
     371        bool polled;
     372        int ret, fd;
     373
     374        DEBUG(5, ("wbc_xids_to_sids called: %u ids\n", (unsigned)count));
     375
     376        fd = winbindd_pipe_sock();
     377        if (fd == -1) {
     378                status = map_nt_error_from_unix_common(errno);
     379                DEBUG(10, ("winbindd_pipe_sock returned %s\n",
     380                           strerror(errno)));
     381                return status;
     382        }
     383
     384        req = wbc_ids_to_sids_send(ev, ev, fd, ids, count);
     385        if (req == NULL) {
     386                status = NT_STATUS_NO_MEMORY;
     387                goto done;
     388        }
     389
     390        polled = tevent_req_poll(req, ev);
     391        if (!polled) {
     392                status = map_nt_error_from_unix_common(errno);
     393                DEBUG(10, ("tevent_req_poll returned %s\n",
     394                           strerror(errno)));
     395                goto done;
     396        }
     397
     398        ret = wbc_ids_to_sids_recv(req);
     399        TALLOC_FREE(req);
     400        if (ret != 0) {
     401                status = map_nt_error_from_unix_common(ret);
     402                DEBUG(10, ("tevent_req_poll returned %s\n",
     403                           strerror(ret)));
     404        } else {
     405                status = NT_STATUS_OK;
     406        }
     407
     408done:
     409        close(fd);
    126410        return status;
    127411}
    128 
    129 static void xids_to_sids_recv_ids(struct tevent_req *subreq);
    130 
    131 struct composite_context *wbc_xids_to_sids_send(struct wbc_context *wbc_ctx,
    132                                                 TALLOC_CTX *mem_ctx,
    133                                                 uint32_t count,
    134                                                 struct id_map *ids)
    135 {
    136         struct composite_context *ctx;
    137         struct wbc_idmap_state *state;
    138         struct tevent_req *subreq;
    139 
    140         DEBUG(5, ("wbc_xids_to_sids called\n"));
    141 
    142         ctx = composite_create(mem_ctx, wbc_ctx->event_ctx);
    143         if (ctx == NULL) return NULL;
    144 
    145         state = talloc(ctx, struct wbc_idmap_state);
    146         if (composite_nomem(state, ctx)) return ctx;
    147         ctx->private_data = state;
    148 
    149         state->req = talloc(state, struct winbind_get_idmap);
    150         if (composite_nomem(state->req, ctx)) return ctx;
    151 
    152         state->req->in.count = count;
    153         state->req->in.level = WINBIND_IDMAP_LEVEL_XIDS_TO_SIDS;
    154         state->req->in.ids = ids;
    155         state->ctx = ctx;
    156 
    157         subreq = dcerpc_winbind_get_idmap_r_send(state,
    158                                                  wbc_ctx->event_ctx,
    159                                                  wbc_ctx->irpc_handle,
    160                                                  state->req);
    161         if (composite_nomem(subreq, ctx)) return ctx;
    162 
    163         tevent_req_set_callback(subreq, xids_to_sids_recv_ids, state);
    164 
    165         return ctx;
    166 }
    167 
    168 static void xids_to_sids_recv_ids(struct tevent_req *subreq)
    169 {
    170         struct wbc_idmap_state *state =
    171                 tevent_req_callback_data(subreq,
    172                 struct wbc_idmap_state);
    173 
    174         state->ctx->status = dcerpc_winbind_get_idmap_r_recv(subreq, state);
    175         TALLOC_FREE(subreq);
    176         if (!composite_is_ok(state->ctx)) return;
    177 
    178         state->ids = state->req->out.ids;
    179         composite_done(state->ctx);
    180 }
    181 
    182 NTSTATUS wbc_xids_to_sids_recv(struct composite_context *ctx,
    183                                struct id_map **ids)
    184 {
    185         NTSTATUS status = composite_wait(ctx);
    186                 DEBUG(5, ("wbc_xids_to_sids_recv called\n"));
    187         if (NT_STATUS_IS_OK(status)) {
    188                 struct wbc_idmap_state *state = talloc_get_type_abort(
    189                                                         ctx->private_data,
    190                                                         struct wbc_idmap_state);
    191                 *ids = state->ids;
    192         }
    193 
    194         return status;
    195 }
    196 
  • vendor/current/source4/libcli/wbclient/wbclient.h

    r740 r988  
    1919   along with this program.  If not, see <http://www.gnu.org/licenses/>.
    2020*/
    21 #include "lib/messaging/irpc.h"
    22 #include "libcli/composite/composite.h"
    23 #include "librpc/gen_ndr/ndr_winbind_c.h"
     21#include "librpc/gen_ndr/idmap.h"
    2422
    25 struct wbc_context {
    26         struct tevent_context *event_ctx;
    27         struct dcerpc_binding_handle *irpc_handle;
    28 };
     23NTSTATUS wbc_sids_to_xids(struct tevent_context *ev, struct id_map *ids,
     24                          uint32_t count);
    2925
    30 struct wbc_context *wbc_init(TALLOC_CTX *mem_ctx,
    31                              struct messaging_context *msg_ctx,
    32                              struct tevent_context *event_ctx);
    33 
    34 struct composite_context *wbc_sids_to_xids_send(struct wbc_context *wbc_ctx,
    35                                                 TALLOC_CTX *mem_ctx,
    36                                                 uint32_t count,
    37                                                 struct id_map *ids);
    38 
    39 NTSTATUS wbc_sids_to_xids_recv(struct composite_context *ctx,
    40                                struct id_map **ids);
    41 
    42 struct composite_context *wbc_xids_to_sids_send(struct wbc_context *wbc_ctx,
    43                                                 TALLOC_CTX *mem_ctx,
    44                                                 uint32_t count,
    45                                                 struct id_map *ids);
    46 
    47 NTSTATUS wbc_xids_to_sids_recv(struct composite_context *ctx,
    48                                struct id_map **ids);
    49 
     26NTSTATUS wbc_xids_to_sids(struct tevent_context *ev, struct id_map *ids,
     27                          uint32_t count);
  • vendor/current/source4/libcli/wbclient/wscript_build

    r740 r988  
    11#!/usr/bin/env python
    22
    3 bld.SAMBA_SUBSYSTEM('LIBWBCLIENT_OLD',
    4         source='wbclient.c',
    5         public_deps='errors events',
    6         deps='NDR_WINBIND MESSAGING RPC_NDR_WINBIND'
     3bld.SAMBA_LIBRARY('LIBWBCLIENT_OLD',
     4                  source='wbclient.c',
     5                  public_deps='samba-errors events',
     6                  cflags='-DWINBINDD_SOCKET_DIR=\"%s\"' % bld.env.WINBINDD_SOCKET_DIR,
     7                  deps='WB_REQTRANS NDR_WINBIND MESSAGING RPC_NDR_WINBIND',
     8                  private_library=True
    79        )
    810
  • vendor/current/source4/libcli/wrepl/winsrepl.c

    r740 r988  
    137137{
    138138        struct interface *ifaces;
    139         load_interfaces(lp_ctx, lpcfg_interfaces(lp_ctx), &ifaces);
    140         return iface_best_ip(ifaces, peer_ip);
     139        load_interface_list(lp_ctx, lp_ctx, &ifaces);
     140        return iface_list_best_ip(ifaces, peer_ip);
    141141}
    142142
     
    182182                                                &state->local_address);
    183183        if (ret != 0) {
    184                 NTSTATUS status = map_nt_error_from_unix(errno);
     184                NTSTATUS status = map_nt_error_from_unix_common(errno);
    185185                tevent_req_nterror(req, status);
    186186                return tevent_req_post(req, ev);
     
    191191                                                &state->remote_address);
    192192        if (ret != 0) {
    193                 NTSTATUS status = map_nt_error_from_unix(errno);
     193                NTSTATUS status = map_nt_error_from_unix_common(errno);
    194194                tevent_req_nterror(req, status);
    195195                return tevent_req_post(req, ev);
     
    202202                              NULL);
    203203        if (!ok) {
    204                 tevent_req_nomem(NULL, req);
     204                tevent_req_oom(req);
    205205                return tevent_req_post(req, ev);
    206206        }
     
    251251                                            state, &state->stream, NULL);
    252252        if (ret != 0) {
    253                 NTSTATUS status = map_nt_error_from_unix(sys_errno);
     253                NTSTATUS status = map_nt_error_from_unix_common(sys_errno);
    254254                tevent_req_nterror(req, status);
    255255                return;
     
    360360
    361361        if (wrepl_socket->stream == NULL) {
    362                 tevent_req_nterror(req, NT_STATUS_INVALID_CONNECTION);
     362                tevent_req_nterror(req, NT_STATUS_CONNECTION_DISCONNECTED);
    363363                return tevent_req_post(req, ev);
    364364        }
     
    383383                              NULL);
    384384        if (!ok) {
    385                 tevent_req_nomem(NULL, req);
     385                tevent_req_oom(req);
    386386                return tevent_req_post(req, ev);
    387387        }
     
    409409
    410410        if (state->caller.wrepl_socket->stream == NULL) {
    411                 tevent_req_nterror(req, NT_STATUS_INVALID_CONNECTION);
     411                tevent_req_nterror(req, NT_STATUS_CONNECTION_DISCONNECTED);
    412412                return;
    413413        }
     
    444444        TALLOC_FREE(subreq);
    445445        if (ret == -1) {
    446                 NTSTATUS status = map_nt_error_from_unix(sys_errno);
     446                NTSTATUS status = map_nt_error_from_unix_common(sys_errno);
    447447                TALLOC_FREE(state->caller.wrepl_socket->stream);
    448448                tevent_req_nterror(req, status);
     
    451451
    452452        if (state->caller.wrepl_socket->stream == NULL) {
    453                 tevent_req_nterror(req, NT_STATUS_INVALID_CONNECTION);
     453                tevent_req_nterror(req, NT_STATUS_CONNECTION_DISCONNECTED);
    454454                return;
    455455        }
     
    495495        TALLOC_FREE(subreq);
    496496        if (ret == -1) {
    497                 NTSTATUS status = map_nt_error_from_unix(sys_errno);
     497                NTSTATUS status = map_nt_error_from_unix_common(sys_errno);
    498498                TALLOC_FREE(state->caller.wrepl_socket->stream);
    499499                tevent_req_nterror(req, status);
  • vendor/current/source4/libcli/wscript_build

    r740 r988  
    44bld.RECURSE('wbclient')
    55
    6 bld.SAMBA_LIBRARY('errors',
    7                   source='../../libcli/util/doserr.c util/errormap.c util/nterr.c',
    8                   public_headers='../../libcli/util/error.h ../../libcli/util/ntstatus.h ../../libcli/util/doserr.h ../../libcli/util/werror.h',
    9                   header_path='core',
    10                   deps='talloc',
    11                   private_library=True
    12                   )
    13 
    14 
    156bld.SAMBA_SUBSYSTEM('LIBSAMBA_TSOCKET',
    167        source='../../libcli/util/tstream.c',
    17         public_deps='LIBTSOCKET UTIL_TEVENT'
     8        public_deps='LIBTSOCKET tevent-util'
    189        )
    1910
     
    2213        source='util/clilsa.c',
    2314        autoproto='util/clilsa.h',
    24         public_deps='RPC_NDR_LSA',
    25         deps='security'
     15        public_deps='RPC_NDR_LSA dcerpc',
     16        deps='samba-security'
    2617        )
    2718
    2819
    29 bld.SAMBA_SUBSYSTEM('LIBCLI_COMPOSITE',
     20bld.SAMBA_SUBSYSTEM('cli_composite',
    3021        source='composite/composite.c',
    3122        autoproto='composite/proto.h',
     
    3627bld.SAMBA_SUBSYSTEM('LIBCLI_SMB_COMPOSITE',
    3728        source='smb_composite/loadfile.c smb_composite/savefile.c smb_composite/connect.c smb_composite/sesssetup.c smb_composite/fetchfile.c smb_composite/appendacl.c smb_composite/fsinfo.c smb_composite/smb2.c',
    38         autoproto='smb_composite/proto.h',
    39         deps='LIBCLI_SMB2',
    40         public_deps='LIBCLI_COMPOSITE credentials gensec LIBCLI_RESOLVE'
     29        deps='LIBCLI_SMB2 tevent-util',
     30        public_deps='cli_composite samba-credentials gensec LIBCLI_RESOLVE tevent',
     31        private_headers='smb_composite/smb_composite.h',
    4132        )
    4233
     34bld.SAMBA_PYTHON('pysmb',
     35    source='pysmb.c',
     36    deps='LIBCLI_SMB_COMPOSITE LIBCLI_SMB2 tevent-util pyparam_util pytalloc-util',
     37        public_deps='cli_composite samba-credentials gensec LIBCLI_RESOLVE tevent param_options',
     38    realname='samba/smb.so'
     39    )
    4340
    4441bld.SAMBA_SUBSYSTEM('LIBCLI_DGRAM',
     
    5956        autoproto='resolve/proto.h',
    6057        deps='roken',
    61         public_deps='NDR_NBT LIBTSOCKET'
     58        public_deps='ndr_nbt LIBTSOCKET'
    6259        )
    6360
    6461
    6562bld.SAMBA_SUBSYSTEM('LP_RESOLVE',
    66         source='resolve/bcast.c resolve/nbtlist.c resolve/wins.c resolve/dns_ex.c resolve/file.c resolve/host.c resolve/resolve_lp.c',
     63        source='resolve/bcast.c resolve/nbtlist.c resolve/wins.c resolve/dns_ex.c resolve/host.c resolve/lmhosts.c resolve/resolve_lp.c',
    6764        autoproto='resolve/lp_proto.h',
    68         deps='cli-nbt samba-hostconfig netif'
     65        deps='cli-nbt samba-hostconfig netif addns'
    6966        )
    7067
    7168
    7269bld.SAMBA_SUBSYSTEM('LIBCLI_FINDDCS',
    73         source='finddcs_nbt.c finddcs_cldap.c',
     70        source='finddcs_cldap.c',
    7471        autoproto='finddcs_proto.h',
    75         public_deps='cli-nbt MESSAGING RPC_NDR_IRPC LIBCLI_CLDAP'
     72        public_deps='cli_cldap'
    7673        )
    7774
     
    7976bld.SAMBA_SUBSYSTEM('LIBCLI_SMB',
    8077        source='clireadwrite.c cliconnect.c clifile.c clilist.c clitrans2.c climessage.c clideltree.c',
    81         autoproto='libcli_proto.h',
    82         public_deps='LIBCLI_RAW errors LIBCLI_AUTH LIBCLI_SMB_COMPOSITE cli-nbt security LIBCLI_RESOLVE LIBCLI_DGRAM LIBCLI_SMB2 LIBCLI_FINDDCS samba_socket'
     78        private_headers='libcli.h:smb_cli.h',
     79        public_deps='smbclient-raw samba-errors LIBCLI_AUTH LIBCLI_SMB_COMPOSITE cli-nbt samba-security LIBCLI_RESOLVE LIBCLI_DGRAM LIBCLI_SMB2 LIBCLI_FINDDCS samba_socket'
    8380        )
    8481
    8582
    86 bld.SAMBA_SUBSYSTEM('LIBCLI_RAW',
     83bld.SAMBA_LIBRARY('smbclient-raw',
    8784        source='raw/rawfile.c raw/smb_signing.c raw/clisocket.c raw/clitransport.c raw/clisession.c raw/clitree.c raw/clierror.c raw/rawrequest.c raw/rawreadwrite.c raw/rawsearch.c raw/rawsetfileinfo.c raw/raweas.c raw/rawtrans.c raw/clioplock.c raw/rawnegotiate.c raw/rawfsinfo.c raw/rawfileinfo.c raw/rawnotify.c raw/rawioctl.c raw/rawacl.c raw/rawdate.c raw/rawlpq.c raw/rawshadow.c',
    8885        autoproto='raw/raw_proto.h',
    8986        public_deps='samba_socket LIBPACKET LIBCRYPTO',
    90         deps='LIBCLI_COMPOSITE LIBCLI_RESOLVE security ndr samba-util errors CHARSET talloc LIBCLI_SMB_COMPOSITE tevent NDR_NBT_BUF LIBCLI_SMB_COMMON'
     87        deps='cli_composite LIBCLI_RESOLVE samba-security ndr samba-util samba-errors charset talloc LIBCLI_SMB_COMPOSITE tevent cli_smb_common',
     88        private_headers='raw/request.h:smb_request.h raw/signing.h:smb_raw_signing.h raw/libcliraw.h:smb_cliraw.h raw/interfaces.h:smb_raw_interfaces.h raw/smb.h:smb_raw.h raw/trans2.h:smb_raw_trans2.h',
     89        private_library=True,
    9190        )
    9291
Note: See TracChangeset for help on using the changeset viewer.