root/source4/libcli/raw/rawfile.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. attrib_string
  2. smb_raw_rename_send
  3. smb_raw_rename
  4. smb_raw_unlink_send
  5. smb_raw_unlink
  6. smb_raw_t2mkdir_send
  7. smb_raw_mkdir_send
  8. smb_raw_mkdir
  9. smb_raw_rmdir_send
  10. smb_raw_rmdir
  11. smb_raw_nttrans_create_recv
  12. smb_raw_nttrans_create_send
  13. smb_raw_t2open_send
  14. smb_raw_t2open_recv
  15. smb_raw_open_send
  16. smb_raw_open_recv
  17. smb_raw_open
  18. smb_raw_close_send
  19. smb_raw_close
  20. smb_raw_lock_send
  21. smb_raw_lock
  22. smb_raw_chkpath_send
  23. smb_raw_chkpath
  24. smb_raw_flush_send
  25. smb_raw_flush
  26. smb_raw_seek_send
  27. smb_raw_seek_recv
  28. smb_raw_seek

   1 /* 
   2    Unix SMB/CIFS implementation.
   3    client file operations
   4    Copyright (C) Andrew Tridgell 1994-1998
   5    Copyright (C) Jeremy Allison 2001-2002
   6    Copyright (C) James Myers 2003
   7    
   8    This program is free software; you can redistribute it and/or modify
   9    it under the terms of the GNU General Public License as published by
  10    the Free Software Foundation; either version 3 of the License, or
  11    (at your option) any later version.
  12    
  13    This program is distributed in the hope that it will be useful,
  14    but WITHOUT ANY WARRANTY; without even the implied warranty of
  15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16    GNU General Public License for more details.
  17    
  18    You should have received a copy of the GNU General Public License
  19    along with this program.  If not, see <http://www.gnu.org/licenses/>.
  20 */
  21 
  22 #include "includes.h"
  23 #include "smb.h"
  24 #include "libcli/raw/libcliraw.h"
  25 #include "libcli/raw/raw_proto.h"
  26 #include "librpc/gen_ndr/ndr_security.h"
  27 
  28 #define SETUP_REQUEST(cmd, wct, buflen) do { \
  29         req = smbcli_request_setup(tree, cmd, wct, buflen); \
  30         if (!req) return NULL; \
  31 } while (0)
  32 
  33 /**
  34  Return a string representing a CIFS attribute for a file.
  35 **/
  36 char *attrib_string(TALLOC_CTX *mem_ctx, uint32_t attrib)
     /* [<][>][^][v][top][bottom][index][help] */
  37 {
  38         int i, len;
  39         const struct {
  40                 char c;
  41                 uint16_t attr;
  42         } attr_strs[] = {
  43                 {'V', FILE_ATTRIBUTE_VOLUME},
  44                 {'D', FILE_ATTRIBUTE_DIRECTORY},
  45                 {'A', FILE_ATTRIBUTE_ARCHIVE},
  46                 {'H', FILE_ATTRIBUTE_HIDDEN},
  47                 {'S', FILE_ATTRIBUTE_SYSTEM},
  48                 {'N', FILE_ATTRIBUTE_NORMAL},
  49                 {'R', FILE_ATTRIBUTE_READONLY},
  50                 {'d', FILE_ATTRIBUTE_DEVICE},
  51                 {'t', FILE_ATTRIBUTE_TEMPORARY},
  52                 {'s', FILE_ATTRIBUTE_SPARSE},
  53                 {'r', FILE_ATTRIBUTE_REPARSE_POINT},
  54                 {'c', FILE_ATTRIBUTE_COMPRESSED},
  55                 {'o', FILE_ATTRIBUTE_OFFLINE},
  56                 {'n', FILE_ATTRIBUTE_NONINDEXED},
  57                 {'e', FILE_ATTRIBUTE_ENCRYPTED}
  58         };
  59         char *ret;
  60 
  61         ret = talloc_array(mem_ctx, char, ARRAY_SIZE(attr_strs)+1);
  62         if (!ret) {
  63                 return NULL;
  64         }
  65 
  66         for (len=i=0; i<ARRAY_SIZE(attr_strs); i++) {
  67                 if (attrib & attr_strs[i].attr) {
  68                         ret[len++] = attr_strs[i].c;
  69                 }
  70         }
  71 
  72         ret[len] = 0;
  73 
  74         talloc_set_name_const(ret, ret);
  75 
  76         return ret;
  77 }
  78 
  79 /****************************************************************************
  80  Rename a file - async interface
  81 ****************************************************************************/
  82 struct smbcli_request *smb_raw_rename_send(struct smbcli_tree *tree,
     /* [<][>][^][v][top][bottom][index][help] */
  83                                         union smb_rename *parms)
  84 {
  85         struct smbcli_request *req = NULL; 
  86         struct smb_nttrans nt;
  87         TALLOC_CTX *mem_ctx;
  88 
  89         switch (parms->generic.level) {
  90         case RAW_RENAME_RENAME:
  91                 SETUP_REQUEST(SMBmv, 1, 0);
  92                 SSVAL(req->out.vwv, VWV(0), parms->rename.in.attrib);
  93                 smbcli_req_append_ascii4(req, parms->rename.in.pattern1, STR_TERMINATE);
  94                 smbcli_req_append_ascii4(req, parms->rename.in.pattern2, STR_TERMINATE);
  95                 break;
  96 
  97         case RAW_RENAME_NTRENAME:
  98                 SETUP_REQUEST(SMBntrename, 4, 0);
  99                 SSVAL(req->out.vwv, VWV(0), parms->ntrename.in.attrib);
 100                 SSVAL(req->out.vwv, VWV(1), parms->ntrename.in.flags);
 101                 SIVAL(req->out.vwv, VWV(2), parms->ntrename.in.cluster_size);
 102                 smbcli_req_append_ascii4(req, parms->ntrename.in.old_name, STR_TERMINATE);
 103                 smbcli_req_append_ascii4(req, parms->ntrename.in.new_name, STR_TERMINATE);
 104                 break;
 105 
 106         case RAW_RENAME_NTTRANS:
 107 
 108                 mem_ctx = talloc_new(tree);
 109 
 110                 nt.in.max_setup = 0;
 111                 nt.in.max_param = 0;
 112                 nt.in.max_data = 0;
 113                 nt.in.setup_count = 0;
 114                 nt.in.setup = NULL;
 115                 nt.in.function = NT_TRANSACT_RENAME;
 116                 nt.in.params = data_blob_talloc(mem_ctx, NULL, 4);
 117                 nt.in.data = data_blob(NULL, 0);
 118 
 119                 SSVAL(nt.in.params.data, VWV(0), parms->nttrans.in.file.fnum);
 120                 SSVAL(nt.in.params.data, VWV(1), parms->nttrans.in.flags);
 121 
 122                 smbcli_blob_append_string(tree->session, mem_ctx,
 123                                           &nt.in.params, parms->nttrans.in.new_name,
 124                                           STR_TERMINATE);
 125 
 126                 req = smb_raw_nttrans_send(tree, &nt);
 127                 talloc_free(mem_ctx);
 128                 return req;
 129         }
 130 
 131         if (!smbcli_request_send(req)) {
 132                 smbcli_request_destroy(req);
 133                 return NULL;
 134         }
 135 
 136         return req;
 137 }
 138 
 139 /****************************************************************************
 140  Rename a file - sync interface
 141 ****************************************************************************/
 142 _PUBLIC_ NTSTATUS smb_raw_rename(struct smbcli_tree *tree,
     /* [<][>][^][v][top][bottom][index][help] */
 143                         union smb_rename *parms)
 144 {
 145         struct smbcli_request *req = smb_raw_rename_send(tree, parms);
 146         return smbcli_request_simple_recv(req);
 147 }
 148 
 149 
 150 /****************************************************************************
 151  Delete a file - async interface
 152 ****************************************************************************/
 153 struct smbcli_request *smb_raw_unlink_send(struct smbcli_tree *tree,
     /* [<][>][^][v][top][bottom][index][help] */
 154                                            union smb_unlink *parms)
 155 {
 156         struct smbcli_request *req; 
 157 
 158         SETUP_REQUEST(SMBunlink, 1, 0);
 159 
 160         SSVAL(req->out.vwv, VWV(0), parms->unlink.in.attrib);
 161         smbcli_req_append_ascii4(req, parms->unlink.in.pattern, STR_TERMINATE);
 162 
 163         if (!smbcli_request_send(req)) {
 164                 smbcli_request_destroy(req);
 165                 return NULL;
 166         }
 167         return req;
 168 }
 169 
 170 /*
 171   delete a file - sync interface
 172 */
 173 _PUBLIC_ NTSTATUS smb_raw_unlink(struct smbcli_tree *tree,
     /* [<][>][^][v][top][bottom][index][help] */
 174                         union smb_unlink *parms)
 175 {
 176         struct smbcli_request *req = smb_raw_unlink_send(tree, parms);
 177         return smbcli_request_simple_recv(req);
 178 }
 179 
 180 
 181 /****************************************************************************
 182  create a directory  using TRANSACT2_MKDIR - async interface
 183 ****************************************************************************/
 184 static struct smbcli_request *smb_raw_t2mkdir_send(struct smbcli_tree *tree, 
     /* [<][>][^][v][top][bottom][index][help] */
 185                                                 union smb_mkdir *parms)
 186 {
 187         struct smb_trans2 t2;
 188         uint16_t setup = TRANSACT2_MKDIR;
 189         TALLOC_CTX *mem_ctx;
 190         struct smbcli_request *req;
 191         uint16_t data_total;
 192 
 193         mem_ctx = talloc_init("t2mkdir");
 194 
 195         data_total = ea_list_size(parms->t2mkdir.in.num_eas, parms->t2mkdir.in.eas);
 196 
 197         t2.in.max_param = 2;
 198         t2.in.max_data = 0;
 199         t2.in.max_setup = 0;
 200         t2.in.flags = 0;
 201         t2.in.timeout = 0;
 202         t2.in.setup_count = 1;
 203         t2.in.setup = &setup;
 204         t2.in.params = data_blob_talloc(mem_ctx, NULL, 4);
 205         t2.in.data = data_blob_talloc(mem_ctx, NULL, data_total);
 206 
 207         SIVAL(t2.in.params.data, VWV(0), 0); /* reserved */
 208 
 209         smbcli_blob_append_string(tree->session, mem_ctx, 
 210                                   &t2.in.params, parms->t2mkdir.in.path, STR_TERMINATE);
 211 
 212         ea_put_list(t2.in.data.data, parms->t2mkdir.in.num_eas, parms->t2mkdir.in.eas);
 213 
 214         req = smb_raw_trans2_send(tree, &t2);
 215 
 216         talloc_free(mem_ctx);
 217 
 218         return req;
 219 }
 220 
 221 /****************************************************************************
 222  Create a directory - async interface
 223 ****************************************************************************/
 224 struct smbcli_request *smb_raw_mkdir_send(struct smbcli_tree *tree,
     /* [<][>][^][v][top][bottom][index][help] */
 225                                        union smb_mkdir *parms)
 226 {
 227         struct smbcli_request *req; 
 228 
 229         if (parms->generic.level == RAW_MKDIR_T2MKDIR) {
 230                 return smb_raw_t2mkdir_send(tree, parms);
 231         }
 232 
 233         if (parms->generic.level != RAW_MKDIR_MKDIR) {
 234                 return NULL;
 235         }
 236 
 237         SETUP_REQUEST(SMBmkdir, 0, 0);
 238         
 239         smbcli_req_append_ascii4(req, parms->mkdir.in.path, STR_TERMINATE);
 240 
 241         if (!smbcli_request_send(req)) {
 242                 return NULL;
 243         }
 244 
 245         return req;
 246 }
 247 
 248 /****************************************************************************
 249  Create a directory - sync interface
 250 ****************************************************************************/
 251 _PUBLIC_ NTSTATUS smb_raw_mkdir(struct smbcli_tree *tree,
     /* [<][>][^][v][top][bottom][index][help] */
 252                        union smb_mkdir *parms)
 253 {
 254         struct smbcli_request *req = smb_raw_mkdir_send(tree, parms);
 255         return smbcli_request_simple_recv(req);
 256 }
 257 
 258 /****************************************************************************
 259  Remove a directory - async interface
 260 ****************************************************************************/
 261 struct smbcli_request *smb_raw_rmdir_send(struct smbcli_tree *tree,
     /* [<][>][^][v][top][bottom][index][help] */
 262                                        struct smb_rmdir *parms)
 263 {
 264         struct smbcli_request *req; 
 265 
 266         SETUP_REQUEST(SMBrmdir, 0, 0);
 267         
 268         smbcli_req_append_ascii4(req, parms->in.path, STR_TERMINATE);
 269 
 270         if (!smbcli_request_send(req)) {
 271                 smbcli_request_destroy(req);
 272                 return NULL;
 273         }
 274 
 275         return req;
 276 }
 277 
 278 /****************************************************************************
 279  Remove a directory - sync interface
 280 ****************************************************************************/
 281 _PUBLIC_ NTSTATUS smb_raw_rmdir(struct smbcli_tree *tree,
     /* [<][>][^][v][top][bottom][index][help] */
 282                        struct smb_rmdir *parms)
 283 {
 284         struct smbcli_request *req = smb_raw_rmdir_send(tree, parms);
 285         return smbcli_request_simple_recv(req);
 286 }
 287 
 288 
 289 /*
 290  Open a file using TRANSACT2_OPEN - async recv
 291 */
 292 static NTSTATUS smb_raw_nttrans_create_recv(struct smbcli_request *req, 
     /* [<][>][^][v][top][bottom][index][help] */
 293                                             TALLOC_CTX *mem_ctx, 
 294                                             union smb_open *parms)
 295 {
 296         NTSTATUS status;
 297         struct smb_nttrans nt;
 298         uint8_t *params;
 299 
 300         status = smb_raw_nttrans_recv(req, mem_ctx, &nt);
 301         if (!NT_STATUS_IS_OK(status)) return status;
 302 
 303         if (nt.out.params.length < 69) {
 304                 return NT_STATUS_INVALID_PARAMETER;
 305         }
 306 
 307         params = nt.out.params.data;
 308 
 309         parms->ntcreatex.out.oplock_level =                 CVAL(params, 0);
 310         parms->ntcreatex.out.file.fnum =                    SVAL(params, 2);
 311         parms->ntcreatex.out.create_action =                IVAL(params, 4);
 312         parms->ntcreatex.out.create_time =   smbcli_pull_nttime(params, 12);
 313         parms->ntcreatex.out.access_time =   smbcli_pull_nttime(params, 20);
 314         parms->ntcreatex.out.write_time =    smbcli_pull_nttime(params, 28);
 315         parms->ntcreatex.out.change_time =   smbcli_pull_nttime(params, 36);
 316         parms->ntcreatex.out.attrib =                      IVAL(params, 44);
 317         parms->ntcreatex.out.alloc_size =                  BVAL(params, 48);
 318         parms->ntcreatex.out.size =                        BVAL(params, 56);
 319         parms->ntcreatex.out.file_type =                   SVAL(params, 64);
 320         parms->ntcreatex.out.ipc_state =                   SVAL(params, 66);
 321         parms->ntcreatex.out.is_directory =                CVAL(params, 68);
 322         
 323         return NT_STATUS_OK;
 324 }
 325 
 326 
 327 /*
 328  Open a file using NTTRANS CREATE - async send 
 329 */
 330 static struct smbcli_request *smb_raw_nttrans_create_send(struct smbcli_tree *tree, 
     /* [<][>][^][v][top][bottom][index][help] */
 331                                                           union smb_open *parms)
 332 {
 333         struct smb_nttrans nt;
 334         uint8_t *params;
 335         TALLOC_CTX *mem_ctx = talloc_new(tree);
 336         uint16_t fname_len;
 337         DATA_BLOB sd_blob, ea_blob;
 338         struct smbcli_request *req;
 339 
 340         nt.in.max_setup = 0;
 341         nt.in.max_param = 101;
 342         nt.in.max_data  = 0;
 343         nt.in.setup_count = 0;
 344         nt.in.function = NT_TRANSACT_CREATE;
 345         nt.in.setup = NULL;
 346 
 347         sd_blob = data_blob(NULL, 0);
 348         ea_blob = data_blob(NULL, 0);
 349 
 350         if (parms->ntcreatex.in.sec_desc) {
 351                 enum ndr_err_code ndr_err;
 352                 ndr_err = ndr_push_struct_blob(&sd_blob, mem_ctx, NULL,
 353                                                parms->ntcreatex.in.sec_desc,
 354                                                (ndr_push_flags_fn_t)ndr_push_security_descriptor);
 355                 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
 356                         talloc_free(mem_ctx);
 357                         return NULL;
 358                 }
 359         }
 360 
 361         if (parms->ntcreatex.in.ea_list) {
 362                 uint32_t ea_size = ea_list_size_chained(parms->ntcreatex.in.ea_list->num_eas,
 363                                                         parms->ntcreatex.in.ea_list->eas, 4);
 364                 ea_blob = data_blob_talloc(mem_ctx, NULL, ea_size);
 365                 if (ea_blob.data == NULL) {
 366                         return NULL;
 367                 }
 368                 ea_put_list_chained(ea_blob.data, 
 369                                     parms->ntcreatex.in.ea_list->num_eas,
 370                                     parms->ntcreatex.in.ea_list->eas, 4);
 371         }
 372 
 373         nt.in.params = data_blob_talloc(mem_ctx, NULL, 53);
 374         if (nt.in.params.data == NULL) {
 375                 talloc_free(mem_ctx);
 376                 return NULL;
 377         }
 378 
 379         /* build the parameter section */
 380         params = nt.in.params.data;
 381 
 382         SIVAL(params,  0, parms->ntcreatex.in.flags);
 383         SIVAL(params,  4, parms->ntcreatex.in.root_fid);
 384         SIVAL(params,  8, parms->ntcreatex.in.access_mask);
 385         SBVAL(params, 12, parms->ntcreatex.in.alloc_size);
 386         SIVAL(params, 20, parms->ntcreatex.in.file_attr);
 387         SIVAL(params, 24, parms->ntcreatex.in.share_access);
 388         SIVAL(params, 28, parms->ntcreatex.in.open_disposition);
 389         SIVAL(params, 32, parms->ntcreatex.in.create_options);
 390         SIVAL(params, 36, sd_blob.length);
 391         SIVAL(params, 40, ea_blob.length);
 392         SIVAL(params, 48, parms->ntcreatex.in.impersonation);
 393         SCVAL(params, 52, parms->ntcreatex.in.security_flags);
 394 
 395         /* the empty string first forces the correct alignment */
 396         smbcli_blob_append_string(tree->session, mem_ctx, &nt.in.params,"", 0);
 397         fname_len = smbcli_blob_append_string(tree->session, mem_ctx, &nt.in.params,
 398                                               parms->ntcreatex.in.fname, STR_TERMINATE);
 399 
 400         SIVAL(nt.in.params.data, 44, fname_len);
 401 
 402         /* build the data section */
 403         nt.in.data = data_blob_talloc(mem_ctx, NULL, sd_blob.length + ea_blob.length);
 404         memcpy(nt.in.data.data, sd_blob.data, sd_blob.length);
 405         memcpy(nt.in.data.data+sd_blob.length, ea_blob.data, ea_blob.length);
 406 
 407         /* send the request on its way */
 408         req = smb_raw_nttrans_send(tree, &nt);
 409 
 410         talloc_free(mem_ctx);
 411         
 412         return req;
 413 }
 414 
 415 
 416 /****************************************************************************
 417  Open a file using TRANSACT2_OPEN - async send 
 418 ****************************************************************************/
 419 static struct smbcli_request *smb_raw_t2open_send(struct smbcli_tree *tree, 
     /* [<][>][^][v][top][bottom][index][help] */
 420                                                union smb_open *parms)
 421 {
 422         struct smb_trans2 t2;
 423         uint16_t setup = TRANSACT2_OPEN;
 424         TALLOC_CTX *mem_ctx = talloc_init("smb_raw_t2open");
 425         struct smbcli_request *req;
 426         uint16_t list_size;
 427 
 428         list_size = ea_list_size(parms->t2open.in.num_eas, parms->t2open.in.eas);
 429 
 430         t2.in.max_param = 30;
 431         t2.in.max_data = 0;
 432         t2.in.max_setup = 0;
 433         t2.in.flags = 0;
 434         t2.in.timeout = 0;
 435         t2.in.setup_count = 1;
 436         t2.in.setup = &setup;
 437         t2.in.params = data_blob_talloc(mem_ctx, NULL, 28);
 438         t2.in.data = data_blob_talloc(mem_ctx, NULL, list_size);
 439 
 440         SSVAL(t2.in.params.data, VWV(0), parms->t2open.in.flags);
 441         SSVAL(t2.in.params.data, VWV(1), parms->t2open.in.open_mode);
 442         SSVAL(t2.in.params.data, VWV(2), parms->t2open.in.search_attrs);
 443         SSVAL(t2.in.params.data, VWV(3), parms->t2open.in.file_attrs);
 444         raw_push_dos_date(tree->session->transport, 
 445                           t2.in.params.data, VWV(4), parms->t2open.in.write_time);
 446         SSVAL(t2.in.params.data, VWV(6), parms->t2open.in.open_func);
 447         SIVAL(t2.in.params.data, VWV(7), parms->t2open.in.size);
 448         SIVAL(t2.in.params.data, VWV(9), parms->t2open.in.timeout);
 449         SIVAL(t2.in.params.data, VWV(11), 0);
 450         SSVAL(t2.in.params.data, VWV(13), 0);
 451 
 452         smbcli_blob_append_string(tree->session, mem_ctx, 
 453                                   &t2.in.params, parms->t2open.in.fname, 
 454                                   STR_TERMINATE);
 455 
 456         ea_put_list(t2.in.data.data, parms->t2open.in.num_eas, parms->t2open.in.eas);
 457 
 458         req = smb_raw_trans2_send(tree, &t2);
 459 
 460         talloc_free(mem_ctx);
 461 
 462         return req;
 463 }
 464 
 465 
 466 /****************************************************************************
 467  Open a file using TRANSACT2_OPEN - async recv
 468 ****************************************************************************/
 469 static NTSTATUS smb_raw_t2open_recv(struct smbcli_request *req, TALLOC_CTX *mem_ctx, union smb_open *parms)
     /* [<][>][^][v][top][bottom][index][help] */
 470 {
 471         struct smbcli_transport *transport = req->transport;
 472         struct smb_trans2 t2;
 473         NTSTATUS status;
 474 
 475         status = smb_raw_trans2_recv(req, mem_ctx, &t2);
 476         if (!NT_STATUS_IS_OK(status)) return status;
 477 
 478         if (t2.out.params.length < 30) {
 479                 return NT_STATUS_INFO_LENGTH_MISMATCH;
 480         }
 481 
 482         parms->t2open.out.file.fnum =   SVAL(t2.out.params.data, VWV(0));
 483         parms->t2open.out.attrib =      SVAL(t2.out.params.data, VWV(1));
 484         parms->t2open.out.write_time =  raw_pull_dos_date3(transport, t2.out.params.data + VWV(2));
 485         parms->t2open.out.size =        IVAL(t2.out.params.data, VWV(4));
 486         parms->t2open.out.access =      SVAL(t2.out.params.data, VWV(6));
 487         parms->t2open.out.ftype =       SVAL(t2.out.params.data, VWV(7));
 488         parms->t2open.out.devstate =    SVAL(t2.out.params.data, VWV(8));
 489         parms->t2open.out.action =      SVAL(t2.out.params.data, VWV(9));
 490         parms->t2open.out.file_id =     SVAL(t2.out.params.data, VWV(10));
 491 
 492         return NT_STATUS_OK;
 493 }
 494 
 495 /****************************************************************************
 496  Open a file - async send
 497 ****************************************************************************/
 498 _PUBLIC_ struct smbcli_request *smb_raw_open_send(struct smbcli_tree *tree, union smb_open *parms)
     /* [<][>][^][v][top][bottom][index][help] */
 499 {
 500         int len;
 501         struct smbcli_request *req = NULL; 
 502         bool bigoffset = false;
 503 
 504         switch (parms->generic.level) {
 505         case RAW_OPEN_T2OPEN:
 506                 return smb_raw_t2open_send(tree, parms);
 507 
 508         case RAW_OPEN_OPEN:
 509                 SETUP_REQUEST(SMBopen, 2, 0);
 510                 SSVAL(req->out.vwv, VWV(0), parms->openold.in.open_mode);
 511                 SSVAL(req->out.vwv, VWV(1), parms->openold.in.search_attrs);
 512                 smbcli_req_append_ascii4(req, parms->openold.in.fname, STR_TERMINATE);
 513                 break;
 514                 
 515         case RAW_OPEN_OPENX:
 516                 SETUP_REQUEST(SMBopenX, 15, 0);
 517                 SSVAL(req->out.vwv, VWV(0), SMB_CHAIN_NONE);
 518                 SSVAL(req->out.vwv, VWV(1), 0);
 519                 SSVAL(req->out.vwv, VWV(2), parms->openx.in.flags);
 520                 SSVAL(req->out.vwv, VWV(3), parms->openx.in.open_mode);
 521                 SSVAL(req->out.vwv, VWV(4), parms->openx.in.search_attrs);
 522                 SSVAL(req->out.vwv, VWV(5), parms->openx.in.file_attrs);
 523                 raw_push_dos_date3(tree->session->transport, 
 524                                   req->out.vwv, VWV(6), parms->openx.in.write_time);
 525                 SSVAL(req->out.vwv, VWV(8), parms->openx.in.open_func);
 526                 SIVAL(req->out.vwv, VWV(9), parms->openx.in.size);
 527                 SIVAL(req->out.vwv, VWV(11),parms->openx.in.timeout);
 528                 SIVAL(req->out.vwv, VWV(13),0); /* reserved */
 529                 smbcli_req_append_string(req, parms->openx.in.fname, STR_TERMINATE);
 530                 break;
 531                 
 532         case RAW_OPEN_MKNEW:
 533                 SETUP_REQUEST(SMBmknew, 3, 0);
 534                 SSVAL(req->out.vwv, VWV(0), parms->mknew.in.attrib);
 535                 raw_push_dos_date3(tree->session->transport, 
 536                                   req->out.vwv, VWV(1), parms->mknew.in.write_time);
 537                 smbcli_req_append_ascii4(req, parms->mknew.in.fname, STR_TERMINATE);
 538                 break;
 539 
 540         case RAW_OPEN_CREATE:
 541                 SETUP_REQUEST(SMBcreate, 3, 0);
 542                 SSVAL(req->out.vwv, VWV(0), parms->create.in.attrib);
 543                 raw_push_dos_date3(tree->session->transport, 
 544                                   req->out.vwv, VWV(1), parms->create.in.write_time);
 545                 smbcli_req_append_ascii4(req, parms->create.in.fname, STR_TERMINATE);
 546                 break;
 547                 
 548         case RAW_OPEN_CTEMP:
 549                 SETUP_REQUEST(SMBctemp, 3, 0);
 550                 SSVAL(req->out.vwv, VWV(0), parms->ctemp.in.attrib);
 551                 raw_push_dos_date3(tree->session->transport, 
 552                                   req->out.vwv, VWV(1), parms->ctemp.in.write_time);
 553                 smbcli_req_append_ascii4(req, parms->ctemp.in.directory, STR_TERMINATE);
 554                 break;
 555                 
 556         case RAW_OPEN_SPLOPEN:
 557                 SETUP_REQUEST(SMBsplopen, 2, 0);
 558                 SSVAL(req->out.vwv, VWV(0), parms->splopen.in.setup_length);
 559                 SSVAL(req->out.vwv, VWV(1), parms->splopen.in.mode);
 560                 break;
 561                 
 562         case RAW_OPEN_NTCREATEX:
 563                 SETUP_REQUEST(SMBntcreateX, 24, 0);
 564                 SSVAL(req->out.vwv, VWV(0),SMB_CHAIN_NONE);
 565                 SSVAL(req->out.vwv, VWV(1),0);
 566                 SCVAL(req->out.vwv, VWV(2),0); /* padding */
 567                 SIVAL(req->out.vwv,  7, parms->ntcreatex.in.flags);
 568                 SIVAL(req->out.vwv, 11, parms->ntcreatex.in.root_fid);
 569                 SIVAL(req->out.vwv, 15, parms->ntcreatex.in.access_mask);
 570                 SBVAL(req->out.vwv, 19, parms->ntcreatex.in.alloc_size);
 571                 SIVAL(req->out.vwv, 27, parms->ntcreatex.in.file_attr);
 572                 SIVAL(req->out.vwv, 31, parms->ntcreatex.in.share_access);
 573                 SIVAL(req->out.vwv, 35, parms->ntcreatex.in.open_disposition);
 574                 SIVAL(req->out.vwv, 39, parms->ntcreatex.in.create_options);
 575                 SIVAL(req->out.vwv, 43, parms->ntcreatex.in.impersonation);
 576                 SCVAL(req->out.vwv, 47, parms->ntcreatex.in.security_flags);
 577                 
 578                 smbcli_req_append_string_len(req, parms->ntcreatex.in.fname, STR_TERMINATE, &len);
 579                 SSVAL(req->out.vwv, 5, len);
 580                 break;
 581 
 582         case RAW_OPEN_NTTRANS_CREATE:
 583                 return smb_raw_nttrans_create_send(tree, parms);
 584 
 585 
 586         case RAW_OPEN_OPENX_READX:
 587                 SETUP_REQUEST(SMBopenX, 15, 0);
 588                 SSVAL(req->out.vwv, VWV(0), SMB_CHAIN_NONE);
 589                 SSVAL(req->out.vwv, VWV(1), 0);
 590                 SSVAL(req->out.vwv, VWV(2), parms->openxreadx.in.flags);
 591                 SSVAL(req->out.vwv, VWV(3), parms->openxreadx.in.open_mode);
 592                 SSVAL(req->out.vwv, VWV(4), parms->openxreadx.in.search_attrs);
 593                 SSVAL(req->out.vwv, VWV(5), parms->openxreadx.in.file_attrs);
 594                 raw_push_dos_date3(tree->session->transport, 
 595                                   req->out.vwv, VWV(6), parms->openxreadx.in.write_time);
 596                 SSVAL(req->out.vwv, VWV(8), parms->openxreadx.in.open_func);
 597                 SIVAL(req->out.vwv, VWV(9), parms->openxreadx.in.size);
 598                 SIVAL(req->out.vwv, VWV(11),parms->openxreadx.in.timeout);
 599                 SIVAL(req->out.vwv, VWV(13),0);
 600                 smbcli_req_append_string(req, parms->openxreadx.in.fname, STR_TERMINATE);
 601 
 602                 if (tree->session->transport->negotiate.capabilities & CAP_LARGE_FILES) {
 603                         bigoffset = true;
 604                 }
 605 
 606                 smbcli_chained_request_setup(req, SMBreadX, bigoffset ? 12 : 10, 0);
 607 
 608                 SSVAL(req->out.vwv, VWV(0), SMB_CHAIN_NONE);
 609                 SSVAL(req->out.vwv, VWV(1), 0);
 610                 SSVAL(req->out.vwv, VWV(2), 0);
 611                 SIVAL(req->out.vwv, VWV(3), parms->openxreadx.in.offset);
 612                 SSVAL(req->out.vwv, VWV(5), parms->openxreadx.in.maxcnt & 0xFFFF);
 613                 SSVAL(req->out.vwv, VWV(6), parms->openxreadx.in.mincnt);
 614                 SIVAL(req->out.vwv, VWV(7), parms->openxreadx.in.maxcnt >> 16);
 615                 SSVAL(req->out.vwv, VWV(9), parms->openxreadx.in.remaining);
 616                 if (bigoffset) {
 617                         SIVAL(req->out.vwv, VWV(10),parms->openxreadx.in.offset>>32);
 618                 }
 619                 break;
 620         case RAW_OPEN_SMB2:
 621                 return NULL;
 622         }
 623 
 624         if (!smbcli_request_send(req)) {
 625                 smbcli_request_destroy(req);
 626                 return NULL;
 627         }
 628 
 629         return req;
 630 }
 631 
 632 /****************************************************************************
 633  Open a file - async recv
 634 ****************************************************************************/
 635 _PUBLIC_ NTSTATUS smb_raw_open_recv(struct smbcli_request *req, TALLOC_CTX *mem_ctx, union smb_open *parms)
     /* [<][>][^][v][top][bottom][index][help] */
 636 {
 637         NTSTATUS status;
 638 
 639         if (!smbcli_request_receive(req) ||
 640             smbcli_request_is_error(req)) {
 641                 goto failed;
 642         }
 643 
 644         switch (parms->openold.level) {
 645         case RAW_OPEN_T2OPEN:
 646                 return smb_raw_t2open_recv(req, mem_ctx, parms);
 647 
 648         case RAW_OPEN_OPEN:
 649                 SMBCLI_CHECK_WCT(req, 7);
 650                 parms->openold.out.file.fnum = SVAL(req->in.vwv, VWV(0));
 651                 parms->openold.out.attrib = SVAL(req->in.vwv, VWV(1));
 652                 parms->openold.out.write_time = raw_pull_dos_date3(req->transport,
 653                                                                 req->in.vwv + VWV(2));
 654                 parms->openold.out.size = IVAL(req->in.vwv, VWV(4));
 655                 parms->openold.out.rmode = SVAL(req->in.vwv, VWV(6));
 656                 break;
 657 
 658         case RAW_OPEN_OPENX:
 659                 SMBCLI_CHECK_MIN_WCT(req, 15);
 660                 parms->openx.out.file.fnum = SVAL(req->in.vwv, VWV(2));
 661                 parms->openx.out.attrib = SVAL(req->in.vwv, VWV(3));
 662                 parms->openx.out.write_time = raw_pull_dos_date3(req->transport,
 663                                                                  req->in.vwv + VWV(4));
 664                 parms->openx.out.size = IVAL(req->in.vwv, VWV(6));
 665                 parms->openx.out.access = SVAL(req->in.vwv, VWV(8));
 666                 parms->openx.out.ftype = SVAL(req->in.vwv, VWV(9));
 667                 parms->openx.out.devstate = SVAL(req->in.vwv, VWV(10));
 668                 parms->openx.out.action = SVAL(req->in.vwv, VWV(11));
 669                 parms->openx.out.unique_fid = IVAL(req->in.vwv, VWV(12));
 670                 if (req->in.wct >= 19) {
 671                         parms->openx.out.access_mask = IVAL(req->in.vwv, VWV(15));
 672                         parms->openx.out.unknown =     IVAL(req->in.vwv, VWV(17));
 673                 } else {
 674                         parms->openx.out.access_mask = 0;
 675                         parms->openx.out.unknown = 0;
 676                 }
 677                 break;
 678 
 679         case RAW_OPEN_MKNEW:
 680                 SMBCLI_CHECK_WCT(req, 1);
 681                 parms->mknew.out.file.fnum = SVAL(req->in.vwv, VWV(0));
 682                 break;
 683 
 684         case RAW_OPEN_CREATE:
 685                 SMBCLI_CHECK_WCT(req, 1);
 686                 parms->create.out.file.fnum = SVAL(req->in.vwv, VWV(0));
 687                 break;
 688 
 689         case RAW_OPEN_CTEMP:
 690                 SMBCLI_CHECK_WCT(req, 1);
 691                 parms->ctemp.out.file.fnum = SVAL(req->in.vwv, VWV(0));
 692                 smbcli_req_pull_string(&req->in.bufinfo, mem_ctx, &parms->ctemp.out.name, req->in.data, -1, STR_TERMINATE | STR_ASCII);
 693                 break;
 694 
 695         case RAW_OPEN_SPLOPEN:
 696                 SMBCLI_CHECK_WCT(req, 1);
 697                 parms->splopen.out.file.fnum = SVAL(req->in.vwv, VWV(0));
 698                 break;
 699 
 700         case RAW_OPEN_NTCREATEX:
 701                 SMBCLI_CHECK_MIN_WCT(req, 34);
 702                 parms->ntcreatex.out.oplock_level =              CVAL(req->in.vwv, 4);
 703                 parms->ntcreatex.out.file.fnum =                 SVAL(req->in.vwv, 5);
 704                 parms->ntcreatex.out.create_action =             IVAL(req->in.vwv, 7);
 705                 parms->ntcreatex.out.create_time =   smbcli_pull_nttime(req->in.vwv, 11);
 706                 parms->ntcreatex.out.access_time =   smbcli_pull_nttime(req->in.vwv, 19);
 707                 parms->ntcreatex.out.write_time =    smbcli_pull_nttime(req->in.vwv, 27);
 708                 parms->ntcreatex.out.change_time =   smbcli_pull_nttime(req->in.vwv, 35);
 709                 parms->ntcreatex.out.attrib =                   IVAL(req->in.vwv, 43);
 710                 parms->ntcreatex.out.alloc_size =               BVAL(req->in.vwv, 47);
 711                 parms->ntcreatex.out.size =                     BVAL(req->in.vwv, 55);
 712                 parms->ntcreatex.out.file_type =                SVAL(req->in.vwv, 63);
 713                 parms->ntcreatex.out.ipc_state =                SVAL(req->in.vwv, 65);
 714                 parms->ntcreatex.out.is_directory =             CVAL(req->in.vwv, 67);
 715                 break;
 716 
 717         case RAW_OPEN_NTTRANS_CREATE:
 718                 return smb_raw_nttrans_create_recv(req, mem_ctx, parms);
 719 
 720         case RAW_OPEN_OPENX_READX:
 721                 SMBCLI_CHECK_MIN_WCT(req, 15);
 722                 parms->openxreadx.out.file.fnum = SVAL(req->in.vwv, VWV(2));
 723                 parms->openxreadx.out.attrib = SVAL(req->in.vwv, VWV(3));
 724                 parms->openxreadx.out.write_time = raw_pull_dos_date3(req->transport,
 725                                                                  req->in.vwv + VWV(4));
 726                 parms->openxreadx.out.size = IVAL(req->in.vwv, VWV(6));
 727                 parms->openxreadx.out.access = SVAL(req->in.vwv, VWV(8));
 728                 parms->openxreadx.out.ftype = SVAL(req->in.vwv, VWV(9));
 729                 parms->openxreadx.out.devstate = SVAL(req->in.vwv, VWV(10));
 730                 parms->openxreadx.out.action = SVAL(req->in.vwv, VWV(11));
 731                 parms->openxreadx.out.unique_fid = IVAL(req->in.vwv, VWV(12));
 732                 if (req->in.wct >= 19) {
 733                         parms->openxreadx.out.access_mask = IVAL(req->in.vwv, VWV(15));
 734                         parms->openxreadx.out.unknown =     IVAL(req->in.vwv, VWV(17));
 735                 } else {
 736                         parms->openxreadx.out.access_mask = 0;
 737                         parms->openxreadx.out.unknown = 0;
 738                 }
 739 
 740                 status = smbcli_chained_advance(req);
 741                 if (!NT_STATUS_IS_OK(status)) {
 742                         return status;
 743                 }
 744 
 745                 SMBCLI_CHECK_WCT(req, 12);
 746                 parms->openxreadx.out.remaining       = SVAL(req->in.vwv, VWV(2));
 747                 parms->openxreadx.out.compaction_mode = SVAL(req->in.vwv, VWV(3));
 748                 parms->openxreadx.out.nread = SVAL(req->in.vwv, VWV(5));
 749                 if (parms->openxreadx.out.nread > 
 750                     MAX(parms->openxreadx.in.mincnt, parms->openxreadx.in.maxcnt) ||
 751                     !smbcli_raw_pull_data(&req->in.bufinfo, req->in.hdr + SVAL(req->in.vwv, VWV(6)), 
 752                                           parms->openxreadx.out.nread, 
 753                                           parms->openxreadx.out.data)) {
 754                         req->status = NT_STATUS_BUFFER_TOO_SMALL;
 755                 }
 756                 break;
 757         case RAW_OPEN_SMB2:
 758                 req->status = NT_STATUS_INTERNAL_ERROR;
 759                 break;
 760         }
 761 
 762 failed:
 763         return smbcli_request_destroy(req);
 764 }
 765 
 766 
 767 /****************************************************************************
 768  Open a file - sync interface
 769 ****************************************************************************/
 770 _PUBLIC_ NTSTATUS smb_raw_open(struct smbcli_tree *tree, TALLOC_CTX *mem_ctx, union smb_open *parms)
     /* [<][>][^][v][top][bottom][index][help] */
 771 {
 772         struct smbcli_request *req = smb_raw_open_send(tree, parms);
 773         return smb_raw_open_recv(req, mem_ctx, parms);
 774 }
 775 
 776 
 777 /****************************************************************************
 778  Close a file - async send
 779 ****************************************************************************/
 780 _PUBLIC_ struct smbcli_request *smb_raw_close_send(struct smbcli_tree *tree, union smb_close *parms)
     /* [<][>][^][v][top][bottom][index][help] */
 781 {
 782         struct smbcli_request *req = NULL; 
 783 
 784         switch (parms->generic.level) {
 785         case RAW_CLOSE_CLOSE:
 786                 SETUP_REQUEST(SMBclose, 3, 0);
 787                 SSVAL(req->out.vwv, VWV(0), parms->close.in.file.fnum);
 788                 raw_push_dos_date3(tree->session->transport, 
 789                                   req->out.vwv, VWV(1), parms->close.in.write_time);
 790                 break;
 791 
 792         case RAW_CLOSE_SPLCLOSE:
 793                 SETUP_REQUEST(SMBsplclose, 3, 0);
 794                 SSVAL(req->out.vwv, VWV(0), parms->splclose.in.file.fnum);
 795                 SIVAL(req->out.vwv, VWV(1), 0); /* reserved */
 796                 break;
 797 
 798         case RAW_CLOSE_SMB2:
 799                 return NULL;
 800         }
 801 
 802         if (!req) return NULL;
 803 
 804         if (!smbcli_request_send(req)) {
 805                 smbcli_request_destroy(req);
 806                 return NULL;
 807         }
 808 
 809         return req;
 810 }
 811 
 812 
 813 /****************************************************************************
 814  Close a file - sync interface
 815 ****************************************************************************/
 816 _PUBLIC_ NTSTATUS smb_raw_close(struct smbcli_tree *tree, union smb_close *parms)
     /* [<][>][^][v][top][bottom][index][help] */
 817 {
 818         struct smbcli_request *req = smb_raw_close_send(tree, parms);
 819         return smbcli_request_simple_recv(req);
 820 }
 821 
 822 
 823 /****************************************************************************
 824  Locking calls - async interface
 825 ****************************************************************************/
 826 struct smbcli_request *smb_raw_lock_send(struct smbcli_tree *tree, union smb_lock *parms)
     /* [<][>][^][v][top][bottom][index][help] */
 827 {
 828         struct smbcli_request *req = NULL; 
 829 
 830         switch (parms->generic.level) {
 831         case RAW_LOCK_LOCK:
 832                 SETUP_REQUEST(SMBlock, 5, 0);
 833                 SSVAL(req->out.vwv, VWV(0), parms->lock.in.file.fnum);
 834                 SIVAL(req->out.vwv, VWV(1), parms->lock.in.count);
 835                 SIVAL(req->out.vwv, VWV(3), parms->lock.in.offset);
 836                 break;
 837                 
 838         case RAW_LOCK_UNLOCK:
 839                 SETUP_REQUEST(SMBunlock, 5, 0);
 840                 SSVAL(req->out.vwv, VWV(0), parms->unlock.in.file.fnum);
 841                 SIVAL(req->out.vwv, VWV(1), parms->unlock.in.count);
 842                 SIVAL(req->out.vwv, VWV(3), parms->unlock.in.offset);
 843                 break;
 844                 
 845         case RAW_LOCK_LOCKX: {
 846                 struct smb_lock_entry *lockp;
 847                 uint_t lck_size = (parms->lockx.in.mode & LOCKING_ANDX_LARGE_FILES)? 20 : 10;
 848                 uint_t lock_count = parms->lockx.in.ulock_cnt + parms->lockx.in.lock_cnt;
 849                 int i;
 850 
 851                 SETUP_REQUEST(SMBlockingX, 8, lck_size * lock_count);
 852                 SSVAL(req->out.vwv, VWV(0), SMB_CHAIN_NONE);
 853                 SSVAL(req->out.vwv, VWV(1), 0);
 854                 SSVAL(req->out.vwv, VWV(2), parms->lockx.in.file.fnum);
 855                 SSVAL(req->out.vwv, VWV(3), parms->lockx.in.mode);
 856                 SIVAL(req->out.vwv, VWV(4), parms->lockx.in.timeout);
 857                 SSVAL(req->out.vwv, VWV(6), parms->lockx.in.ulock_cnt);
 858                 SSVAL(req->out.vwv, VWV(7), parms->lockx.in.lock_cnt);
 859                 
 860                 /* copy in all the locks */
 861                 lockp = &parms->lockx.in.locks[0];
 862                 for (i = 0; i < lock_count; i++) {
 863                         uint8_t *p = req->out.data + lck_size * i;
 864                         SSVAL(p, 0, lockp[i].pid);
 865                         if (parms->lockx.in.mode & LOCKING_ANDX_LARGE_FILES) {
 866                                 SSVAL(p,  2, 0); /* reserved */
 867                                 SIVAL(p,  4, lockp[i].offset>>32);
 868                                 SIVAL(p,  8, lockp[i].offset);
 869                                 SIVAL(p, 12, lockp[i].count>>32);
 870                                 SIVAL(p, 16, lockp[i].count);
 871                         } else {
 872                                 SIVAL(p, 2, lockp[i].offset);
 873                                 SIVAL(p, 6, lockp[i].count);
 874                         }
 875                 }       
 876                 break;
 877         }
 878         case RAW_LOCK_SMB2:
 879                 return NULL;
 880         }
 881 
 882         if (!smbcli_request_send(req)) {
 883                 smbcli_request_destroy(req);
 884                 return NULL;
 885         }
 886 
 887         return req;
 888 }
 889 
 890 /****************************************************************************
 891  Locking calls - sync interface
 892 ****************************************************************************/
 893 _PUBLIC_ NTSTATUS smb_raw_lock(struct smbcli_tree *tree, union smb_lock *parms)
     /* [<][>][^][v][top][bottom][index][help] */
 894 {
 895         struct smbcli_request *req = smb_raw_lock_send(tree, parms);
 896         return smbcli_request_simple_recv(req);
 897 }
 898         
 899 
 900 /****************************************************************************
 901  Check for existence of a dir - async send
 902 ****************************************************************************/
 903 struct smbcli_request *smb_raw_chkpath_send(struct smbcli_tree *tree, union smb_chkpath *parms)
     /* [<][>][^][v][top][bottom][index][help] */
 904 {
 905         struct smbcli_request *req; 
 906 
 907         SETUP_REQUEST(SMBchkpth, 0, 0);
 908 
 909         smbcli_req_append_ascii4(req, parms->chkpath.in.path, STR_TERMINATE);
 910 
 911         if (!smbcli_request_send(req)) {
 912                 smbcli_request_destroy(req);
 913                 return NULL;
 914         }
 915 
 916         return req;
 917 }
 918 
 919 /****************************************************************************
 920  Check for existence of a dir - sync interface
 921 ****************************************************************************/
 922 NTSTATUS smb_raw_chkpath(struct smbcli_tree *tree, union smb_chkpath *parms)
     /* [<][>][^][v][top][bottom][index][help] */
 923 {
 924         struct smbcli_request *req = smb_raw_chkpath_send(tree, parms);
 925         return smbcli_request_simple_recv(req);
 926 }
 927 
 928 /****************************************************************************
 929  flush a file - async send
 930  a flush with RAW_FLUSH_ALL will flush all files
 931 ****************************************************************************/
 932 struct smbcli_request *smb_raw_flush_send(struct smbcli_tree *tree, union smb_flush *parms)
     /* [<][>][^][v][top][bottom][index][help] */
 933 {
 934         struct smbcli_request *req; 
 935         uint16_t fnum=0;
 936 
 937         switch (parms->generic.level) {
 938         case RAW_FLUSH_FLUSH:
 939                 fnum = parms->flush.in.file.fnum;
 940                 break;
 941         case RAW_FLUSH_ALL:
 942                 fnum = 0xFFFF;
 943                 break;
 944         case RAW_FLUSH_SMB2:
 945                 return NULL;
 946         }
 947 
 948         SETUP_REQUEST(SMBflush, 1, 0);
 949         SSVAL(req->out.vwv, VWV(0), fnum);
 950 
 951         if (!smbcli_request_send(req)) {
 952                 smbcli_request_destroy(req);
 953                 return NULL;
 954         }
 955 
 956         return req;
 957 }
 958 
 959 
 960 /****************************************************************************
 961  flush a file - sync interface
 962 ****************************************************************************/
 963 _PUBLIC_ NTSTATUS smb_raw_flush(struct smbcli_tree *tree, union smb_flush *parms)
     /* [<][>][^][v][top][bottom][index][help] */
 964 {
 965         struct smbcli_request *req = smb_raw_flush_send(tree, parms);
 966         return smbcli_request_simple_recv(req);
 967 }
 968 
 969 
 970 /****************************************************************************
 971  seek a file - async send
 972 ****************************************************************************/
 973 struct smbcli_request *smb_raw_seek_send(struct smbcli_tree *tree,
     /* [<][>][^][v][top][bottom][index][help] */
 974                                          union smb_seek *parms)
 975 {
 976         struct smbcli_request *req; 
 977 
 978         SETUP_REQUEST(SMBlseek, 4, 0);
 979 
 980         SSVAL(req->out.vwv, VWV(0), parms->lseek.in.file.fnum);
 981         SSVAL(req->out.vwv, VWV(1), parms->lseek.in.mode);
 982         SIVALS(req->out.vwv, VWV(2), parms->lseek.in.offset);
 983 
 984         if (!smbcli_request_send(req)) {
 985                 smbcli_request_destroy(req);
 986                 return NULL;
 987         }
 988         return req;
 989 }
 990 
 991 /****************************************************************************
 992  seek a file - async receive
 993 ****************************************************************************/
 994 NTSTATUS smb_raw_seek_recv(struct smbcli_request *req,
     /* [<][>][^][v][top][bottom][index][help] */
 995                            union smb_seek *parms)
 996 {
 997         if (!smbcli_request_receive(req) ||
 998             smbcli_request_is_error(req)) {
 999                 return smbcli_request_destroy(req);
1000         }
1001 
1002         SMBCLI_CHECK_WCT(req, 2);       
1003         parms->lseek.out.offset = IVAL(req->in.vwv, VWV(0));
1004 
1005 failed: 
1006         return smbcli_request_destroy(req);
1007 }
1008 
1009 /*
1010   seek a file - sync interface
1011 */
1012 _PUBLIC_ NTSTATUS smb_raw_seek(struct smbcli_tree *tree,
     /* [<][>][^][v][top][bottom][index][help] */
1013                       union smb_seek *parms)
1014 {
1015         struct smbcli_request *req = smb_raw_seek_send(tree, parms);
1016         return smb_raw_seek_recv(req, parms);
1017 }

/* [<][>][^][v][top][bottom][index][help] */