Ignore:
Timestamp:
Nov 14, 2012, 12:59:34 PM (13 years ago)
Author:
Silvan Scherrer
Message:

Samba Server: update vendor to 3.6.0

File:
1 edited

Legend:

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

    r414 r740  
    44   Copyright (C) Andrew Tridgell 1994-1998
    55   Copyright (C) Jeremy Allison 2001-2009
    6    
     6
    77   This program is free software; you can redistribute it and/or modify
    88   it under the terms of the GNU General Public License as published by
    99   the Free Software Foundation; either version 3 of the License, or
    1010   (at your option) any later version.
    11    
     11
    1212   This program is distributed in the hope that it will be useful,
    1313   but WITHOUT ANY WARRANTY; without even the implied warranty of
    1414   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    1515   GNU General Public License for more details.
    16    
     16
    1717   You should have received a copy of the GNU General Public License
    1818   along with this program.  If not, see <http://www.gnu.org/licenses/>.
     
    2020
    2121#include "includes.h"
     22#include "system/filesys.h"
     23#include "libsmb/libsmb.h"
     24#include "../lib/util/tevent_ntstatus.h"
     25#include "async_smb.h"
     26#include "libsmb/clirap.h"
     27#include "trans2.h"
     28#include "ntioctl.h"
    2229
    2330/***********************************************************
     
    9299}
    93100
     101uint8_t *smb_bytes_push_bytes(uint8_t *buf, uint8_t prefix,
     102                              const uint8_t *bytes, size_t num_bytes)
     103{
     104        size_t buflen;
     105
     106        if (buf == NULL) {
     107                return NULL;
     108        }
     109        buflen = talloc_get_size(buf);
     110
     111        buf = TALLOC_REALLOC_ARRAY(NULL, buf, uint8_t,
     112                                   buflen + 1 + num_bytes);
     113        if (buf == NULL) {
     114                return NULL;
     115        }
     116        buf[buflen] = prefix;
     117        memcpy(&buf[buflen+1], bytes, num_bytes);
     118        return buf;
     119}
     120
    94121/***********************************************************
    95122 Same as smb_bytes_push_str(), but without the odd byte
     
    107134}
    108135
     136struct cli_setpathinfo_state {
     137        uint16_t setup;
     138        uint8_t *param;
     139};
     140
     141static void cli_setpathinfo_done(struct tevent_req *subreq);
     142
     143struct tevent_req *cli_setpathinfo_send(TALLOC_CTX *mem_ctx,
     144                                        struct tevent_context *ev,
     145                                        struct cli_state *cli,
     146                                        uint16_t level,
     147                                        const char *path,
     148                                        uint8_t *data,
     149                                        size_t data_len)
     150{
     151        struct tevent_req *req, *subreq;
     152        struct cli_setpathinfo_state *state;
     153
     154        req = tevent_req_create(mem_ctx, &state,
     155                                struct cli_setpathinfo_state);
     156        if (req == NULL) {
     157                return NULL;
     158        }
     159
     160        /* Setup setup word. */
     161        SSVAL(&state->setup, 0, TRANSACT2_SETPATHINFO);
     162
     163        /* Setup param array. */
     164        state->param = TALLOC_ZERO_ARRAY(state, uint8_t, 6);
     165        if (tevent_req_nomem(state->param, req)) {
     166                return tevent_req_post(req, ev);
     167        }
     168        SSVAL(state->param, 0, level);
     169
     170        state->param = trans2_bytes_push_str(
     171                state->param, cli_ucs2(cli), path, strlen(path)+1, NULL);
     172        if (tevent_req_nomem(state->param, req)) {
     173                return tevent_req_post(req, ev);
     174        }
     175
     176        subreq = cli_trans_send(
     177                state,                  /* mem ctx. */
     178                ev,                     /* event ctx. */
     179                cli,                    /* cli_state. */
     180                SMBtrans2,              /* cmd. */
     181                NULL,                   /* pipe name. */
     182                -1,                     /* fid. */
     183                0,                      /* function. */
     184                0,                      /* flags. */
     185                &state->setup,          /* setup. */
     186                1,                      /* num setup uint16_t words. */
     187                0,                      /* max returned setup. */
     188                state->param,           /* param. */
     189                talloc_get_size(state->param),  /* num param. */
     190                2,                      /* max returned param. */
     191                data,                   /* data. */
     192                data_len,               /* num data. */
     193                0);                     /* max returned data. */
     194
     195        if (tevent_req_nomem(subreq, req)) {
     196                return tevent_req_post(req, ev);
     197        }
     198        tevent_req_set_callback(subreq, cli_setpathinfo_done, req);
     199        return req;
     200}
     201
     202static void cli_setpathinfo_done(struct tevent_req *subreq)
     203{
     204        NTSTATUS status = cli_trans_recv(subreq, NULL, NULL, NULL, 0, NULL,
     205                                         NULL, 0, NULL, NULL, 0, NULL);
     206        tevent_req_simple_finish_ntstatus(subreq, status);
     207}
     208
     209NTSTATUS cli_setpathinfo_recv(struct tevent_req *req)
     210{
     211        return tevent_req_simple_recv_ntstatus(req);
     212}
     213
     214NTSTATUS cli_setpathinfo(struct cli_state *cli,
     215                         uint16_t level,
     216                         const char *path,
     217                         uint8_t *data,
     218                         size_t data_len)
     219{
     220        TALLOC_CTX *frame = talloc_stackframe();
     221        struct tevent_context *ev;
     222        struct tevent_req *req;
     223        NTSTATUS status = NT_STATUS_NO_MEMORY;
     224
     225        if (cli_has_async_calls(cli)) {
     226                /*
     227                 * Can't use sync call while an async call is in flight
     228                 */
     229                status = NT_STATUS_INVALID_PARAMETER;
     230                goto fail;
     231        }
     232        ev = tevent_context_init(frame);
     233        if (ev == NULL) {
     234                goto fail;
     235        }
     236        req = cli_setpathinfo_send(ev, ev, cli, level, path, data, data_len);
     237        if (req == NULL) {
     238                goto fail;
     239        }
     240        if (!tevent_req_poll_ntstatus(req, ev, &status)) {
     241                goto fail;
     242        }
     243        status = cli_setpathinfo_recv(req);
     244 fail:
     245        TALLOC_FREE(frame);
     246        return status;
     247}
     248
    109249/****************************************************************************
    110250 Hard/Symlink a file (UNIX extensions).
     
    112252****************************************************************************/
    113253
    114 struct link_state {
    115         uint16_t setup;
    116         uint8_t *param;
     254struct cli_posix_link_internal_state {
    117255        uint8_t *data;
    118256};
    119257
    120 static void cli_posix_link_internal_done(struct tevent_req *subreq)
    121 {
    122         struct tevent_req *req = tevent_req_callback_data(
    123                                 subreq, struct tevent_req);
    124         struct link_state *state = tevent_req_data(req, struct link_state);
    125         NTSTATUS status;
    126 
    127         status = cli_trans_recv(subreq, state, NULL, NULL, NULL, NULL, NULL, NULL);
    128         TALLOC_FREE(subreq);
    129         if (!NT_STATUS_IS_OK(status)) {
    130                 tevent_req_nterror(req, status);
    131                 return;
    132         }
    133         tevent_req_done(req);
    134 }
     258static void cli_posix_link_internal_done(struct tevent_req *subreq);
    135259
    136260static struct tevent_req *cli_posix_link_internal_send(TALLOC_CTX *mem_ctx,
    137261                                        struct event_context *ev,
    138262                                        struct cli_state *cli,
     263                                        uint16_t level,
    139264                                        const char *oldname,
    140                                         const char *newname,
    141                                         bool hardlink)
     265                                        const char *newname)
    142266{
    143267        struct tevent_req *req = NULL, *subreq = NULL;
    144         struct link_state *state = NULL;
    145 
    146         req = tevent_req_create(mem_ctx, &state, struct link_state);
     268        struct cli_posix_link_internal_state *state = NULL;
     269
     270        req = tevent_req_create(mem_ctx, &state,
     271                                struct cli_posix_link_internal_state);
    147272        if (req == NULL) {
    148273                return NULL;
    149         }
    150 
    151         /* Setup setup word. */
    152         SSVAL(&state->setup, 0, TRANSACT2_SETPATHINFO);
    153 
    154         /* Setup param array. */
    155         state->param = talloc_array(state, uint8_t, 6);
    156         if (tevent_req_nomem(state->param, req)) {
    157                 return tevent_req_post(req, ev);
    158         }
    159         memset(state->param, '\0', 6);
    160         SSVAL(state->param,0,hardlink ? SMB_SET_FILE_UNIX_HLINK : SMB_SET_FILE_UNIX_LINK);
    161 
    162         state->param = trans2_bytes_push_str(state->param, cli_ucs2(cli), newname,
    163                                    strlen(newname)+1, NULL);
    164 
    165         if (tevent_req_nomem(state->param, req)) {
    166                 return tevent_req_post(req, ev);
    167274        }
    168275
     
    172279                return tevent_req_post(req, ev);
    173280        }
    174         state->data = trans2_bytes_push_str(state->data, cli_ucs2(cli), oldname,
    175                                    strlen(oldname)+1, NULL);
    176 
    177         subreq = cli_trans_send(state,                  /* mem ctx. */
    178                                 ev,                     /* event ctx. */
    179                                 cli,                    /* cli_state. */
    180                                 SMBtrans2,              /* cmd. */
    181                                 NULL,                   /* pipe name. */
    182                                 -1,                     /* fid. */
    183                                 0,                      /* function. */
    184                                 0,                      /* flags. */
    185                                 &state->setup,          /* setup. */
    186                                 1,                      /* num setup uint16_t words. */
    187                                 0,                      /* max returned setup. */
    188                                 state->param,           /* param. */
    189                                 talloc_get_size(state->param),  /* num param. */
    190                                 2,                      /* max returned param. */
    191                                 state->data,            /* data. */
    192                                 talloc_get_size(state->data),   /* num data. */
    193                                 0);                     /* max returned data. */
    194 
     281        state->data = trans2_bytes_push_str(
     282                state->data, cli_ucs2(cli), oldname, strlen(oldname)+1, NULL);
     283
     284        subreq = cli_setpathinfo_send(
     285                state, ev, cli, level, newname,
     286                state->data, talloc_get_size(state->data));
    195287        if (tevent_req_nomem(subreq, req)) {
    196288                return tevent_req_post(req, ev);
     
    198290        tevent_req_set_callback(subreq, cli_posix_link_internal_done, req);
    199291        return req;
     292}
     293
     294static void cli_posix_link_internal_done(struct tevent_req *subreq)
     295{
     296        NTSTATUS status = cli_setpathinfo_recv(subreq);
     297        tevent_req_simple_finish_ntstatus(subreq, status);
    200298}
    201299
     
    210308                                        const char *newname)
    211309{
    212         return cli_posix_link_internal_send(mem_ctx, ev, cli,
    213                         oldname, newname, false);
     310        return cli_posix_link_internal_send(
     311                mem_ctx, ev, cli, SMB_SET_FILE_UNIX_LINK, oldname, newname);
    214312}
    215313
    216314NTSTATUS cli_posix_symlink_recv(struct tevent_req *req)
    217315{
    218         NTSTATUS status;
    219 
    220         if (tevent_req_is_nterror(req, &status)) {
    221                 return status;
    222         }
    223         return NT_STATUS_OK;
     316        return tevent_req_simple_recv_ntstatus(req);
    224317}
    225318
     
    277370
    278371struct readlink_state {
    279         uint16_t setup;
    280         uint8_t *param;
    281372        uint8_t *data;
    282373        uint32_t num_data;
    283374};
    284375
    285 static void cli_posix_readlink_done(struct tevent_req *subreq)
    286 {
    287         struct tevent_req *req = tevent_req_callback_data(
    288                                 subreq, struct tevent_req);
    289         struct readlink_state *state = tevent_req_data(req, struct readlink_state);
    290         NTSTATUS status;
    291 
    292         status = cli_trans_recv(subreq, state, NULL, NULL, NULL, NULL,
    293                         &state->data, &state->num_data);
    294         TALLOC_FREE(subreq);
    295         if (!NT_STATUS_IS_OK(status)) {
    296                 tevent_req_nterror(req, status);
    297                 return;
    298         }
    299         if (state->num_data == 0) {
    300                 tevent_req_nterror(req, NT_STATUS_DATA_ERROR);
    301                 return;
    302         }
    303         if (state->data[state->num_data-1] != '\0') {
    304                 tevent_req_nterror(req, NT_STATUS_DATA_ERROR);
    305                 return;
    306         }
    307         tevent_req_done(req);
    308 }
     376static void cli_posix_readlink_done(struct tevent_req *subreq);
    309377
    310378struct tevent_req *cli_posix_readlink_send(TALLOC_CTX *mem_ctx,
     
    318386        uint32_t maxbytelen = (uint32_t)(cli_ucs2(cli) ? len*3 : len);
    319387
    320         if (maxbytelen < len) {
     388        req = tevent_req_create(mem_ctx, &state, struct readlink_state);
     389        if (req == NULL) {
    321390                return NULL;
    322391        }
    323392
    324         req = tevent_req_create(mem_ctx, &state, struct readlink_state);
    325         if (req == NULL) {
    326                 return NULL;
    327         }
    328 
    329         /* Setup setup word. */
    330         SSVAL(&state->setup, 0, TRANSACT2_QPATHINFO);
    331 
    332         /* Setup param array. */
    333         state->param = talloc_array(state, uint8_t, 6);
    334         if (tevent_req_nomem(state->param, req)) {
    335                 return tevent_req_post(req, ev);
    336         }
    337         memset(state->param, '\0', 6);
    338         SSVAL(state->param,0,SMB_QUERY_FILE_UNIX_LINK);
    339 
    340         state->param = trans2_bytes_push_str(state->param, cli_ucs2(cli), fname,
    341                                    strlen(fname)+1, NULL);
    342 
    343         if (tevent_req_nomem(state->param, req)) {
    344                 return tevent_req_post(req, ev);
    345         }
    346 
    347         subreq = cli_trans_send(state,                  /* mem ctx. */
    348                                 ev,                     /* event ctx. */
    349                                 cli,                    /* cli_state. */
    350                                 SMBtrans2,              /* cmd. */
    351                                 NULL,                   /* pipe name. */
    352                                 -1,                     /* fid. */
    353                                 0,                      /* function. */
    354                                 0,                      /* flags. */
    355                                 &state->setup,          /* setup. */
    356                                 1,                      /* num setup uint16_t words. */
    357                                 0,                      /* max returned setup. */
    358                                 state->param,           /* param. */
    359                                 talloc_get_size(state->param),  /* num param. */
    360                                 2,                      /* max returned param. */
    361                                 NULL,                   /* data. */
    362                                 0,                      /* num data. */
    363                                 maxbytelen);            /* max returned data. */
    364 
     393        /*
     394         * Len is in bytes, we need it in UCS2 units.
     395         */
     396        if ((2*len < len) || (maxbytelen < len)) {
     397                tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
     398                return tevent_req_post(req, ev);
     399        }
     400
     401        subreq = cli_qpathinfo_send(state, ev, cli, fname,
     402                                    SMB_QUERY_FILE_UNIX_LINK, 1, maxbytelen);
    365403        if (tevent_req_nomem(subreq, req)) {
    366404                return tevent_req_post(req, ev);
     
    368406        tevent_req_set_callback(subreq, cli_posix_readlink_done, req);
    369407        return req;
     408}
     409
     410static void cli_posix_readlink_done(struct tevent_req *subreq)
     411{
     412        struct tevent_req *req = tevent_req_callback_data(
     413                subreq, struct tevent_req);
     414        struct readlink_state *state = tevent_req_data(
     415                req, struct readlink_state);
     416        NTSTATUS status;
     417
     418        status = cli_qpathinfo_recv(subreq, state, &state->data,
     419                                    &state->num_data);
     420        TALLOC_FREE(subreq);
     421        if (tevent_req_nterror(req, status)) {
     422                return;
     423        }
     424        /*
     425         * num_data is > 1, we've given 1 as minimum to cli_qpathinfo_send
     426         */
     427        if (state->data[state->num_data-1] != '\0') {
     428                tevent_req_nterror(req, NT_STATUS_DATA_ERROR);
     429                return;
     430        }
     431        tevent_req_done(req);
    370432}
    371433
     
    423485        }
    424486
    425         /* Len is in bytes, we need it in UCS2 units. */
    426         if (2*len < len) {
    427                 status = NT_STATUS_INVALID_PARAMETER;
    428                 goto fail;
    429         }
    430 
    431487        req = cli_posix_readlink_send(frame,
    432488                                ev,
     
    464520                                        const char *newname)
    465521{
    466         return cli_posix_link_internal_send(mem_ctx, ev, cli,
    467                         oldname, newname, true);
     522        return cli_posix_link_internal_send(
     523                mem_ctx, ev, cli, SMB_SET_FILE_UNIX_HLINK, oldname, newname);
    468524}
    469525
    470526NTSTATUS cli_posix_hardlink_recv(struct tevent_req *req)
    471527{
    472         NTSTATUS status;
    473 
    474         if (tevent_req_is_nterror(req, &status)) {
    475                 return status;
    476         }
    477         return NT_STATUS_OK;
     528        return tevent_req_simple_recv_ntstatus(req);
    478529}
    479530
     
    625676
    626677struct getfacl_state {
    627         uint16_t setup;
    628         uint8_t *param;
    629678        uint32_t num_data;
    630679        uint8_t *data;
    631680};
    632681
    633 static void cli_posix_getfacl_done(struct tevent_req *subreq)
    634 {
    635         struct tevent_req *req = tevent_req_callback_data(
    636                                 subreq, struct tevent_req);
    637         struct getfacl_state *state = tevent_req_data(req, struct getfacl_state);
    638         NTSTATUS status;
    639 
    640         status = cli_trans_recv(subreq, state, NULL, NULL, NULL, NULL,
    641                         &state->data, &state->num_data);
    642         TALLOC_FREE(subreq);
    643         if (!NT_STATUS_IS_OK(status)) {
    644                 tevent_req_nterror(req, status);
    645                 return;
    646         }
    647         tevent_req_done(req);
    648 }
     682static void cli_posix_getfacl_done(struct tevent_req *subreq);
    649683
    650684struct tevent_req *cli_posix_getfacl_send(TALLOC_CTX *mem_ctx,
     
    654688{
    655689        struct tevent_req *req = NULL, *subreq = NULL;
    656         struct link_state *state = NULL;
     690        struct getfacl_state *state = NULL;
    657691
    658692        req = tevent_req_create(mem_ctx, &state, struct getfacl_state);
     
    660694                return NULL;
    661695        }
    662 
    663         /* Setup setup word. */
    664         SSVAL(&state->setup, 0, TRANSACT2_QPATHINFO);
    665 
    666         /* Setup param array. */
    667         state->param = talloc_array(state, uint8_t, 6);
    668         if (tevent_req_nomem(state->param, req)) {
    669                 return tevent_req_post(req, ev);
    670         }
    671         memset(state->param, '\0', 6);
    672         SSVAL(state->param, 0, SMB_QUERY_POSIX_ACL);
    673 
    674         state->param = trans2_bytes_push_str(state->param, cli_ucs2(cli), fname,
    675                                    strlen(fname)+1, NULL);
    676 
    677         if (tevent_req_nomem(state->param, req)) {
    678                 return tevent_req_post(req, ev);
    679         }
    680 
    681         subreq = cli_trans_send(state,                  /* mem ctx. */
    682                                 ev,                     /* event ctx. */
    683                                 cli,                    /* cli_state. */
    684                                 SMBtrans2,              /* cmd. */
    685                                 NULL,                   /* pipe name. */
    686                                 -1,                     /* fid. */
    687                                 0,                      /* function. */
    688                                 0,                      /* flags. */
    689                                 &state->setup,          /* setup. */
    690                                 1,                      /* num setup uint16_t words. */
    691                                 0,                      /* max returned setup. */
    692                                 state->param,           /* param. */
    693                                 talloc_get_size(state->param),  /* num param. */
    694                                 2,                      /* max returned param. */
    695                                 NULL,                   /* data. */
    696                                 0,                      /* num data. */
    697                                 cli->max_xmit);         /* max returned data. */
    698 
     696        subreq = cli_qpathinfo_send(state, ev, cli, fname, SMB_QUERY_POSIX_ACL,
     697                                    0, cli->max_xmit);
    699698        if (tevent_req_nomem(subreq, req)) {
    700699                return tevent_req_post(req, ev);
     
    702701        tevent_req_set_callback(subreq, cli_posix_getfacl_done, req);
    703702        return req;
     703}
     704
     705static void cli_posix_getfacl_done(struct tevent_req *subreq)
     706{
     707        struct tevent_req *req = tevent_req_callback_data(
     708                subreq, struct tevent_req);
     709        struct getfacl_state *state = tevent_req_data(
     710                req, struct getfacl_state);
     711        NTSTATUS status;
     712
     713        status = cli_qpathinfo_recv(subreq, state, &state->data,
     714                                    &state->num_data);
     715        TALLOC_FREE(subreq);
     716        if (tevent_req_nterror(req, status)) {
     717                return;
     718        }
     719        tevent_req_done(req);
    704720}
    705721
     
    774790
    775791struct stat_state {
    776         uint16_t setup;
    777         uint8_t *param;
    778792        uint32_t num_data;
    779793        uint8_t *data;
    780794};
     795
     796static void cli_posix_stat_done(struct tevent_req *subreq);
     797
     798struct tevent_req *cli_posix_stat_send(TALLOC_CTX *mem_ctx,
     799                                        struct event_context *ev,
     800                                        struct cli_state *cli,
     801                                        const char *fname)
     802{
     803        struct tevent_req *req = NULL, *subreq = NULL;
     804        struct stat_state *state = NULL;
     805
     806        req = tevent_req_create(mem_ctx, &state, struct stat_state);
     807        if (req == NULL) {
     808                return NULL;
     809        }
     810        subreq = cli_qpathinfo_send(state, ev, cli, fname,
     811                                    SMB_QUERY_FILE_UNIX_BASIC, 100, 100);
     812        if (tevent_req_nomem(subreq, req)) {
     813                return tevent_req_post(req, ev);
     814        }
     815        tevent_req_set_callback(subreq, cli_posix_stat_done, req);
     816        return req;
     817}
    781818
    782819static void cli_posix_stat_done(struct tevent_req *subreq)
     
    787824        NTSTATUS status;
    788825
    789         status = cli_trans_recv(subreq, state, NULL, NULL, NULL, NULL,
    790                         &state->data, &state->num_data);
     826        status = cli_qpathinfo_recv(subreq, state, &state->data,
     827                                    &state->num_data);
    791828        TALLOC_FREE(subreq);
    792         if (!NT_STATUS_IS_OK(status)) {
    793                 tevent_req_nterror(req, status);
     829        if (tevent_req_nterror(req, status)) {
    794830                return;
    795831        }
    796832        tevent_req_done(req);
    797 }
    798 
    799 struct tevent_req *cli_posix_stat_send(TALLOC_CTX *mem_ctx,
    800                                         struct event_context *ev,
    801                                         struct cli_state *cli,
    802                                         const char *fname)
    803 {
    804         struct tevent_req *req = NULL, *subreq = NULL;
    805         struct stat_state *state = NULL;
    806 
    807         req = tevent_req_create(mem_ctx, &state, struct stat_state);
    808         if (req == NULL) {
    809                 return NULL;
    810         }
    811 
    812         /* Setup setup word. */
    813         SSVAL(&state->setup, 0, TRANSACT2_QPATHINFO);
    814 
    815         /* Setup param array. */
    816         state->param = talloc_array(state, uint8_t, 6);
    817         if (tevent_req_nomem(state->param, req)) {
    818                 return tevent_req_post(req, ev);
    819         }
    820         memset(state->param, '\0', 6);
    821         SSVAL(state->param, 0, SMB_QUERY_FILE_UNIX_BASIC);
    822 
    823         state->param = trans2_bytes_push_str(state->param, cli_ucs2(cli), fname,
    824                                    strlen(fname)+1, NULL);
    825 
    826         if (tevent_req_nomem(state->param, req)) {
    827                 return tevent_req_post(req, ev);
    828         }
    829 
    830         subreq = cli_trans_send(state,                  /* mem ctx. */
    831                                 ev,                     /* event ctx. */
    832                                 cli,                    /* cli_state. */
    833                                 SMBtrans2,              /* cmd. */
    834                                 NULL,                   /* pipe name. */
    835                                 -1,                     /* fid. */
    836                                 0,                      /* function. */
    837                                 0,                      /* flags. */
    838                                 &state->setup,          /* setup. */
    839                                 1,                      /* num setup uint16_t words. */
    840                                 0,                      /* max returned setup. */
    841                                 state->param,           /* param. */
    842                                 talloc_get_size(state->param),  /* num param. */
    843                                 2,                      /* max returned param. */
    844                                 NULL,                   /* data. */
    845                                 0,                      /* num data. */
    846                                 96);                    /* max returned data. */
    847 
    848         if (tevent_req_nomem(subreq, req)) {
    849                 return tevent_req_post(req, ev);
    850         }
    851         tevent_req_set_callback(subreq, cli_posix_stat_done, req);
    852         return req;
    853833}
    854834
     
    861841        if (tevent_req_is_nterror(req, &status)) {
    862842                return status;
    863         }
    864 
    865         if (state->num_data != 96) {
    866                 return NT_STATUS_DATA_ERROR;
    867843        }
    868844
     
    891867        sbuf->st_ex_ino = (SMB_INO_T)IVAL2_TO_SMB_BIG_UINT(state->data,76);      /* inode */
    892868        sbuf->st_ex_mode |= wire_perms_to_unix(IVAL(state->data,84));     /* protection */
    893         sbuf->st_ex_nlink = IVAL(state->data,92);    /* number of hard links */
     869        sbuf->st_ex_nlink = BIG_UINT(state->data,92); /* number of hard links */
    894870
    895871        return NT_STATUS_OK;
     
    947923****************************************************************************/
    948924
    949 struct ch_state {
    950         uint16_t setup;
    951         uint8_t *param;
    952         uint8_t *data;
     925struct cli_posix_chown_chmod_internal_state {
     926        uint8_t data[100];
    953927};
    954928
    955 static void cli_posix_chown_chmod_internal_done(struct tevent_req *subreq)
    956 {
    957         struct tevent_req *req = tevent_req_callback_data(
    958                                 subreq, struct tevent_req);
    959         struct ch_state *state = tevent_req_data(req, struct ch_state);
    960         NTSTATUS status;
    961 
    962         status = cli_trans_recv(subreq, state, NULL, NULL, NULL, NULL, NULL, NULL);
    963         TALLOC_FREE(subreq);
    964         if (!NT_STATUS_IS_OK(status)) {
    965                 tevent_req_nterror(req, status);
    966                 return;
    967         }
    968         tevent_req_done(req);
    969 }
     929static void cli_posix_chown_chmod_internal_done(struct tevent_req *subreq);
    970930
    971931static struct tevent_req *cli_posix_chown_chmod_internal_send(TALLOC_CTX *mem_ctx,
     
    978938{
    979939        struct tevent_req *req = NULL, *subreq = NULL;
    980         struct ch_state *state = NULL;
    981 
    982         req = tevent_req_create(mem_ctx, &state, struct ch_state);
     940        struct cli_posix_chown_chmod_internal_state *state = NULL;
     941
     942        req = tevent_req_create(mem_ctx, &state,
     943                                struct cli_posix_chown_chmod_internal_state);
    983944        if (req == NULL) {
    984945                return NULL;
    985946        }
    986947
    987         /* Setup setup word. */
    988         SSVAL(&state->setup, 0, TRANSACT2_SETPATHINFO);
    989 
    990         /* Setup param array. */
    991         state->param = talloc_array(state, uint8_t, 6);
    992         if (tevent_req_nomem(state->param, req)) {
    993                 return tevent_req_post(req, ev);
    994         }
    995         memset(state->param, '\0', 6);
    996         SSVAL(state->param,0,SMB_SET_FILE_UNIX_BASIC);
    997 
    998         state->param = trans2_bytes_push_str(state->param, cli_ucs2(cli), fname,
    999                                    strlen(fname)+1, NULL);
    1000 
    1001         if (tevent_req_nomem(state->param, req)) {
    1002                 return tevent_req_post(req, ev);
    1003         }
    1004 
    1005         /* Setup data array. */
    1006         state->data = talloc_array(state, uint8_t, 100);
    1007         if (tevent_req_nomem(state->data, req)) {
    1008                 return tevent_req_post(req, ev);
    1009         }
    1010948        memset(state->data, 0xff, 40); /* Set all sizes/times to no change. */
    1011949        memset(&state->data[40], '\0', 60);
     
    1014952        SIVAL(state->data,84,mode);
    1015953
    1016         subreq = cli_trans_send(state,                  /* mem ctx. */
    1017                                 ev,                     /* event ctx. */
    1018                                 cli,                    /* cli_state. */
    1019                                 SMBtrans2,              /* cmd. */
    1020                                 NULL,                   /* pipe name. */
    1021                                 -1,                     /* fid. */
    1022                                 0,                      /* function. */
    1023                                 0,                      /* flags. */
    1024                                 &state->setup,          /* setup. */
    1025                                 1,                      /* num setup uint16_t words. */
    1026                                 0,                      /* max returned setup. */
    1027                                 state->param,           /* param. */
    1028                                 talloc_get_size(state->param),  /* num param. */
    1029                                 2,                      /* max returned param. */
    1030                                 state->data,            /* data. */
    1031                                 talloc_get_size(state->data),   /* num data. */
    1032                                 0);                     /* max returned data. */
    1033 
     954        subreq = cli_setpathinfo_send(state, ev, cli, SMB_SET_FILE_UNIX_BASIC,
     955                                      fname, state->data, sizeof(state->data));
    1034956        if (tevent_req_nomem(subreq, req)) {
    1035957                return tevent_req_post(req, ev);
    1036958        }
    1037         tevent_req_set_callback(subreq, cli_posix_chown_chmod_internal_done, req);
     959        tevent_req_set_callback(subreq, cli_posix_chown_chmod_internal_done,
     960                                req);
    1038961        return req;
     962}
     963
     964static void cli_posix_chown_chmod_internal_done(struct tevent_req *subreq)
     965{
     966        NTSTATUS status = cli_setpathinfo_recv(subreq);
     967        tevent_req_simple_finish_ntstatus(subreq, status);
    1039968}
    1040969
     
    1058987NTSTATUS cli_posix_chmod_recv(struct tevent_req *req)
    1059988{
    1060         NTSTATUS status;
    1061 
    1062         if (tevent_req_is_nterror(req, &status)) {
    1063                 return status;
    1064         }
    1065         return NT_STATUS_OK;
     989        return tevent_req_simple_recv_ntstatus(req);
    1066990}
    1067991
     
    11321056NTSTATUS cli_posix_chown_recv(struct tevent_req *req)
    11331057{
    1134         NTSTATUS status;
    1135 
    1136         if (tevent_req_is_nterror(req, &status)) {
    1137                 return status;
    1138         }
    1139         return NT_STATUS_OK;
     1058        return tevent_req_simple_recv_ntstatus(req);
    11401059}
    11411060
     
    12161135        }
    12171136
    1218         SSVAL(state->vwv+0, 0, aSYSTEM | aHIDDEN | aDIR);
     1137        SSVAL(state->vwv+0, 0, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_DIRECTORY);
    12191138
    12201139        bytes = talloc_array(state, uint8_t, 1);
     
    12571176        NTSTATUS status;
    12581177
    1259         status = cli_smb_recv(subreq, 0, NULL, NULL, NULL, NULL);
     1178        status = cli_smb_recv(subreq, NULL, NULL, 0, NULL, NULL, NULL, NULL);
    12601179        TALLOC_FREE(subreq);
    1261         if (!NT_STATUS_IS_OK(status)) {
    1262                 tevent_req_nterror(req, status);
     1180        if (tevent_req_nterror(req, status)) {
    12631181                return;
    12641182        }
     
    13411259        }
    13421260
    1343         SSVAL(state->vwv+0, 0 ,aSYSTEM | aHIDDEN | aDIR);
     1261        SSVAL(state->vwv+0, 0 ,FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_DIRECTORY);
    13441262        SSVAL(state->vwv+1, 0, rename_flag);
    13451263
     
    13831301        NTSTATUS status;
    13841302
    1385         status = cli_smb_recv(subreq, 0, NULL, NULL, NULL, NULL);
     1303        status = cli_smb_recv(subreq, NULL, NULL, 0, NULL, NULL, NULL, NULL);
    13861304        TALLOC_FREE(subreq);
    1387         if (!NT_STATUS_IS_OK(status)) {
    1388                 tevent_req_nterror(req, status);
     1305        if (tevent_req_nterror(req, status)) {
    13891306                return;
    13901307        }
     
    15781495        NTSTATUS status;
    15791496
    1580         status = cli_smb_recv(subreq, 0, NULL, NULL, NULL, NULL);
     1497        status = cli_smb_recv(subreq, NULL, NULL, 0, NULL, NULL, NULL, NULL);
    15811498        TALLOC_FREE(subreq);
    1582         if (!NT_STATUS_IS_OK(status)) {
    1583                 tevent_req_nterror(req, status);
     1499        if (tevent_req_nterror(req, status)) {
    15841500                return;
    15851501        }
     
    16861602        NTSTATUS status;
    16871603
    1688         status = cli_smb_recv(subreq, 0, NULL, NULL, NULL, NULL);
     1604        status = cli_smb_recv(subreq, NULL, NULL, 0, NULL, NULL, NULL, NULL);
    16891605        TALLOC_FREE(subreq);
    1690         if (!NT_STATUS_IS_OK(status)) {
    1691                 tevent_req_nterror(req, status);
     1606        if (tevent_req_nterror(req, status)) {
    16921607                return;
    16931608        }
     
    17941709        NTSTATUS status;
    17951710
    1796         status = cli_smb_recv(subreq, 0, NULL, NULL, NULL, NULL);
     1711        status = cli_smb_recv(subreq, NULL, NULL, 0, NULL, NULL, NULL, NULL);
    17971712        TALLOC_FREE(subreq);
    1798         if (!NT_STATUS_IS_OK(status)) {
    1799                 tevent_req_nterror(req, status);
     1713        if (tevent_req_nterror(req, status)) {
    18001714                return;
    18011715        }
     
    18621776static void cli_nt_delete_on_close_done(struct tevent_req *subreq)
    18631777{
    1864         struct tevent_req *req = tevent_req_callback_data(
    1865                                 subreq, struct tevent_req);
    1866         struct doc_state *state = tevent_req_data(req, struct doc_state);
    1867         NTSTATUS status;
    1868 
    1869         status = cli_trans_recv(subreq, state, NULL, NULL, NULL, NULL, NULL, NULL);
    1870         TALLOC_FREE(subreq);
    1871         if (!NT_STATUS_IS_OK(status)) {
    1872                 tevent_req_nterror(req, status);
    1873                 return;
    1874         }
    1875         tevent_req_done(req);
     1778        NTSTATUS status = cli_trans_recv(subreq, NULL, NULL, NULL, 0, NULL,
     1779                                         NULL, 0, NULL, NULL, 0, NULL);
     1780        tevent_req_simple_finish_ntstatus(subreq, status);
    18761781}
    18771782
     
    19271832NTSTATUS cli_nt_delete_on_close_recv(struct tevent_req *req)
    19281833{
    1929         NTSTATUS status;
    1930 
    1931         if (tevent_req_is_nterror(req, &status)) {
    1932                 return status;
    1933         }
    1934         return NT_STATUS_OK;
     1834        return tevent_req_simple_recv_ntstatus(req);
    19351835}
    19361836
     
    20661966        uint32_t num_bytes;
    20671967        uint8_t *bytes;
     1968        uint8_t *inbuf;
    20681969        NTSTATUS status;
    20691970
    2070         status = cli_smb_recv(subreq, 3, &wct, &vwv, &num_bytes, &bytes);
    2071         if (!NT_STATUS_IS_OK(status)) {
    2072                 TALLOC_FREE(subreq);
    2073                 tevent_req_nterror(req, status);
     1971        status = cli_smb_recv(subreq, state, &inbuf, 3, &wct, &vwv,
     1972                              &num_bytes, &bytes);
     1973        TALLOC_FREE(subreq);
     1974        if (tevent_req_nterror(req, status)) {
    20741975                return;
    20751976        }
     
    22092110        SSVAL(state->vwv + 2, 0, 0);  /* no additional info */
    22102111        SSVAL(state->vwv + 3, 0, accessmode);
    2211         SSVAL(state->vwv + 4, 0, aSYSTEM | aHIDDEN);
     2112        SSVAL(state->vwv + 4, 0, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
    22122113        SSVAL(state->vwv + 5, 0, 0);
    22132114        SIVAL(state->vwv + 6, 0, 0);
     
    22632164
    22642165        status = cli_smb_req_send(subreq);
    2265         if (!NT_STATUS_IS_OK(status)) {
    2266                 tevent_req_nterror(req, status);
     2166        if (tevent_req_nterror(req, status)) {
    22672167                return tevent_req_post(req, ev);
    22682168        }
     
    22782178        uint8_t wct;
    22792179        uint16_t *vwv;
     2180        uint8_t *inbuf;
    22802181        NTSTATUS status;
    22812182
    2282         status = cli_smb_recv(subreq, 3, &wct, &vwv, NULL, NULL);
    2283         if (!NT_STATUS_IS_OK(status)) {
    2284                 TALLOC_FREE(subreq);
    2285                 tevent_req_nterror(req, status);
     2183        status = cli_smb_recv(subreq, state, &inbuf, 3, &wct, &vwv, NULL,
     2184                              NULL);
     2185        TALLOC_FREE(subreq);
     2186        if (tevent_req_nterror(req, status)) {
    22862187                return;
    22872188        }
     
    23972298
    23982299        status = cli_smb_req_send(subreq);
    2399         if (!NT_STATUS_IS_OK(status)) {
    2400                 tevent_req_nterror(req, status);
     2300        if (tevent_req_nterror(req, status)) {
    24012301                return tevent_req_post(req, ev);
    24022302        }
     
    24102310        NTSTATUS status;
    24112311
    2412         status = cli_smb_recv(subreq, 0, NULL, NULL, NULL, NULL);
     2312        status = cli_smb_recv(subreq, NULL, NULL, 0, NULL, NULL, NULL, NULL);
    24132313        TALLOC_FREE(subreq);
    2414         if (!NT_STATUS_IS_OK(status)) {
    2415                 tevent_req_nterror(req, status);
     2314        if (tevent_req_nterror(req, status)) {
    24162315                return;
    24172316        }
     
    24772376static void cli_ftruncate_done(struct tevent_req *subreq)
    24782377{
    2479         struct tevent_req *req = tevent_req_callback_data(
    2480                                 subreq, struct tevent_req);
    2481         struct ftrunc_state *state = tevent_req_data(req, struct ftrunc_state);
    2482         NTSTATUS status;
    2483 
    2484         status = cli_trans_recv(subreq, state, NULL, NULL, NULL, NULL, NULL, NULL);
    2485         TALLOC_FREE(subreq);
    2486         if (!NT_STATUS_IS_OK(status)) {
    2487                 tevent_req_nterror(req, status);
    2488                 return;
    2489         }
    2490         tevent_req_done(req);
     2378        NTSTATUS status = cli_trans_recv(subreq, NULL, NULL, NULL, 0, NULL,
     2379                                         NULL, 0, NULL, NULL, 0, NULL);
     2380        tevent_req_simple_finish_ntstatus(subreq, status);
    24912381}
    24922382
     
    25432433NTSTATUS cli_ftruncate_recv(struct tevent_req *req)
    25442434{
    2545         NTSTATUS status;
    2546 
    2547         if (tevent_req_is_nterror(req, &status)) {
    2548                 return status;
    2549         }
    2550         return NT_STATUS_OK;
     2435        return tevent_req_simple_recv_ntstatus(req);
    25512436}
    25522437
     
    26062491                      int timeout, unsigned char locktype)
    26072492{
    2608         char *p;
    2609         int saved_timeout = cli->timeout;
    2610 
    2611         memset(cli->outbuf,'\0',smb_size);
    2612         memset(cli->inbuf,'\0', smb_size);
    2613 
    2614         cli_set_message(cli->outbuf,8,0,True);
    2615 
    2616         SCVAL(cli->outbuf,smb_com,SMBlockingX);
    2617         SSVAL(cli->outbuf,smb_tid,cli->cnum);
    2618         cli_setup_packet(cli);
    2619 
    2620         SCVAL(cli->outbuf,smb_vwv0,0xFF);
    2621         SSVAL(cli->outbuf,smb_vwv2,fnum);
    2622         SCVAL(cli->outbuf,smb_vwv3,locktype);
    2623         SIVALS(cli->outbuf, smb_vwv4, timeout);
    2624         SSVAL(cli->outbuf,smb_vwv6,0);
    2625         SSVAL(cli->outbuf,smb_vwv7,1);
    2626 
    2627         p = smb_buf(cli->outbuf);
    2628         SSVAL(p, 0, cli->pid);
    2629         SIVAL(p, 2, offset);
    2630         SIVAL(p, 6, len);
    2631 
    2632         p += 10;
    2633 
    2634         cli_setup_bcc(cli, p);
    2635 
    2636         cli_send_smb(cli);
     2493        uint16_t vwv[8];
     2494        uint8_t bytes[10];
     2495        NTSTATUS status;
     2496        int saved_timeout;
     2497
     2498        SCVAL(vwv + 0, 0, 0xff);
     2499        SCVAL(vwv + 0, 1, 0);
     2500        SSVAL(vwv + 1, 0, 0);
     2501        SSVAL(vwv + 2, 0, fnum);
     2502        SCVAL(vwv + 3, 0, locktype);
     2503        SCVAL(vwv + 3, 1, 0);
     2504        SIVALS(vwv + 4, 0, timeout);
     2505        SSVAL(vwv + 6, 0, 0);
     2506        SSVAL(vwv + 7, 0, 1);
     2507
     2508        SSVAL(bytes, 0, cli->pid);
     2509        SIVAL(bytes, 2, offset);
     2510        SIVAL(bytes, 6, len);
     2511
     2512        saved_timeout = cli->timeout;
    26372513
    26382514        if (timeout != 0) {
    2639                 cli->timeout = (timeout == -1) ? 0x7FFFFFFF : (timeout + 2*1000);
    2640         }
    2641 
    2642         if (!cli_receive_smb(cli)) {
    2643                 cli->timeout = saved_timeout;
    2644                 return NT_STATUS_UNSUCCESSFUL;
    2645         }
     2515                cli->timeout = (timeout == -1)
     2516                        ? 0x7FFFFFFF : (timeout + 2*1000);
     2517        }
     2518
     2519        status = cli_smb(talloc_tos(), cli, SMBlockingX, 0, 8, vwv,
     2520                         10, bytes, NULL, 0, NULL, NULL, NULL, NULL);
    26462521
    26472522        cli->timeout = saved_timeout;
    26482523
    2649         return cli_nt_error(cli);
     2524        return status;
    26502525}
    26512526
     
    26562531
    26572532bool cli_lock(struct cli_state *cli, uint16_t fnum,
    2658               uint32_t offset, uint32_t len, int timeout, enum brl_type lock_type)
    2659 {
    2660         char *p;
    2661         int saved_timeout = cli->timeout;
    2662 
    2663         memset(cli->outbuf,'\0',smb_size);
    2664         memset(cli->inbuf,'\0', smb_size);
    2665 
    2666         cli_set_message(cli->outbuf,8,0,True);
    2667 
    2668         SCVAL(cli->outbuf,smb_com,SMBlockingX);
    2669         SSVAL(cli->outbuf,smb_tid,cli->cnum);
    2670         cli_setup_packet(cli);
    2671 
    2672         SCVAL(cli->outbuf,smb_vwv0,0xFF);
    2673         SSVAL(cli->outbuf,smb_vwv2,fnum);
    2674         SCVAL(cli->outbuf,smb_vwv3,(lock_type == READ_LOCK? 1 : 0));
    2675         SIVALS(cli->outbuf, smb_vwv4, timeout);
    2676         SSVAL(cli->outbuf,smb_vwv6,0);
    2677         SSVAL(cli->outbuf,smb_vwv7,1);
    2678 
    2679         p = smb_buf(cli->outbuf);
    2680         SSVAL(p, 0, cli->pid);
    2681         SIVAL(p, 2, offset);
    2682         SIVAL(p, 6, len);
    2683 
    2684         p += 10;
    2685 
    2686         cli_setup_bcc(cli, p);
    2687 
    2688         cli_send_smb(cli);
    2689 
    2690         if (timeout != 0) {
    2691                 cli->timeout = (timeout == -1) ? 0x7FFFFFFF : (timeout*2 + 5*1000);
    2692         }
    2693 
    2694         if (!cli_receive_smb(cli)) {
    2695                 cli->timeout = saved_timeout;
    2696                 return False;
    2697         }
    2698 
    2699         cli->timeout = saved_timeout;
    2700 
    2701         if (cli_is_error(cli)) {
    2702                 return False;
    2703         }
    2704 
    2705         return True;
     2533                  uint32_t offset, uint32_t len, int timeout,
     2534                  enum brl_type lock_type)
     2535{
     2536        NTSTATUS status;
     2537
     2538        status = cli_locktype(cli, fnum, offset, len, timeout,
     2539                              (lock_type == READ_LOCK? 1 : 0));
     2540        cli_set_error(cli, status);
     2541        return NT_STATUS_IS_OK(status);
    27062542}
    27072543
     
    27602596        NTSTATUS status;
    27612597
    2762         status = cli_smb_recv(subreq, 0, NULL, NULL, NULL, NULL);
     2598        status = cli_smb_recv(subreq, NULL, NULL, 0, NULL, NULL, NULL, NULL);
    27632599        TALLOC_FREE(subreq);
    2764         if (!NT_STATUS_IS_OK(status)) {
    2765                 tevent_req_nterror(req, status);
     2600        if (tevent_req_nterror(req, status)) {
    27662601                return;
    27672602        }
     
    28252660
    28262661bool cli_lock64(struct cli_state *cli, uint16_t fnum,
    2827                 uint64_t offset, uint64_t len, int timeout, enum brl_type lock_type)
    2828 {
    2829         char *p;
     2662                uint64_t offset, uint64_t len, int timeout,
     2663                enum brl_type lock_type)
     2664{
     2665        uint16_t vwv[8];
     2666        uint8_t bytes[20];
    28302667        int saved_timeout = cli->timeout;
    28312668        int ltype;
     2669        NTSTATUS status;
    28322670
    28332671        if (! (cli->capabilities & CAP_LARGE_FILES)) {
     
    28382676        ltype |= LOCKING_ANDX_LARGE_FILES;
    28392677
    2840         memset(cli->outbuf,'\0',smb_size);
    2841         memset(cli->inbuf,'\0', smb_size);
    2842 
    2843         cli_set_message(cli->outbuf,8,0,True);
    2844 
    2845         SCVAL(cli->outbuf,smb_com,SMBlockingX);
    2846         SSVAL(cli->outbuf,smb_tid,cli->cnum);
    2847         cli_setup_packet(cli);
    2848 
    2849         SCVAL(cli->outbuf,smb_vwv0,0xFF);
    2850         SSVAL(cli->outbuf,smb_vwv2,fnum);
    2851         SCVAL(cli->outbuf,smb_vwv3,ltype);
    2852         SIVALS(cli->outbuf, smb_vwv4, timeout);
    2853         SSVAL(cli->outbuf,smb_vwv6,0);
    2854         SSVAL(cli->outbuf,smb_vwv7,1);
    2855 
    2856         p = smb_buf(cli->outbuf);
    2857         SIVAL(p, 0, cli->pid);
    2858         SOFF_T_R(p, 4, offset);
    2859         SOFF_T_R(p, 12, len);
    2860         p += 20;
    2861 
    2862         cli_setup_bcc(cli, p);
    2863         cli_send_smb(cli);
     2678        SCVAL(vwv + 0, 0, 0xff);
     2679        SCVAL(vwv + 0, 1, 0);
     2680        SSVAL(vwv + 1, 0, 0);
     2681        SSVAL(vwv + 2, 0, fnum);
     2682        SCVAL(vwv + 3, 0, ltype);
     2683        SCVAL(vwv + 3, 1, 0);
     2684        SIVALS(vwv + 4, 0, timeout);
     2685        SSVAL(vwv + 6, 0, 0);
     2686        SSVAL(vwv + 7, 0, 1);
     2687
     2688        SIVAL(bytes, 0, cli->pid);
     2689        SOFF_T_R(bytes, 4, offset);
     2690        SOFF_T_R(bytes, 12, len);
     2691
     2692        saved_timeout = cli->timeout;
    28642693
    28652694        if (timeout != 0) {
    2866                 cli->timeout = (timeout == -1) ? 0x7FFFFFFF : (timeout + 5*1000);
    2867         }
    2868 
    2869         if (!cli_receive_smb(cli)) {
    2870                 cli->timeout = saved_timeout;
    2871                 return False;
    2872         }
     2695                cli->timeout = (timeout == -1)
     2696                        ? 0x7FFFFFFF : (timeout + 2*1000);
     2697        }
     2698
     2699        status = cli_smb(talloc_tos(), cli, SMBlockingX, 0, 8, vwv,
     2700                         20, bytes, NULL, 0, NULL, NULL, NULL, NULL);
    28732701
    28742702        cli->timeout = saved_timeout;
    28752703
    2876         if (cli_is_error(cli)) {
    2877                 return False;
    2878         }
    2879 
    2880         return True;
     2704        cli_set_error(cli, status);
     2705        return NT_STATUS_IS_OK(status);
    28812706}
    28822707
     
    29352760        NTSTATUS status;
    29362761
    2937         status = cli_smb_recv(subreq, 0, NULL, NULL, NULL, NULL);
     2762        status = cli_smb_recv(subreq, NULL, NULL, 0, NULL, NULL, NULL, NULL);
    29382763        TALLOC_FREE(subreq);
    2939         if (!NT_STATUS_IS_OK(status)) {
    2940                 tevent_req_nterror(req, status);
     2764        if (tevent_req_nterror(req, status)) {
    29412765                return;
    29422766        }
     
    30112835static void cli_posix_unlock_internal_done(struct tevent_req *subreq)
    30122836{
    3013         struct tevent_req *req = tevent_req_callback_data(
    3014                                         subreq, struct tevent_req);
    3015         struct posix_lock_state *state = tevent_req_data(req, struct posix_lock_state);
    3016         NTSTATUS status;
    3017 
    3018         status = cli_trans_recv(subreq, state, NULL, NULL, NULL, NULL, NULL, NULL);
    3019         TALLOC_FREE(subreq);
    3020         if (!NT_STATUS_IS_OK(status)) {
    3021                 tevent_req_nterror(req, status);
    3022                 return;
    3023         }
    3024         tevent_req_done(req);
     2837        NTSTATUS status = cli_trans_recv(subreq, NULL, NULL, NULL, 0, NULL,
     2838                                         NULL, 0, NULL, NULL, 0, NULL);
     2839        tevent_req_simple_finish_ntstatus(subreq, status);
    30252840}
    30262841
     
    31232938NTSTATUS cli_posix_lock_recv(struct tevent_req *req)
    31242939{
    3125         NTSTATUS status;
    3126 
    3127         if (tevent_req_is_nterror(req, &status)) {
    3128                 return status;
    3129         }
    3130         return NT_STATUS_OK;
     2940        return tevent_req_simple_recv_ntstatus(req);
    31312941}
    31322942
     
    32043014NTSTATUS cli_posix_unlock_recv(struct tevent_req *req)
    32053015{
    3206         NTSTATUS status;
    3207 
    3208         if (tevent_req_is_nterror(req, &status)) {
    3209                 return status;
    3210         }
    3211         return NT_STATUS_OK;
     3016        return tevent_req_simple_recv_ntstatus(req);
    32123017}
    32133018
     
    33093114        uint8_t wct;
    33103115        uint16_t *vwv = NULL;
     3116        uint8_t *inbuf;
    33113117        NTSTATUS status;
    33123118
    3313         status = cli_smb_recv(subreq, 11, &wct, &vwv, NULL, NULL);
    3314         if (!NT_STATUS_IS_OK(status)) {
    3315                 tevent_req_nterror(req, status);
     3119        status = cli_smb_recv(subreq, state, &inbuf, 11, &wct, &vwv,
     3120                              NULL, NULL);
     3121        TALLOC_FREE(subreq);
     3122        if (tevent_req_nterror(req, status)) {
    33163123                return;
    33173124        }
     
    33233130        state->write_time = make_unix_date2(vwv+4, state->zone_offset);
    33243131
    3325         TALLOC_FREE(subreq);
    33263132        tevent_req_done(req);
    33273133}
     
    34713277        uint8_t wct;
    34723278        uint16_t *vwv = NULL;
     3279        uint8_t *inbuf;
    34733280        NTSTATUS status;
    34743281
    3475         status = cli_smb_recv(subreq, 4, &wct, &vwv, NULL, NULL);
    3476         if (!NT_STATUS_IS_OK(status)) {
    3477                 tevent_req_nterror(req, status);
     3282        status = cli_smb_recv(subreq, state, &inbuf, 4, &wct, &vwv, NULL,
     3283                              NULL);
     3284        TALLOC_FREE(subreq);
     3285        if (tevent_req_nterror(req, status)) {
    34783286                return;
    34793287        }
     
    34833291        state->write_time = make_unix_date3(vwv+1, state->zone_offset);
    34843292
    3485         TALLOC_FREE(subreq);
    34863293        tevent_req_done(req);
    34873294}
     
    35883395
    35893396        SSVAL(state->vwv+0, 0, fnum);
    3590         cli_put_dos_date2(cli, (char *)&state->vwv[1], 0, change_time);
    3591         cli_put_dos_date2(cli, (char *)&state->vwv[3], 0, access_time);
    3592         cli_put_dos_date2(cli, (char *)&state->vwv[5], 0, write_time);
     3397        push_dos_date2((uint8_t *)&state->vwv[1], 0, change_time,
     3398                       cli->serverzone);
     3399        push_dos_date2((uint8_t *)&state->vwv[3], 0, access_time,
     3400                       cli->serverzone);
     3401        push_dos_date2((uint8_t *)&state->vwv[5], 0, write_time,
     3402                       cli->serverzone);
    35933403
    35943404        subreq = cli_smb_send(state, ev, cli, SMBsetattrE, additional_flags,
     
    36073417        NTSTATUS status;
    36083418
    3609         status = cli_smb_recv(subreq, 0, NULL, NULL, NULL, NULL);
     3419        status = cli_smb_recv(subreq, NULL, NULL, 0, NULL, NULL, NULL, NULL);
    36103420        TALLOC_FREE(subreq);
    3611         if (!NT_STATUS_IS_OK(status)) {
    3612                 tevent_req_nterror(req, status);
     3421        if (tevent_req_nterror(req, status)) {
    36133422                return;
    36143423        }
     
    37013510
    37023511        SSVAL(state->vwv+0, 0, attr);
    3703         cli_put_dos_date3(cli, (char *)&state->vwv[1], 0, mtime);
     3512        push_dos_date3((uint8_t *)&state->vwv[1], 0, mtime, cli->serverzone);
    37043513
    37053514        bytes = talloc_array(state, uint8_t, 1);
     
    37413550        NTSTATUS status;
    37423551
    3743         status = cli_smb_recv(subreq, 0, NULL, NULL, NULL, NULL);
     3552        status = cli_smb_recv(subreq, NULL, NULL, 0, NULL, NULL, NULL, NULL);
    37443553        TALLOC_FREE(subreq);
    3745         if (!NT_STATUS_IS_OK(status)) {
    3746                 tevent_req_nterror(req, status);
     3554        if (tevent_req_nterror(req, status)) {
    37473555                return;
    37483556        }
     
    38523660        NTSTATUS status;
    38533661
    3854         status = cli_smb_recv(subreq, 0, NULL, NULL, NULL, NULL);
     3662        status = cli_smb_recv(subreq, NULL, NULL, 0, NULL, NULL, NULL, NULL);
    38553663        TALLOC_FREE(subreq);
    3856         if (!NT_STATUS_IS_OK(status)) {
    3857                 tevent_req_nterror(req, status);
     3664        if (tevent_req_nterror(req, status)) {
    38583665                return;
    38593666        }
     
    39653772        uint8_t wct;
    39663773        uint16_t *vwv = NULL;
     3774        uint8_t *inbuf;
    39673775        NTSTATUS status;
    39683776
    3969         status = cli_smb_recv(subreq, 4, &wct, &vwv, NULL, NULL);
    3970         if (!NT_STATUS_IS_OK(status)) {
    3971                 tevent_req_nterror(req, status);
     3777        status = cli_smb_recv(subreq, state, &inbuf, 4, &wct, &vwv, NULL,
     3778                              NULL);
     3779        TALLOC_FREE(subreq);
     3780        if (tevent_req_nterror(req, status)) {
    39723781                return;
    39733782        }
     
    39753784        state->total = SVAL(vwv+0, 0);
    39763785        state->avail = SVAL(vwv+3, 0);
    3977         TALLOC_FREE(subreq);
    39783786        tevent_req_done(req);
    39793787}
     
    40973905        uint32_t num_bytes = 0;
    40983906        uint8_t *bytes = NULL;
    4099 
    4100         status = cli_smb_recv(subreq, 1, &wcnt, &vwv, &num_bytes, &bytes);
    4101         if (!NT_STATUS_IS_OK(status)) {
    4102                 TALLOC_FREE(subreq);
    4103                 tevent_req_nterror(req, status);
     3907        uint8_t *inbuf;
     3908
     3909        status = cli_smb_recv(subreq, state, &inbuf, 1, &wcnt, &vwv,
     3910                              &num_bytes, &bytes);
     3911        TALLOC_FREE(subreq);
     3912        if (tevent_req_nterror(req, status)) {
    41043913                return;
    41053914        }
    41063915
    41073916        state->fnum = SVAL(vwv+0, 0);
    4108 
    4109         TALLOC_FREE(subreq);
    41103917
    41113918        /* From W2K3, the result is just the ASCII name */
     
    41994006NTSTATUS cli_raw_ioctl(struct cli_state *cli, uint16_t fnum, uint32_t code, DATA_BLOB *blob)
    42004007{
    4201         memset(cli->outbuf,'\0',smb_size);
    4202         memset(cli->inbuf,'\0',smb_size);
    4203 
    4204         cli_set_message(cli->outbuf, 3, 0, True);
    4205         SCVAL(cli->outbuf,smb_com,SMBioctl);
    4206         cli_setup_packet(cli);
    4207 
    4208         SSVAL(cli->outbuf, smb_vwv0, fnum);
    4209         SSVAL(cli->outbuf, smb_vwv1, code>>16);
    4210         SSVAL(cli->outbuf, smb_vwv2, (code&0xFFFF));
    4211 
    4212         cli_send_smb(cli);
    4213         if (!cli_receive_smb(cli)) {
    4214                 return NT_STATUS_UNEXPECTED_NETWORK_ERROR;
    4215         }
    4216 
    4217         if (cli_is_error(cli)) {
    4218                 return cli_nt_error(cli);
    4219         }
    4220 
     4008        uint16_t vwv[3];
     4009        NTSTATUS status;
     4010
     4011        SSVAL(vwv+0, 0, fnum);
     4012        SSVAL(vwv+1, 0, code>>16);
     4013        SSVAL(vwv+2, 0, (code&0xFFFF));
     4014
     4015        status = cli_smb(talloc_tos(), cli, SMBioctl, 0, 3, vwv, 0, NULL,
     4016                         NULL, 0, NULL, NULL, NULL, NULL);
     4017        if (!NT_STATUS_IS_OK(status)) {
     4018                return status;
     4019        }
    42214020        *blob = data_blob_null;
    4222 
    42234021        return NT_STATUS_OK;
    42244022}
     
    42284026*********************************************************/
    42294027
    4230 static bool cli_set_ea(struct cli_state *cli, uint16_t setup, char *param, unsigned int param_len,
    4231                         const char *ea_name, const char *ea_val, size_t ea_len)
    4232 {
     4028static NTSTATUS cli_set_ea(struct cli_state *cli, uint16_t setup_val,
     4029                           uint8_t *param, unsigned int param_len,
     4030                           const char *ea_name,
     4031                           const char *ea_val, size_t ea_len)
     4032{
     4033        uint16_t setup[1];
    42334034        unsigned int data_len = 0;
    4234         char *data = NULL;
    4235         char *rparam=NULL, *rdata=NULL;
     4035        uint8_t *data = NULL;
    42364036        char *p;
    42374037        size_t ea_namelen = strlen(ea_name);
     4038        NTSTATUS status;
     4039
     4040        SSVAL(setup, 0, setup_val);
    42384041
    42394042        if (ea_namelen == 0 && ea_len == 0) {
    42404043                data_len = 4;
    4241                 data = (char *)SMB_MALLOC(data_len);
     4044                data = (uint8_t *)SMB_MALLOC(data_len);
    42424045                if (!data) {
    4243                         return False;
     4046                        return NT_STATUS_NO_MEMORY;
    42444047                }
    4245                 p = data;
     4048                p = (char *)data;
    42464049                SIVAL(p,0,data_len);
    42474050        } else {
    42484051                data_len = 4 + 4 + ea_namelen + 1 + ea_len;
    4249                 data = (char *)SMB_MALLOC(data_len);
     4052                data = (uint8_t *)SMB_MALLOC(data_len);
    42504053                if (!data) {
    4251                         return False;
     4054                        return NT_STATUS_NO_MEMORY;
    42524055                }
    4253                 p = data;
     4056                p = (char *)data;
    42544057                SIVAL(p,0,data_len);
    42554058                p += 4;
     
    42614064        }
    42624065
    4263         if (!cli_send_trans(cli, SMBtrans2,
    4264                         NULL,                        /* name */
    4265                         -1, 0,                          /* fid, flags */
    4266                         &setup, 1, 0,                   /* setup, length, max */
    4267                         param, param_len, 2,            /* param, length, max */
    4268                         data,  data_len, cli->max_xmit /* data, length, max */
    4269                         )) {
    4270                 SAFE_FREE(data);
    4271                 return False;
    4272         }
    4273 
    4274         if (!cli_receive_trans(cli, SMBtrans2,
    4275                         &rparam, &param_len,
    4276                         &rdata, &data_len)) {
    4277                         SAFE_FREE(data);
    4278                 return false;
    4279         }
    4280 
     4066        status = cli_trans(talloc_tos(), cli, SMBtrans2, NULL, -1, 0, 0,
     4067                           setup, 1, 0,
     4068                           param, param_len, 2,
     4069                           data,  data_len, cli->max_xmit,
     4070                           NULL,
     4071                           NULL, 0, NULL, /* rsetup */
     4072                           NULL, 0, NULL, /* rparam */
     4073                           NULL, 0, NULL); /* rdata */
    42814074        SAFE_FREE(data);
    4282         SAFE_FREE(rdata);
    4283         SAFE_FREE(rparam);
    4284 
    4285         return True;
     4075        return status;
    42864076}
    42874077
     
    42904080*********************************************************/
    42914081
    4292 bool cli_set_ea_path(struct cli_state *cli, const char *path, const char *ea_name, const char *ea_val, size_t ea_len)
    4293 {
    4294         uint16_t setup = TRANSACT2_SETPATHINFO;
     4082NTSTATUS cli_set_ea_path(struct cli_state *cli, const char *path,
     4083                         const char *ea_name, const char *ea_val,
     4084                         size_t ea_len)
     4085{
    42954086        unsigned int param_len = 0;
    4296         char *param;
     4087        uint8_t *param;
    42974088        size_t srclen = 2*(strlen(path)+1);
    42984089        char *p;
    4299         bool ret;
    4300 
    4301         param = SMB_MALLOC_ARRAY(char, 6+srclen+2);
     4090        NTSTATUS status;
     4091
     4092        param = SMB_MALLOC_ARRAY(uint8_t, 6+srclen+2);
    43024093        if (!param) {
    4303                 return false;
     4094                return NT_STATUS_NO_MEMORY;
    43044095        }
    43054096        memset(param, '\0', 6);
    43064097        SSVAL(param,0,SMB_INFO_SET_EA);
    4307         p = &param[6];
     4098        p = (char *)(&param[6]);
    43084099
    43094100        p += clistr_push(cli, p, path, srclen, STR_TERMINATE);
    43104101        param_len = PTR_DIFF(p, param);
    43114102
    4312         ret = cli_set_ea(cli, setup, param, param_len, ea_name, ea_val, ea_len);
     4103        status = cli_set_ea(cli, TRANSACT2_SETPATHINFO, param, param_len,
     4104                            ea_name, ea_val, ea_len);
    43134105        SAFE_FREE(param);
    4314         return ret;
     4106        return status;
    43154107}
    43164108
     
    43194111*********************************************************/
    43204112
    4321 bool cli_set_ea_fnum(struct cli_state *cli, uint16_t fnum, const char *ea_name, const char *ea_val, size_t ea_len)
    4322 {
    4323         char param[6];
    4324         uint16_t setup = TRANSACT2_SETFILEINFO;
     4113NTSTATUS cli_set_ea_fnum(struct cli_state *cli, uint16_t fnum,
     4114                         const char *ea_name, const char *ea_val,
     4115                         size_t ea_len)
     4116{
     4117        uint8_t param[6];
    43254118
    43264119        memset(param, 0, 6);
     
    43284121        SSVAL(param,2,SMB_INFO_SET_EA);
    43294122
    4330         return cli_set_ea(cli, setup, param, 6, ea_name, ea_val, ea_len);
     4123        return cli_set_ea(cli, TRANSACT2_SETFILEINFO, param, 6,
     4124                          ea_name, ea_val, ea_len);
    43314125}
    43324126
     
    43354129*********************************************************/
    43364130
    4337 static bool cli_get_ea_list(struct cli_state *cli,
    4338                 uint16_t setup, char *param, unsigned int param_len,
    4339                 TALLOC_CTX *ctx,
    4340                 size_t *pnum_eas,
    4341                 struct ea_struct **pea_list)
    4342 {
    4343         unsigned int data_len = 0;
    4344         unsigned int rparam_len, rdata_len;
    4345         char *rparam=NULL, *rdata=NULL;
    4346         char *p;
     4131static bool parse_ea_blob(TALLOC_CTX *ctx, const uint8_t *rdata,
     4132                          size_t rdata_len,
     4133                          size_t *pnum_eas, struct ea_struct **pea_list)
     4134{
     4135        struct ea_struct *ea_list = NULL;
     4136        size_t num_eas;
    43474137        size_t ea_size;
    4348         size_t num_eas;
    4349         bool ret = False;
    4350         struct ea_struct *ea_list;
    4351 
    4352         *pnum_eas = 0;
    4353         if (pea_list) {
    4354                 *pea_list = NULL;
    4355         }
    4356 
    4357         if (!cli_send_trans(cli, SMBtrans2,
    4358                         NULL,           /* Name */
    4359                         -1, 0,          /* fid, flags */
    4360                         &setup, 1, 0,   /* setup, length, max */
    4361                         param, param_len, 10, /* param, length, max */
    4362                         NULL, data_len, cli->max_xmit /* data, length, max */
    4363                                 )) {
    4364                 return False;
    4365         }
    4366 
    4367         if (!cli_receive_trans(cli, SMBtrans2,
    4368                         &rparam, &rparam_len,
    4369                         &rdata, &rdata_len)) {
    4370                 return False;
    4371         }
    4372 
    4373         if (!rdata || rdata_len < 4) {
    4374                 goto out;
     4138        const uint8_t *p;
     4139
     4140        if (rdata_len < 4) {
     4141                return false;
    43754142        }
    43764143
    43774144        ea_size = (size_t)IVAL(rdata,0);
    43784145        if (ea_size > rdata_len) {
    4379                 goto out;
     4146                return false;
    43804147        }
    43814148
    43824149        if (ea_size == 0) {
    43834150                /* No EA's present. */
    4384                 ret = True;
    4385                 goto out;
     4151                *pnum_eas = 0;
     4152                *pea_list = NULL;
     4153                return true;
    43864154        }
    43874155
     
    43944162                unsigned int ea_valuelen = SVAL(p,2);
    43954163                if (ea_namelen == 0) {
    4396                         goto out;
     4164                        return false;
    43974165                }
    43984166                if (4 + ea_namelen + 1 + ea_valuelen > ea_size) {
    4399                         goto out;
     4167                        return false;
    44004168                }
    44014169                ea_size -= 4 + ea_namelen + 1 + ea_valuelen;
     
    44044172
    44054173        if (num_eas == 0) {
    4406                 ret = True;
    4407                 goto out;
     4174                *pnum_eas = 0;
     4175                *pea_list = NULL;
     4176                return true;
    44084177        }
    44094178
     
    44114180        if (!pea_list) {
    44124181                /* Caller only wants number of EA's. */
    4413                 ret = True;
    4414                 goto out;
     4182                return true;
    44154183        }
    44164184
    44174185        ea_list = TALLOC_ARRAY(ctx, struct ea_struct, num_eas);
    44184186        if (!ea_list) {
    4419                 goto out;
     4187                return false;
    44204188        }
    44214189
     
    44324200                unix_ea_name[0] = '\0';
    44334201                pull_ascii_fstring(unix_ea_name, p + 4);
    4434                 ea->name = talloc_strdup(ctx, unix_ea_name);
     4202                ea->name = talloc_strdup(ea_list, unix_ea_name);
     4203                if (!ea->name) {
     4204                        goto fail;
     4205                }
    44354206                /* Ensure the value is null terminated (in case it's a string). */
    4436                 ea->value = data_blob_talloc(ctx, NULL, ea_valuelen + 1);
     4207                ea->value = data_blob_talloc(ea_list, NULL, ea_valuelen + 1);
    44374208                if (!ea->value.data) {
    4438                         goto out;
     4209                        goto fail;
    44394210                }
    44404211                if (ea_valuelen) {
     
    44474218
    44484219        *pea_list = ea_list;
    4449         ret = True;
    4450 
    4451  out :
    4452 
    4453         SAFE_FREE(rdata);
    4454         SAFE_FREE(rparam);
    4455         return ret;
     4220        return true;
     4221
     4222fail:
     4223        TALLOC_FREE(ea_list);
     4224        return false;
    44564225}
    44574226
     
    44604229*********************************************************/
    44614230
    4462 bool cli_get_ea_list_path(struct cli_state *cli, const char *path,
     4231struct cli_get_ea_list_path_state {
     4232        uint32_t num_data;
     4233        uint8_t *data;
     4234};
     4235
     4236static void cli_get_ea_list_path_done(struct tevent_req *subreq);
     4237
     4238struct tevent_req *cli_get_ea_list_path_send(TALLOC_CTX *mem_ctx,
     4239                                             struct tevent_context *ev,
     4240                                             struct cli_state *cli,
     4241                                             const char *fname)
     4242{
     4243        struct tevent_req *req, *subreq;
     4244        struct cli_get_ea_list_path_state *state;
     4245
     4246        req = tevent_req_create(mem_ctx, &state,
     4247                                struct cli_get_ea_list_path_state);
     4248        if (req == NULL) {
     4249                return NULL;
     4250        }
     4251        subreq = cli_qpathinfo_send(state, ev, cli, fname,
     4252                                    SMB_INFO_QUERY_ALL_EAS, 4,
     4253                                    cli->max_xmit);
     4254        if (tevent_req_nomem(subreq, req)) {
     4255                return tevent_req_post(req, ev);
     4256        }
     4257        tevent_req_set_callback(subreq, cli_get_ea_list_path_done, req);
     4258        return req;
     4259}
     4260
     4261static void cli_get_ea_list_path_done(struct tevent_req *subreq)
     4262{
     4263        struct tevent_req *req = tevent_req_callback_data(
     4264                                subreq, struct tevent_req);
     4265        struct cli_get_ea_list_path_state *state = tevent_req_data(
     4266                req, struct cli_get_ea_list_path_state);
     4267        NTSTATUS status;
     4268
     4269        status = cli_qpathinfo_recv(subreq, state, &state->data,
     4270                                    &state->num_data);
     4271        TALLOC_FREE(subreq);
     4272        if (tevent_req_nterror(req, status)) {
     4273                return;
     4274        }
     4275        tevent_req_done(req);
     4276}
     4277
     4278NTSTATUS cli_get_ea_list_path_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
     4279                                   size_t *pnum_eas, struct ea_struct **peas)
     4280{
     4281        struct cli_get_ea_list_path_state *state = tevent_req_data(
     4282                req, struct cli_get_ea_list_path_state);
     4283        NTSTATUS status;
     4284
     4285        if (tevent_req_is_nterror(req, &status)) {
     4286                return status;
     4287        }
     4288        if (!parse_ea_blob(mem_ctx, state->data, state->num_data,
     4289                           pnum_eas, peas)) {
     4290                return NT_STATUS_INVALID_NETWORK_RESPONSE;
     4291        }
     4292        return NT_STATUS_OK;
     4293}
     4294
     4295NTSTATUS cli_get_ea_list_path(struct cli_state *cli, const char *path,
    44634296                TALLOC_CTX *ctx,
    44644297                size_t *pnum_eas,
    44654298                struct ea_struct **pea_list)
    44664299{
    4467         uint16_t setup = TRANSACT2_QPATHINFO;
    4468         unsigned int param_len = 0;
    4469         char *param;
    4470         char *p;
    4471         size_t srclen = 2*(strlen(path)+1);
    4472         bool ret;
    4473 
    4474         param = SMB_MALLOC_ARRAY(char, 6+srclen+2);
    4475         if (!param) {
    4476                 return false;
    4477         }
    4478         p = param;
    4479         memset(p, 0, 6);
    4480         SSVAL(p, 0, SMB_INFO_QUERY_ALL_EAS);
    4481         p += 6;
    4482         p += clistr_push(cli, p, path, srclen, STR_TERMINATE);
    4483         param_len = PTR_DIFF(p, param);
    4484 
    4485         ret = cli_get_ea_list(cli, setup, param, param_len, ctx, pnum_eas, pea_list);
    4486         SAFE_FREE(param);
    4487         return ret;
    4488 }
    4489 
    4490 /*********************************************************
    4491  Get an extended attribute list from an fnum.
    4492 *********************************************************/
    4493 
    4494 bool cli_get_ea_list_fnum(struct cli_state *cli, uint16_t fnum,
    4495                 TALLOC_CTX *ctx,
    4496                 size_t *pnum_eas,
    4497                 struct ea_struct **pea_list)
    4498 {
    4499         uint16_t setup = TRANSACT2_QFILEINFO;
    4500         char param[6];
    4501 
    4502         memset(param, 0, 6);
    4503         SSVAL(param,0,fnum);
    4504         SSVAL(param,2,SMB_INFO_SET_EA);
    4505 
    4506         return cli_get_ea_list(cli, setup, param, 6, ctx, pnum_eas, pea_list);
     4300        TALLOC_CTX *frame = talloc_stackframe();
     4301        struct event_context *ev = NULL;
     4302        struct tevent_req *req = NULL;
     4303        NTSTATUS status = NT_STATUS_NO_MEMORY;
     4304
     4305        if (cli_has_async_calls(cli)) {
     4306                /*
     4307                 * Can't use sync call while an async call is in flight
     4308                 */
     4309                status = NT_STATUS_INVALID_PARAMETER;
     4310                goto fail;
     4311        }
     4312        ev = event_context_init(frame);
     4313        if (ev == NULL) {
     4314                goto fail;
     4315        }
     4316        req = cli_get_ea_list_path_send(frame, ev, cli, path);
     4317        if (req == NULL) {
     4318                goto fail;
     4319        }
     4320        if (!tevent_req_poll_ntstatus(req, ev, &status)) {
     4321                goto fail;
     4322        }
     4323        status = cli_get_ea_list_path_recv(req, ctx, pnum_eas, pea_list);
     4324 fail:
     4325        TALLOC_FREE(frame);
     4326        if (!NT_STATUS_IS_OK(status)) {
     4327                cli_set_error(cli, status);
     4328        }
     4329        return status;
    45074330}
    45084331
     
    45534376#if defined(O_DIRECTORY)
    45544377        if (flags & O_DIRECTORY) {
    4555                 ret &= ~(SMB_O_RDONLY|SMB_O_RDWR|SMB_O_WRONLY);
    45564378                ret |= SMB_O_DIRECTORY;
    45574379        }
     
    45804402        uint32_t num_data;
    45814403
    4582         status = cli_trans_recv(subreq, state, NULL, NULL, NULL, NULL, &data, &num_data);
     4404        status = cli_trans_recv(subreq, state, NULL, NULL, 0, NULL,
     4405                                NULL, 0, NULL, &data, 12, &num_data);
    45834406        TALLOC_FREE(subreq);
    4584         if (!NT_STATUS_IS_OK(status)) {
    4585                 tevent_req_nterror(req, status);
    4586                 return;
    4587         }
    4588         if (num_data < 12) {
    4589                 tevent_req_nterror(req, status);
     4407        if (tevent_req_nterror(req, status)) {
    45904408                return;
    45914409        }
     
    46314449        /* Setup data words. */
    46324450        if (is_dir) {
    4633                 wire_flags &= ~(SMB_O_RDONLY|SMB_O_RDWR|SMB_O_WRONLY);
    46344451                wire_flags |= SMB_O_DIRECTORY;
    46354452        }
     
    47544571NTSTATUS cli_posix_mkdir_recv(struct tevent_req *req)
    47554572{
    4756         NTSTATUS status;
    4757 
    4758         if (tevent_req_is_nterror(req, &status)) {
    4759                 return status;
    4760         }
    4761         return NT_STATUS_OK;
     4573        return tevent_req_simple_recv_ntstatus(req);
    47624574}
    47634575
     
    48124624****************************************************************************/
    48134625
    4814 struct unlink_state {
    4815         uint16_t setup;
     4626struct cli_posix_unlink_internal_state {
    48164627        uint8_t data[2];
    48174628};
    48184629
    4819 static void cli_posix_unlink_internal_done(struct tevent_req *subreq)
    4820 {
    4821         struct tevent_req *req = tevent_req_callback_data(
    4822                                 subreq, struct tevent_req);
    4823         struct unlink_state *state = tevent_req_data(req, struct unlink_state);
    4824         NTSTATUS status;
    4825 
    4826         status = cli_trans_recv(subreq, state, NULL, NULL, NULL, NULL, NULL, NULL);
    4827         TALLOC_FREE(subreq);
    4828         if (!NT_STATUS_IS_OK(status)) {
    4829                 tevent_req_nterror(req, status);
    4830                 return;
    4831         }
    4832         tevent_req_done(req);
    4833 }
     4630static void cli_posix_unlink_internal_done(struct tevent_req *subreq);
    48344631
    48354632static struct tevent_req *cli_posix_unlink_internal_send(TALLOC_CTX *mem_ctx,
     
    48374634                                        struct cli_state *cli,
    48384635                                        const char *fname,
    4839                                         bool is_dir)
     4636                                        uint16_t level)
    48404637{
    48414638        struct tevent_req *req = NULL, *subreq = NULL;
    4842         struct unlink_state *state = NULL;
    4843         uint8_t *param = NULL;
    4844 
    4845         req = tevent_req_create(mem_ctx, &state, struct unlink_state);
     4639        struct cli_posix_unlink_internal_state *state = NULL;
     4640
     4641        req = tevent_req_create(mem_ctx, &state,
     4642                                struct cli_posix_unlink_internal_state);
    48464643        if (req == NULL) {
    48474644                return NULL;
    48484645        }
    48494646
    4850         /* Setup setup word. */
    4851         SSVAL(&state->setup, 0, TRANSACT2_SETPATHINFO);
    4852 
    4853         /* Setup param array. */
    4854         param = talloc_array(state, uint8_t, 6);
    4855         if (tevent_req_nomem(param, req)) {
    4856                 return tevent_req_post(req, ev);
    4857         }
    4858         memset(param, '\0', 6);
    4859         SSVAL(param, 0, SMB_POSIX_PATH_UNLINK);
    4860 
    4861         param = trans2_bytes_push_str(param, cli_ucs2(cli), fname,
    4862                                    strlen(fname)+1, NULL);
    4863 
    4864         if (tevent_req_nomem(param, req)) {
    4865                 return tevent_req_post(req, ev);
    4866         }
    4867 
    48684647        /* Setup data word. */
    4869         SSVAL(state->data, 0, is_dir ? SMB_POSIX_UNLINK_DIRECTORY_TARGET :
    4870                         SMB_POSIX_UNLINK_FILE_TARGET);
    4871 
    4872         subreq = cli_trans_send(state,                  /* mem ctx. */
    4873                                 ev,                     /* event ctx. */
    4874                                 cli,                    /* cli_state. */
    4875                                 SMBtrans2,              /* cmd. */
    4876                                 NULL,                   /* pipe name. */
    4877                                 -1,                     /* fid. */
    4878                                 0,                      /* function. */
    4879                                 0,                      /* flags. */
    4880                                 &state->setup,          /* setup. */
    4881                                 1,                      /* num setup uint16_t words. */
    4882                                 0,                      /* max returned setup. */
    4883                                 param,                  /* param. */
    4884                                 talloc_get_size(param), /* num param. */
    4885                                 2,                      /* max returned param. */
    4886                                 state->data,            /* data. */
    4887                                 2,                      /* num data. */
    4888                                 0);                     /* max returned data. */
    4889 
     4648        SSVAL(state->data, 0, level);
     4649
     4650        subreq = cli_setpathinfo_send(state, ev, cli,
     4651                                      SMB_POSIX_PATH_UNLINK,
     4652                                      fname,
     4653                                      state->data, sizeof(state->data));
    48904654        if (tevent_req_nomem(subreq, req)) {
    48914655                return tevent_req_post(req, ev);
     
    48934657        tevent_req_set_callback(subreq, cli_posix_unlink_internal_done, req);
    48944658        return req;
     4659}
     4660
     4661static void cli_posix_unlink_internal_done(struct tevent_req *subreq)
     4662{
     4663        NTSTATUS status = cli_setpathinfo_recv(subreq);
     4664        tevent_req_simple_finish_ntstatus(subreq, status);
    48954665}
    48964666
     
    49004670                                        const char *fname)
    49014671{
    4902         return cli_posix_unlink_internal_send(mem_ctx, ev, cli, fname, false);
     4672        return cli_posix_unlink_internal_send(mem_ctx, ev, cli, fname,
     4673                                              SMB_POSIX_UNLINK_FILE_TARGET);
    49034674}
    49044675
    49054676NTSTATUS cli_posix_unlink_recv(struct tevent_req *req)
    49064677{
    4907         NTSTATUS status;
    4908 
    4909         if (tevent_req_is_nterror(req, &status)) {
    4910                 return status;
    4911         }
    4912         return NT_STATUS_OK;
     4678        return tevent_req_simple_recv_ntstatus(req);
    49134679}
    49144680
     
    49714737                                        const char *fname)
    49724738{
    4973         return cli_posix_unlink_internal_send(mem_ctx, ev, cli, fname, true);
     4739        return cli_posix_unlink_internal_send(
     4740                mem_ctx, ev, cli, fname,
     4741                SMB_POSIX_UNLINK_DIRECTORY_TARGET);
    49744742}
    49754743
    49764744NTSTATUS cli_posix_rmdir_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx)
    49774745{
    4978         NTSTATUS status;
    4979 
    4980         if (tevent_req_is_nterror(req, &status)) {
    4981                 return status;
    4982         }
    4983         return NT_STATUS_OK;
     4746        return tevent_req_simple_recv_ntstatus(req);
    49844747}
    49854748
     
    50944857        uint8_t *params;
    50954858        uint32_t i, ofs, num_params;
    5096 
    5097         status = cli_trans_recv(subreq, talloc_tos(), NULL, NULL,
    5098                                 &params, &num_params, NULL, NULL);
     4859        uint16_t flags2;
     4860
     4861        status = cli_trans_recv(subreq, talloc_tos(), &flags2, NULL, 0, NULL,
     4862                                &params, 0, &num_params, NULL, 0, NULL);
    50994863        TALLOC_FREE(subreq);
    5100         if (!NT_STATUS_IS_OK(status)) {
     4864        if (tevent_req_nterror(req, status)) {
    51014865                DEBUG(10, ("cli_trans_recv returned %s\n", nt_errstr(status)));
    5102                 tevent_req_nterror(req, status);
    51034866                return;
    51044867        }
     
    51404903
    51414904                state->changes[i].action = IVAL(params, ofs+4);
    5142                 ret = clistr_pull_talloc(params, (char *)params, &name,
    5143                                          params+ofs+12, len,
     4905                ret = clistr_pull_talloc(params, (char *)params, flags2,
     4906                                         &name, params+ofs+12, len,
    51444907                                         STR_TERMINATE|STR_UNICODE);
    51454908                if (ret == -1) {
     
    51724935        return NT_STATUS_OK;
    51734936}
     4937
     4938struct cli_qpathinfo_state {
     4939        uint8_t *param;
     4940        uint8_t *data;
     4941        uint16_t setup[1];
     4942        uint32_t min_rdata;
     4943        uint8_t *rdata;
     4944        uint32_t num_rdata;
     4945};
     4946
     4947static void cli_qpathinfo_done(struct tevent_req *subreq);
     4948
     4949struct tevent_req *cli_qpathinfo_send(TALLOC_CTX *mem_ctx,
     4950                                      struct tevent_context *ev,
     4951                                      struct cli_state *cli, const char *fname,
     4952                                      uint16_t level, uint32_t min_rdata,
     4953                                      uint32_t max_rdata)
     4954{
     4955        struct tevent_req *req, *subreq;
     4956        struct cli_qpathinfo_state *state;
     4957
     4958        req = tevent_req_create(mem_ctx, &state, struct cli_qpathinfo_state);
     4959        if (req == NULL) {
     4960                return NULL;
     4961        }
     4962        state->min_rdata = min_rdata;
     4963        SSVAL(state->setup, 0, TRANSACT2_QPATHINFO);
     4964
     4965        state->param = talloc_zero_array(state, uint8_t, 6);
     4966        if (tevent_req_nomem(state->param, req)) {
     4967                return tevent_req_post(req, ev);
     4968        }
     4969        SSVAL(state->param, 0, level);
     4970        state->param = trans2_bytes_push_str(
     4971                state->param, cli_ucs2(cli), fname, strlen(fname)+1, NULL);
     4972        if (tevent_req_nomem(state->param, req)) {
     4973                return tevent_req_post(req, ev);
     4974        }
     4975
     4976        subreq = cli_trans_send(
     4977                state,                  /* mem ctx. */
     4978                ev,                     /* event ctx. */
     4979                cli,                    /* cli_state. */
     4980                SMBtrans2,              /* cmd. */
     4981                NULL,                   /* pipe name. */
     4982                -1,                     /* fid. */
     4983                0,                      /* function. */
     4984                0,                      /* flags. */
     4985                state->setup,           /* setup. */
     4986                1,                      /* num setup uint16_t words. */
     4987                0,                      /* max returned setup. */
     4988                state->param,           /* param. */
     4989                talloc_get_size(state->param),  /* num param. */
     4990                2,                      /* max returned param. */
     4991                NULL,                   /* data. */
     4992                0,                      /* num data. */
     4993                max_rdata);             /* max returned data. */
     4994
     4995        if (tevent_req_nomem(subreq, req)) {
     4996                return tevent_req_post(req, ev);
     4997        }
     4998        tevent_req_set_callback(subreq, cli_qpathinfo_done, req);
     4999        return req;
     5000}
     5001
     5002static void cli_qpathinfo_done(struct tevent_req *subreq)
     5003{
     5004        struct tevent_req *req = tevent_req_callback_data(
     5005                subreq, struct tevent_req);
     5006        struct cli_qpathinfo_state *state = tevent_req_data(
     5007                req, struct cli_qpathinfo_state);
     5008        NTSTATUS status;
     5009
     5010        status = cli_trans_recv(subreq, state, NULL, NULL, 0, NULL,
     5011                                NULL, 0, NULL,
     5012                                &state->rdata, state->min_rdata,
     5013                                &state->num_rdata);
     5014        if (tevent_req_nterror(req, status)) {
     5015                return;
     5016        }
     5017        tevent_req_done(req);
     5018}
     5019
     5020NTSTATUS cli_qpathinfo_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
     5021                            uint8_t **rdata, uint32_t *num_rdata)
     5022{
     5023        struct cli_qpathinfo_state *state = tevent_req_data(
     5024                req, struct cli_qpathinfo_state);
     5025        NTSTATUS status;
     5026
     5027        if (tevent_req_is_nterror(req, &status)) {
     5028                return status;
     5029        }
     5030        if (rdata != NULL) {
     5031                *rdata = talloc_move(mem_ctx, &state->rdata);
     5032        } else {
     5033                TALLOC_FREE(state->rdata);
     5034        }
     5035        if (num_rdata != NULL) {
     5036                *num_rdata = state->num_rdata;
     5037        }
     5038        return NT_STATUS_OK;
     5039}
     5040
     5041NTSTATUS cli_qpathinfo(TALLOC_CTX *mem_ctx, struct cli_state *cli,
     5042                       const char *fname, uint16_t level, uint32_t min_rdata,
     5043                       uint32_t max_rdata,
     5044                       uint8_t **rdata, uint32_t *num_rdata)
     5045{
     5046        TALLOC_CTX *frame = talloc_stackframe();
     5047        struct event_context *ev;
     5048        struct tevent_req *req;
     5049        NTSTATUS status = NT_STATUS_NO_MEMORY;
     5050
     5051        if (cli_has_async_calls(cli)) {
     5052                /*
     5053                 * Can't use sync call while an async call is in flight
     5054                 */
     5055                status = NT_STATUS_INVALID_PARAMETER;
     5056                goto fail;
     5057        }
     5058        ev = event_context_init(frame);
     5059        if (ev == NULL) {
     5060                goto fail;
     5061        }
     5062        req = cli_qpathinfo_send(frame, ev, cli, fname, level, min_rdata,
     5063                                 max_rdata);
     5064        if (req == NULL) {
     5065                goto fail;
     5066        }
     5067        if (!tevent_req_poll_ntstatus(req, ev, &status)) {
     5068                goto fail;
     5069        }
     5070        status = cli_qpathinfo_recv(req, mem_ctx, rdata, num_rdata);
     5071 fail:
     5072        TALLOC_FREE(frame);
     5073        if (!NT_STATUS_IS_OK(status)) {
     5074                cli_set_error(cli, status);
     5075        }
     5076        return status;
     5077}
     5078
     5079struct cli_qfileinfo_state {
     5080        uint16_t setup[1];
     5081        uint8_t param[4];
     5082        uint8_t *data;
     5083        uint32_t min_rdata;
     5084        uint8_t *rdata;
     5085        uint32_t num_rdata;
     5086};
     5087
     5088static void cli_qfileinfo_done(struct tevent_req *subreq);
     5089
     5090struct tevent_req *cli_qfileinfo_send(TALLOC_CTX *mem_ctx,
     5091                                      struct tevent_context *ev,
     5092                                      struct cli_state *cli, uint16_t fnum,
     5093                                      uint16_t level, uint32_t min_rdata,
     5094                                      uint32_t max_rdata)
     5095{
     5096        struct tevent_req *req, *subreq;
     5097        struct cli_qfileinfo_state *state;
     5098
     5099        req = tevent_req_create(mem_ctx, &state, struct cli_qfileinfo_state);
     5100        if (req == NULL) {
     5101                return NULL;
     5102        }
     5103        state->min_rdata = min_rdata;
     5104        SSVAL(state->param, 0, fnum);
     5105        SSVAL(state->param, 2, level);
     5106        SSVAL(state->setup, 0, TRANSACT2_QFILEINFO);
     5107
     5108        subreq = cli_trans_send(
     5109                state,                  /* mem ctx. */
     5110                ev,                     /* event ctx. */
     5111                cli,                    /* cli_state. */
     5112                SMBtrans2,              /* cmd. */
     5113                NULL,                   /* pipe name. */
     5114                -1,                     /* fid. */
     5115                0,                      /* function. */
     5116                0,                      /* flags. */
     5117                state->setup,           /* setup. */
     5118                1,                      /* num setup uint16_t words. */
     5119                0,                      /* max returned setup. */
     5120                state->param,           /* param. */
     5121                sizeof(state->param),   /* num param. */
     5122                2,                      /* max returned param. */
     5123                NULL,                   /* data. */
     5124                0,                      /* num data. */
     5125                max_rdata);             /* max returned data. */
     5126
     5127        if (tevent_req_nomem(subreq, req)) {
     5128                return tevent_req_post(req, ev);
     5129        }
     5130        tevent_req_set_callback(subreq, cli_qfileinfo_done, req);
     5131        return req;
     5132}
     5133
     5134static void cli_qfileinfo_done(struct tevent_req *subreq)
     5135{
     5136        struct tevent_req *req = tevent_req_callback_data(
     5137                subreq, struct tevent_req);
     5138        struct cli_qfileinfo_state *state = tevent_req_data(
     5139                req, struct cli_qfileinfo_state);
     5140        NTSTATUS status;
     5141
     5142        status = cli_trans_recv(subreq, state, NULL, NULL, 0, NULL,
     5143                                NULL, 0, NULL,
     5144                                &state->rdata, state->min_rdata,
     5145                                &state->num_rdata);
     5146        if (tevent_req_nterror(req, status)) {
     5147                return;
     5148        }
     5149        tevent_req_done(req);
     5150}
     5151
     5152NTSTATUS cli_qfileinfo_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
     5153                            uint8_t **rdata, uint32_t *num_rdata)
     5154{
     5155        struct cli_qfileinfo_state *state = tevent_req_data(
     5156                req, struct cli_qfileinfo_state);
     5157        NTSTATUS status;
     5158
     5159        if (tevent_req_is_nterror(req, &status)) {
     5160                return status;
     5161        }
     5162        if (rdata != NULL) {
     5163                *rdata = talloc_move(mem_ctx, &state->rdata);
     5164        } else {
     5165                TALLOC_FREE(state->rdata);
     5166        }
     5167        if (num_rdata != NULL) {
     5168                *num_rdata = state->num_rdata;
     5169        }
     5170        return NT_STATUS_OK;
     5171}
     5172
     5173NTSTATUS cli_qfileinfo(TALLOC_CTX *mem_ctx, struct cli_state *cli,
     5174                       uint16_t fnum, uint16_t level, uint32_t min_rdata,
     5175                       uint32_t max_rdata,
     5176                       uint8_t **rdata, uint32_t *num_rdata)
     5177{
     5178        TALLOC_CTX *frame = talloc_stackframe();
     5179        struct event_context *ev;
     5180        struct tevent_req *req;
     5181        NTSTATUS status = NT_STATUS_NO_MEMORY;
     5182
     5183        if (cli_has_async_calls(cli)) {
     5184                /*
     5185                 * Can't use sync call while an async call is in flight
     5186                 */
     5187                status = NT_STATUS_INVALID_PARAMETER;
     5188                goto fail;
     5189        }
     5190        ev = event_context_init(frame);
     5191        if (ev == NULL) {
     5192                goto fail;
     5193        }
     5194        req = cli_qfileinfo_send(frame, ev, cli, fnum, level, min_rdata,
     5195                                 max_rdata);
     5196        if (req == NULL) {
     5197                goto fail;
     5198        }
     5199        if (!tevent_req_poll_ntstatus(req, ev, &status)) {
     5200                goto fail;
     5201        }
     5202        status = cli_qfileinfo_recv(req, mem_ctx, rdata, num_rdata);
     5203 fail:
     5204        TALLOC_FREE(frame);
     5205        if (!NT_STATUS_IS_OK(status)) {
     5206                cli_set_error(cli, status);
     5207        }
     5208        return status;
     5209}
     5210
     5211struct cli_flush_state {
     5212        uint16_t vwv[1];
     5213};
     5214
     5215static void cli_flush_done(struct tevent_req *subreq);
     5216
     5217struct tevent_req *cli_flush_send(TALLOC_CTX *mem_ctx,
     5218                                  struct event_context *ev,
     5219                                  struct cli_state *cli,
     5220                                  uint16_t fnum)
     5221{
     5222        struct tevent_req *req, *subreq;
     5223        struct cli_flush_state *state;
     5224
     5225        req = tevent_req_create(mem_ctx, &state, struct cli_flush_state);
     5226        if (req == NULL) {
     5227                return NULL;
     5228        }
     5229        SSVAL(state->vwv + 0, 0, fnum);
     5230
     5231        subreq = cli_smb_send(state, ev, cli, SMBflush, 0, 1, state->vwv,
     5232                              0, NULL);
     5233        if (tevent_req_nomem(subreq, req)) {
     5234                return tevent_req_post(req, ev);
     5235        }
     5236        tevent_req_set_callback(subreq, cli_flush_done, req);
     5237        return req;
     5238}
     5239
     5240static void cli_flush_done(struct tevent_req *subreq)
     5241{
     5242        struct tevent_req *req = tevent_req_callback_data(
     5243                subreq, struct tevent_req);
     5244        NTSTATUS status;
     5245
     5246        status = cli_smb_recv(subreq, NULL, NULL, 0, NULL, NULL, NULL, NULL);
     5247        TALLOC_FREE(subreq);
     5248        if (tevent_req_nterror(req, status)) {
     5249                return;
     5250        }
     5251        tevent_req_done(req);
     5252}
     5253
     5254NTSTATUS cli_flush_recv(struct tevent_req *req)
     5255{
     5256        return tevent_req_simple_recv_ntstatus(req);
     5257}
     5258
     5259NTSTATUS cli_flush(TALLOC_CTX *mem_ctx, struct cli_state *cli, uint16_t fnum)
     5260{
     5261        TALLOC_CTX *frame = talloc_stackframe();
     5262        struct event_context *ev;
     5263        struct tevent_req *req;
     5264        NTSTATUS status = NT_STATUS_NO_MEMORY;
     5265
     5266        if (cli_has_async_calls(cli)) {
     5267                /*
     5268                 * Can't use sync call while an async call is in flight
     5269                 */
     5270                status = NT_STATUS_INVALID_PARAMETER;
     5271                goto fail;
     5272        }
     5273        ev = event_context_init(frame);
     5274        if (ev == NULL) {
     5275                goto fail;
     5276        }
     5277        req = cli_flush_send(frame, ev, cli, fnum);
     5278        if (req == NULL) {
     5279                goto fail;
     5280        }
     5281        if (!tevent_req_poll_ntstatus(req, ev, &status)) {
     5282                goto fail;
     5283        }
     5284        status = cli_flush_recv(req);
     5285 fail:
     5286        TALLOC_FREE(frame);
     5287        if (!NT_STATUS_IS_OK(status)) {
     5288                cli_set_error(cli, status);
     5289        }
     5290        return status;
     5291}
     5292
     5293struct cli_shadow_copy_data_state {
     5294        uint16_t setup[4];
     5295        uint8_t *data;
     5296        uint32_t num_data;
     5297        bool get_names;
     5298};
     5299
     5300static void cli_shadow_copy_data_done(struct tevent_req *subreq);
     5301
     5302struct tevent_req *cli_shadow_copy_data_send(TALLOC_CTX *mem_ctx,
     5303                                             struct tevent_context *ev,
     5304                                             struct cli_state *cli,
     5305                                             uint16_t fnum,
     5306                                             bool get_names)
     5307{
     5308        struct tevent_req *req, *subreq;
     5309        struct cli_shadow_copy_data_state *state;
     5310        uint32_t ret_size;
     5311
     5312        req = tevent_req_create(mem_ctx, &state,
     5313                                struct cli_shadow_copy_data_state);
     5314        if (req == NULL) {
     5315                return NULL;
     5316        }
     5317        state->get_names = get_names;
     5318        ret_size = get_names ? cli->max_xmit : 16;
     5319
     5320        SIVAL(state->setup + 0, 0, FSCTL_GET_SHADOW_COPY_DATA);
     5321        SSVAL(state->setup + 2, 0, fnum);
     5322        SCVAL(state->setup + 3, 0, 0); /* isFsctl */
     5323        SCVAL(state->setup + 3, 1, 0); /* compfilter, isFlags (WSSP) */
     5324
     5325        subreq = cli_trans_send(
     5326                state, ev, cli, SMBnttrans, NULL, 0, NT_TRANSACT_IOCTL, 0,
     5327                state->setup, ARRAY_SIZE(state->setup), 0,
     5328                NULL, 0, 0,
     5329                NULL, 0, ret_size);
     5330        if (tevent_req_nomem(subreq, req)) {
     5331                return tevent_req_post(req, ev);
     5332        }
     5333        tevent_req_set_callback(subreq, cli_shadow_copy_data_done, req);
     5334        return req;
     5335}
     5336
     5337static void cli_shadow_copy_data_done(struct tevent_req *subreq)
     5338{
     5339        struct tevent_req *req = tevent_req_callback_data(
     5340                subreq, struct tevent_req);
     5341        struct cli_shadow_copy_data_state *state = tevent_req_data(
     5342                req, struct cli_shadow_copy_data_state);
     5343        NTSTATUS status;
     5344
     5345        status = cli_trans_recv(subreq, state, NULL,
     5346                                NULL, 0, NULL, /* setup */
     5347                                NULL, 0, NULL, /* param */
     5348                                &state->data, 12, &state->num_data);
     5349        TALLOC_FREE(subreq);
     5350        if (tevent_req_nterror(req, status)) {
     5351                return;
     5352        }
     5353        tevent_req_done(req);
     5354}
     5355
     5356NTSTATUS cli_shadow_copy_data_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
     5357                                   char ***pnames, int *pnum_names)
     5358{
     5359        struct cli_shadow_copy_data_state *state = tevent_req_data(
     5360                req, struct cli_shadow_copy_data_state);
     5361        char **names;
     5362        int i, num_names;
     5363        uint32_t dlength;
     5364        NTSTATUS status;
     5365
     5366        if (tevent_req_is_nterror(req, &status)) {
     5367                return status;
     5368        }
     5369        num_names = IVAL(state->data, 4);
     5370        dlength = IVAL(state->data, 8);
     5371
     5372        if (!state->get_names) {
     5373                *pnum_names = num_names;
     5374                return NT_STATUS_OK;
     5375        }
     5376
     5377        if (dlength+12 > state->num_data) {
     5378                return NT_STATUS_INVALID_NETWORK_RESPONSE;
     5379        }
     5380        names = talloc_array(mem_ctx, char *, num_names);
     5381        if (names == NULL) {
     5382                return NT_STATUS_NO_MEMORY;
     5383        }
     5384
     5385        for (i=0; i<num_names; i++) {
     5386                bool ret;
     5387                uint8_t *src;
     5388                size_t converted_size;
     5389
     5390                src = state->data + 12 + i * 2 * sizeof(SHADOW_COPY_LABEL);
     5391                ret = convert_string_talloc(
     5392                        names, CH_UTF16LE, CH_UNIX,
     5393                        src, 2 * sizeof(SHADOW_COPY_LABEL),
     5394                        &names[i], &converted_size, True);
     5395                if (!ret) {
     5396                        TALLOC_FREE(names);
     5397                        return NT_STATUS_INVALID_NETWORK_RESPONSE;
     5398                }
     5399        }
     5400        *pnum_names = num_names;
     5401        *pnames = names;
     5402        return NT_STATUS_OK;
     5403}
     5404
     5405NTSTATUS cli_shadow_copy_data(TALLOC_CTX *mem_ctx, struct cli_state *cli,
     5406                              uint16_t fnum, bool get_names,
     5407                              char ***pnames, int *pnum_names)
     5408{
     5409        TALLOC_CTX *frame = talloc_stackframe();
     5410        struct event_context *ev;
     5411        struct tevent_req *req;
     5412        NTSTATUS status = NT_STATUS_NO_MEMORY;
     5413
     5414        if (cli_has_async_calls(cli)) {
     5415                /*
     5416                 * Can't use sync call while an async call is in flight
     5417                 */
     5418                status = NT_STATUS_INVALID_PARAMETER;
     5419                goto fail;
     5420        }
     5421        ev = event_context_init(frame);
     5422        if (ev == NULL) {
     5423                goto fail;
     5424        }
     5425        req = cli_shadow_copy_data_send(frame, ev, cli, fnum, get_names);
     5426        if (req == NULL) {
     5427                goto fail;
     5428        }
     5429        if (!tevent_req_poll_ntstatus(req, ev, &status)) {
     5430                goto fail;
     5431        }
     5432        status = cli_shadow_copy_data_recv(req, mem_ctx, pnames, pnum_names);
     5433 fail:
     5434        TALLOC_FREE(frame);
     5435        if (!NT_STATUS_IS_OK(status)) {
     5436                cli_set_error(cli, status);
     5437        }
     5438        return status;
     5439}
Note: See TracChangeset for help on using the changeset viewer.