root/source4/torture/raw/read.c

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

DEFINITIONS

This source file includes following definitions.
  1. setup_buffer
  2. check_buffer
  3. test_read
  4. test_lockread
  5. test_readx
  6. test_readbraw
  7. test_read_for_execute
  8. torture_raw_read

   1 /* 
   2    Unix SMB/CIFS implementation.
   3    test suite for various read operations
   4    Copyright (C) Andrew Tridgell 2003
   5    
   6    This program is free software; you can redistribute it and/or modify
   7    it under the terms of the GNU General Public License as published by
   8    the Free Software Foundation; either version 3 of the License, or
   9    (at your option) any later version.
  10    
  11    This program is distributed in the hope that it will be useful,
  12    but WITHOUT ANY WARRANTY; without even the implied warranty of
  13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14    GNU General Public License for more details.
  15    
  16    You should have received a copy of the GNU General Public License
  17    along with this program.  If not, see <http://www.gnu.org/licenses/>.
  18 */
  19 
  20 #include "includes.h"
  21 #include "torture/torture.h"
  22 #include "libcli/raw/libcliraw.h"
  23 #include "libcli/raw/raw_proto.h"
  24 #include "system/time.h"
  25 #include "system/filesys.h"
  26 #include "libcli/libcli.h"
  27 #include "torture/util.h"
  28 
  29 #define CHECK_STATUS(status, correct) do { \
  30         if (!NT_STATUS_EQUAL(status, correct)) { \
  31                 printf("(%s) Incorrect status %s - should be %s\n", \
  32                        __location__, nt_errstr(status), nt_errstr(correct)); \
  33                 ret = false; \
  34                 goto done; \
  35         }} while (0)
  36 
  37 #define CHECK_VALUE(v, correct) do { \
  38         if ((v) != (correct)) { \
  39                 printf("(%s) Incorrect value %s=%ld - should be %ld\n", \
  40                        __location__, #v, (long)v, (long)correct); \
  41                 ret = false; \
  42                 goto done; \
  43         }} while (0)
  44 
  45 #define CHECK_BUFFER(buf, seed, len) do { \
  46         if (!check_buffer(buf, seed, len, __LINE__)) { \
  47                 ret = false; \
  48                 goto done; \
  49         }} while (0)
  50 
  51 #define BASEDIR "\\testread"
  52 
  53 
  54 /*
  55   setup a random buffer based on a seed
  56 */
  57 static void setup_buffer(uint8_t *buf, uint_t seed, int len)
     /* [<][>][^][v][top][bottom][index][help] */
  58 {
  59         int i;
  60         srandom(seed);
  61         for (i=0;i<len;i++) buf[i] = random();
  62 }
  63 
  64 /*
  65   check a random buffer based on a seed
  66 */
  67 static bool check_buffer(uint8_t *buf, uint_t seed, int len, int line)
     /* [<][>][^][v][top][bottom][index][help] */
  68 {
  69         int i;
  70         srandom(seed);
  71         for (i=0;i<len;i++) {
  72                 uint8_t v = random();
  73                 if (buf[i] != v) {
  74                         printf("Buffer incorrect at line %d! ofs=%d v1=0x%x v2=0x%x\n", 
  75                                line, i, buf[i], v);
  76                         return false;
  77                 }
  78         }
  79         return true;
  80 }
  81 
  82 /*
  83   test read ops
  84 */
  85 static bool test_read(struct torture_context *tctx, struct smbcli_state *cli)
     /* [<][>][^][v][top][bottom][index][help] */
  86 {
  87         union smb_read io;
  88         NTSTATUS status;
  89         bool ret = true;
  90         int fnum;
  91         uint8_t *buf;
  92         const int maxsize = 90000;
  93         const char *fname = BASEDIR "\\test.txt";
  94         const char *test_data = "TEST DATA";
  95         uint_t seed = time(NULL);
  96 
  97         buf = talloc_zero_array(tctx, uint8_t, maxsize);
  98 
  99         if (!torture_setup_dir(cli, BASEDIR)) {
 100                 return false;
 101         }
 102 
 103         printf("Testing RAW_READ_READ\n");
 104         io.generic.level = RAW_READ_READ;
 105         
 106         fnum = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT, DENY_NONE);
 107         if (fnum == -1) {
 108                 printf("Failed to create %s - %s\n", fname, smbcli_errstr(cli->tree));
 109                 ret = false;
 110                 goto done;
 111         }
 112 
 113         printf("Trying empty file read\n");
 114         io.read.in.file.fnum = fnum;
 115         io.read.in.count = 1;
 116         io.read.in.offset = 0;
 117         io.read.in.remaining = 0;
 118         io.read.out.data = buf;
 119         status = smb_raw_read(cli->tree, &io);
 120 
 121         CHECK_STATUS(status, NT_STATUS_OK);
 122         CHECK_VALUE(io.read.out.nread, 0);
 123 
 124         printf("Trying zero file read\n");
 125         io.read.in.count = 0;
 126         status = smb_raw_read(cli->tree, &io);
 127         CHECK_STATUS(status, NT_STATUS_OK);
 128         CHECK_VALUE(io.read.out.nread, 0);
 129 
 130         printf("Trying bad fnum\n");
 131         io.read.in.file.fnum = fnum+1;
 132         status = smb_raw_read(cli->tree, &io);
 133         CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);
 134         io.read.in.file.fnum = fnum;
 135 
 136         smbcli_write(cli->tree, fnum, 0, test_data, 0, strlen(test_data));
 137 
 138         printf("Trying small read\n");
 139         io.read.in.file.fnum = fnum;
 140         io.read.in.offset = 0;
 141         io.read.in.remaining = 0;
 142         io.read.in.count = strlen(test_data);
 143         status = smb_raw_read(cli->tree, &io);
 144         CHECK_STATUS(status, NT_STATUS_OK);
 145         CHECK_VALUE(io.read.out.nread, strlen(test_data));
 146         if (memcmp(buf, test_data, strlen(test_data)) != 0) {
 147                 ret = false;
 148                 printf("incorrect data at %d!? (%s:%s)\n", __LINE__, test_data, buf);
 149                 goto done;
 150         }
 151 
 152         printf("Trying short read\n");
 153         io.read.in.offset = 1;
 154         io.read.in.count = strlen(test_data);
 155         status = smb_raw_read(cli->tree, &io);
 156         CHECK_STATUS(status, NT_STATUS_OK);
 157         CHECK_VALUE(io.read.out.nread, strlen(test_data)-1);
 158         if (memcmp(buf, test_data+1, strlen(test_data)-1) != 0) {
 159                 ret = false;
 160                 printf("incorrect data at %d!? (%s:%s)\n", __LINE__, test_data+1, buf);
 161                 goto done;
 162         }
 163 
 164         if (cli->transport->negotiate.capabilities & CAP_LARGE_FILES) {
 165                 printf("Trying max offset\n");
 166                 io.read.in.offset = ~0;
 167                 io.read.in.count = strlen(test_data);
 168                 status = smb_raw_read(cli->tree, &io);
 169                 CHECK_STATUS(status, NT_STATUS_OK);
 170                 CHECK_VALUE(io.read.out.nread, 0);
 171         }
 172 
 173         setup_buffer(buf, seed, maxsize);
 174         smbcli_write(cli->tree, fnum, 0, buf, 0, maxsize);
 175         memset(buf, 0, maxsize);
 176 
 177         printf("Trying large read\n");
 178         io.read.in.offset = 0;
 179         io.read.in.count = ~0;
 180         status = smb_raw_read(cli->tree, &io);
 181         CHECK_STATUS(status, NT_STATUS_OK);
 182         CHECK_BUFFER(buf, seed, io.read.out.nread);
 183 
 184 
 185         printf("Trying locked region\n");
 186         cli->session->pid++;
 187         if (NT_STATUS_IS_ERR(smbcli_lock(cli->tree, fnum, 103, 1, 0, WRITE_LOCK))) {
 188                 printf("Failed to lock file at %d\n", __LINE__);
 189                 ret = false;
 190                 goto done;
 191         }
 192         cli->session->pid--;
 193         memset(buf, 0, maxsize);
 194         io.read.in.offset = 0;
 195         io.read.in.count = ~0;
 196         status = smb_raw_read(cli->tree, &io);
 197         CHECK_STATUS(status, NT_STATUS_FILE_LOCK_CONFLICT);
 198         
 199 
 200 done:
 201         smbcli_close(cli->tree, fnum);
 202         smb_raw_exit(cli->session);
 203         smbcli_deltree(cli->tree, BASEDIR);
 204         return ret;
 205 }
 206 
 207 
 208 /*
 209   test lockread ops
 210 */
 211 static bool test_lockread(struct torture_context *tctx, 
     /* [<][>][^][v][top][bottom][index][help] */
 212                                                   struct smbcli_state *cli)
 213 {
 214         union smb_read io;
 215         NTSTATUS status;
 216         bool ret = true;
 217         int fnum;
 218         uint8_t *buf;
 219         const int maxsize = 90000;
 220         const char *fname = BASEDIR "\\test.txt";
 221         const char *test_data = "TEST DATA";
 222         uint_t seed = time(NULL);
 223 
 224         buf = talloc_zero_array(tctx, uint8_t, maxsize);
 225 
 226         if (!torture_setup_dir(cli, BASEDIR)) {
 227                 return false;
 228         }
 229 
 230         printf("Testing RAW_READ_LOCKREAD\n");
 231         io.generic.level = RAW_READ_LOCKREAD;
 232         
 233         fnum = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT, DENY_NONE);
 234         if (fnum == -1) {
 235                 printf("Failed to create %s - %s\n", fname, smbcli_errstr(cli->tree));
 236                 ret = false;
 237                 goto done;
 238         }
 239 
 240         printf("Trying empty file read\n");
 241         io.lockread.in.file.fnum = fnum;
 242         io.lockread.in.count = 1;
 243         io.lockread.in.offset = 1;
 244         io.lockread.in.remaining = 0;
 245         io.lockread.out.data = buf;
 246         status = smb_raw_read(cli->tree, &io);
 247 
 248         CHECK_STATUS(status, NT_STATUS_OK);
 249         CHECK_VALUE(io.lockread.out.nread, 0);
 250 
 251         status = smb_raw_read(cli->tree, &io);
 252         CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
 253 
 254         status = smb_raw_read(cli->tree, &io);
 255         CHECK_STATUS(status, NT_STATUS_FILE_LOCK_CONFLICT);
 256 
 257         printf("Trying zero file read\n");
 258         io.lockread.in.count = 0;
 259         status = smb_raw_read(cli->tree, &io);
 260         CHECK_STATUS(status, NT_STATUS_OK);
 261 
 262         smbcli_unlock(cli->tree, fnum, 1, 1);
 263 
 264         printf("Trying bad fnum\n");
 265         io.lockread.in.file.fnum = fnum+1;
 266         status = smb_raw_read(cli->tree, &io);
 267         CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);
 268         io.lockread.in.file.fnum = fnum;
 269 
 270         smbcli_write(cli->tree, fnum, 0, test_data, 0, strlen(test_data));
 271 
 272         printf("Trying small read\n");
 273         io.lockread.in.file.fnum = fnum;
 274         io.lockread.in.offset = 0;
 275         io.lockread.in.remaining = 0;
 276         io.lockread.in.count = strlen(test_data);
 277         status = smb_raw_read(cli->tree, &io);
 278         CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
 279 
 280         smbcli_unlock(cli->tree, fnum, 1, 0);
 281 
 282         status = smb_raw_read(cli->tree, &io);
 283         CHECK_STATUS(status, NT_STATUS_OK);
 284         CHECK_VALUE(io.lockread.out.nread, strlen(test_data));
 285         if (memcmp(buf, test_data, strlen(test_data)) != 0) {
 286                 ret = false;
 287                 printf("incorrect data at %d!? (%s:%s)\n", __LINE__, test_data, buf);
 288                 goto done;
 289         }
 290 
 291         printf("Trying short read\n");
 292         io.lockread.in.offset = 1;
 293         io.lockread.in.count = strlen(test_data);
 294         status = smb_raw_read(cli->tree, &io);
 295         CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
 296         smbcli_unlock(cli->tree, fnum, 0, strlen(test_data));
 297         status = smb_raw_read(cli->tree, &io);
 298         CHECK_STATUS(status, NT_STATUS_OK);
 299 
 300         CHECK_VALUE(io.lockread.out.nread, strlen(test_data)-1);
 301         if (memcmp(buf, test_data+1, strlen(test_data)-1) != 0) {
 302                 ret = false;
 303                 printf("incorrect data at %d!? (%s:%s)\n", __LINE__, test_data+1, buf);
 304                 goto done;
 305         }
 306 
 307         if (cli->transport->negotiate.capabilities & CAP_LARGE_FILES) {
 308                 printf("Trying max offset\n");
 309                 io.lockread.in.offset = ~0;
 310                 io.lockread.in.count = strlen(test_data);
 311                 status = smb_raw_read(cli->tree, &io);
 312                 CHECK_STATUS(status, NT_STATUS_OK);
 313                 CHECK_VALUE(io.lockread.out.nread, 0);
 314         }
 315 
 316         setup_buffer(buf, seed, maxsize);
 317         smbcli_write(cli->tree, fnum, 0, buf, 0, maxsize);
 318         memset(buf, 0, maxsize);
 319 
 320         printf("Trying large read\n");
 321         io.lockread.in.offset = 0;
 322         io.lockread.in.count = ~0;
 323         status = smb_raw_read(cli->tree, &io);
 324         CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
 325         smbcli_unlock(cli->tree, fnum, 1, strlen(test_data));
 326         status = smb_raw_read(cli->tree, &io);
 327         CHECK_STATUS(status, NT_STATUS_OK);
 328         CHECK_BUFFER(buf, seed, io.lockread.out.nread);
 329         smbcli_unlock(cli->tree, fnum, 0, 0xFFFF);
 330 
 331 
 332         printf("Trying locked region\n");
 333         cli->session->pid++;
 334         if (NT_STATUS_IS_ERR(smbcli_lock(cli->tree, fnum, 103, 1, 0, WRITE_LOCK))) {
 335                 printf("Failed to lock file at %d\n", __LINE__);
 336                 ret = false;
 337                 goto done;
 338         }
 339         cli->session->pid--;
 340         memset(buf, 0, maxsize);
 341         io.lockread.in.offset = 0;
 342         io.lockread.in.count = ~0;
 343         status = smb_raw_read(cli->tree, &io);
 344         CHECK_STATUS(status, NT_STATUS_FILE_LOCK_CONFLICT);
 345         
 346 
 347 done:
 348         smbcli_close(cli->tree, fnum);
 349         smbcli_deltree(cli->tree, BASEDIR);
 350         return ret;
 351 }
 352 
 353 
 354 /*
 355   test readx ops
 356 */
 357 static bool test_readx(struct torture_context *tctx, struct smbcli_state *cli)
     /* [<][>][^][v][top][bottom][index][help] */
 358 {
 359         union smb_read io;
 360         NTSTATUS status;
 361         bool ret = true;
 362         int fnum;
 363         uint8_t *buf;
 364         const int maxsize = 90000;
 365         const char *fname = BASEDIR "\\test.txt";
 366         const char *test_data = "TEST DATA";
 367         uint_t seed = time(NULL);
 368 
 369         buf = talloc_zero_array(tctx, uint8_t, maxsize);
 370 
 371         if (!torture_setup_dir(cli, BASEDIR)) {
 372                 return false;
 373         }
 374 
 375         printf("Testing RAW_READ_READX\n");
 376         
 377         fnum = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT, DENY_NONE);
 378         if (fnum == -1) {
 379                 printf("Failed to create %s - %s\n", fname, smbcli_errstr(cli->tree));
 380                 ret = false;
 381                 goto done;
 382         }
 383 
 384         printf("Trying empty file read\n");
 385         io.generic.level = RAW_READ_READX;
 386         io.readx.in.file.fnum = fnum;
 387         io.readx.in.mincnt = 1;
 388         io.readx.in.maxcnt = 1;
 389         io.readx.in.offset = 0;
 390         io.readx.in.remaining = 0;
 391         io.readx.in.read_for_execute = false;
 392         io.readx.out.data = buf;
 393         status = smb_raw_read(cli->tree, &io);
 394 
 395         CHECK_STATUS(status, NT_STATUS_OK);
 396         CHECK_VALUE(io.readx.out.nread, 0);
 397         CHECK_VALUE(io.readx.out.remaining, 0xFFFF);
 398         CHECK_VALUE(io.readx.out.compaction_mode, 0);
 399 
 400         printf("Trying zero file read\n");
 401         io.readx.in.mincnt = 0;
 402         io.readx.in.maxcnt = 0;
 403         status = smb_raw_read(cli->tree, &io);
 404         CHECK_STATUS(status, NT_STATUS_OK);
 405         CHECK_VALUE(io.readx.out.nread, 0);
 406         CHECK_VALUE(io.readx.out.remaining, 0xFFFF);
 407         CHECK_VALUE(io.readx.out.compaction_mode, 0);
 408 
 409         printf("Trying bad fnum\n");
 410         io.readx.in.file.fnum = fnum+1;
 411         status = smb_raw_read(cli->tree, &io);
 412         CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);
 413         io.readx.in.file.fnum = fnum;
 414 
 415         smbcli_write(cli->tree, fnum, 0, test_data, 0, strlen(test_data));
 416 
 417         printf("Trying small read\n");
 418         io.readx.in.file.fnum = fnum;
 419         io.readx.in.offset = 0;
 420         io.readx.in.remaining = 0;
 421         io.readx.in.read_for_execute = false;
 422         io.readx.in.mincnt = strlen(test_data);
 423         io.readx.in.maxcnt = strlen(test_data);
 424         status = smb_raw_read(cli->tree, &io);
 425         CHECK_STATUS(status, NT_STATUS_OK);
 426         CHECK_VALUE(io.readx.out.nread, strlen(test_data));
 427         CHECK_VALUE(io.readx.out.remaining, 0xFFFF);
 428         CHECK_VALUE(io.readx.out.compaction_mode, 0);
 429         if (memcmp(buf, test_data, strlen(test_data)) != 0) {
 430                 ret = false;
 431                 printf("incorrect data at %d!? (%s:%s)\n", __LINE__, test_data, buf);
 432                 goto done;
 433         }
 434 
 435         printf("Trying short read\n");
 436         io.readx.in.offset = 1;
 437         io.readx.in.mincnt = strlen(test_data);
 438         io.readx.in.maxcnt = strlen(test_data);
 439         status = smb_raw_read(cli->tree, &io);
 440         CHECK_STATUS(status, NT_STATUS_OK);
 441         CHECK_VALUE(io.readx.out.nread, strlen(test_data)-1);
 442         CHECK_VALUE(io.readx.out.remaining, 0xFFFF);
 443         CHECK_VALUE(io.readx.out.compaction_mode, 0);
 444         if (memcmp(buf, test_data+1, strlen(test_data)-1) != 0) {
 445                 ret = false;
 446                 printf("incorrect data at %d!? (%s:%s)\n", __LINE__, test_data+1, buf);
 447                 goto done;
 448         }
 449 
 450         if (cli->transport->negotiate.capabilities & CAP_LARGE_FILES) {
 451                 printf("Trying max offset\n");
 452                 io.readx.in.offset = 0xffffffff;
 453                 io.readx.in.mincnt = strlen(test_data);
 454                 io.readx.in.maxcnt = strlen(test_data);
 455                 status = smb_raw_read(cli->tree, &io);
 456                 CHECK_STATUS(status, NT_STATUS_OK);
 457                 CHECK_VALUE(io.readx.out.nread, 0);
 458                 CHECK_VALUE(io.readx.out.remaining, 0xFFFF);
 459                 CHECK_VALUE(io.readx.out.compaction_mode, 0);
 460         }
 461 
 462         printf("Trying mincnt past EOF\n");
 463         memset(buf, 0, maxsize);
 464         io.readx.in.offset = 0;
 465         io.readx.in.mincnt = 100;
 466         io.readx.in.maxcnt = 110;
 467         status = smb_raw_read(cli->tree, &io);
 468         CHECK_STATUS(status, NT_STATUS_OK);
 469         CHECK_VALUE(io.readx.out.remaining, 0xFFFF);
 470         CHECK_VALUE(io.readx.out.compaction_mode, 0);
 471         CHECK_VALUE(io.readx.out.nread, strlen(test_data));
 472         if (memcmp(buf, test_data, strlen(test_data)) != 0) {
 473                 ret = false;
 474                 printf("incorrect data at %d!? (%s:%s)\n", __LINE__, test_data, buf);
 475                 goto done;
 476         }
 477 
 478 
 479         setup_buffer(buf, seed, maxsize);
 480         smbcli_write(cli->tree, fnum, 0, buf, 0, maxsize);
 481         memset(buf, 0, maxsize);
 482 
 483         printf("Trying large read\n");
 484         io.readx.in.offset = 0;
 485         io.readx.in.mincnt = 0xFFFF;
 486         io.readx.in.maxcnt = 0xFFFF;
 487         status = smb_raw_read(cli->tree, &io);
 488         CHECK_STATUS(status, NT_STATUS_OK);
 489         CHECK_VALUE(io.readx.out.remaining, 0xFFFF);
 490         CHECK_VALUE(io.readx.out.compaction_mode, 0);
 491         CHECK_VALUE(io.readx.out.nread, io.readx.in.maxcnt);
 492         CHECK_BUFFER(buf, seed, io.readx.out.nread);
 493 
 494         printf("Trying extra large read\n");
 495         io.readx.in.offset = 0;
 496         io.readx.in.mincnt = 100;
 497         io.readx.in.maxcnt = 80000;
 498         status = smb_raw_read(cli->tree, &io);
 499         CHECK_STATUS(status, NT_STATUS_OK);
 500         CHECK_VALUE(io.readx.out.remaining, 0xFFFF);
 501         CHECK_VALUE(io.readx.out.compaction_mode, 0);
 502         if (torture_setting_bool(tctx, "samba3", false)) {
 503                 printf("SAMBA3: large read extension\n");
 504                 CHECK_VALUE(io.readx.out.nread, 80000);
 505         } else {
 506                 CHECK_VALUE(io.readx.out.nread, 0);
 507         }
 508         CHECK_BUFFER(buf, seed, io.readx.out.nread);
 509 
 510         printf("Trying mincnt > maxcnt\n");
 511         memset(buf, 0, maxsize);
 512         io.readx.in.offset = 0;
 513         io.readx.in.mincnt = 30000;
 514         io.readx.in.maxcnt = 20000;
 515         status = smb_raw_read(cli->tree, &io);
 516         CHECK_STATUS(status, NT_STATUS_OK);
 517         CHECK_VALUE(io.readx.out.remaining, 0xFFFF);
 518         CHECK_VALUE(io.readx.out.compaction_mode, 0);
 519         CHECK_VALUE(io.readx.out.nread, io.readx.in.maxcnt);
 520         CHECK_BUFFER(buf, seed, io.readx.out.nread);
 521 
 522         printf("Trying mincnt < maxcnt\n");
 523         memset(buf, 0, maxsize);
 524         io.readx.in.offset = 0;
 525         io.readx.in.mincnt = 20000;
 526         io.readx.in.maxcnt = 30000;
 527         status = smb_raw_read(cli->tree, &io);
 528         CHECK_STATUS(status, NT_STATUS_OK);
 529         CHECK_VALUE(io.readx.out.remaining, 0xFFFF);
 530         CHECK_VALUE(io.readx.out.compaction_mode, 0);
 531         CHECK_VALUE(io.readx.out.nread, io.readx.in.maxcnt);
 532         CHECK_BUFFER(buf, seed, io.readx.out.nread);
 533 
 534         if (cli->transport->negotiate.capabilities & CAP_LARGE_READX) {
 535                 printf("Trying large readx\n");
 536                 io.readx.in.offset = 0;
 537                 io.readx.in.mincnt = 0;
 538                 io.readx.in.maxcnt = 0x10000 - 1;
 539                 status = smb_raw_read(cli->tree, &io);
 540                 CHECK_STATUS(status, NT_STATUS_OK);
 541                 CHECK_VALUE(io.readx.out.nread, 0xFFFF);
 542 
 543                 io.readx.in.maxcnt = 0x10000;
 544                 status = smb_raw_read(cli->tree, &io);
 545                 CHECK_STATUS(status, NT_STATUS_OK);
 546                 if (torture_setting_bool(tctx, "samba3", false)) {
 547                         printf("SAMBA3: large read extension\n");
 548                         CHECK_VALUE(io.readx.out.nread, 0x10000);
 549                 } else {
 550                         CHECK_VALUE(io.readx.out.nread, 0);
 551                 }
 552 
 553                 io.readx.in.maxcnt = 0x10001;
 554                 status = smb_raw_read(cli->tree, &io);
 555                 CHECK_STATUS(status, NT_STATUS_OK);
 556                 if (torture_setting_bool(tctx, "samba3", false)) {
 557                         printf("SAMBA3: large read extension\n");
 558                         CHECK_VALUE(io.readx.out.nread, 0x10001);
 559                 } else {
 560                         CHECK_VALUE(io.readx.out.nread, 0);
 561                 }
 562         }
 563 
 564         printf("Trying locked region\n");
 565         cli->session->pid++;
 566         if (NT_STATUS_IS_ERR(smbcli_lock(cli->tree, fnum, 103, 1, 0, WRITE_LOCK))) {
 567                 printf("Failed to lock file at %d\n", __LINE__);
 568                 ret = false;
 569                 goto done;
 570         }
 571         cli->session->pid--;
 572         memset(buf, 0, maxsize);
 573         io.readx.in.offset = 0;
 574         io.readx.in.mincnt = 100;
 575         io.readx.in.maxcnt = 200;
 576         status = smb_raw_read(cli->tree, &io);
 577         CHECK_STATUS(status, NT_STATUS_FILE_LOCK_CONFLICT);     
 578 
 579         if (!(cli->transport->negotiate.capabilities & CAP_LARGE_FILES)) {
 580                 printf("skipping large file tests - CAP_LARGE_FILES not set\n");
 581                 goto done;
 582         }
 583 
 584         printf("Trying large offset read\n");
 585         io.readx.in.offset = ((uint64_t)0x2) << 32;
 586         io.readx.in.mincnt = 10;
 587         io.readx.in.maxcnt = 10;
 588         status = smb_raw_read(cli->tree, &io);
 589         CHECK_STATUS(status, NT_STATUS_OK);
 590         CHECK_VALUE(io.readx.out.nread, 0);
 591 
 592         if (NT_STATUS_IS_ERR(smbcli_lock64(cli->tree, fnum, io.readx.in.offset, 1, 0, WRITE_LOCK))) {
 593                 printf("Failed to lock file at %d\n", __LINE__);
 594                 ret = false;
 595                 goto done;
 596         }
 597 
 598         status = smb_raw_read(cli->tree, &io);
 599         CHECK_STATUS(status, NT_STATUS_OK);
 600         CHECK_VALUE(io.readx.out.nread, 0);
 601 
 602 done:
 603         smbcli_close(cli->tree, fnum);
 604         smbcli_deltree(cli->tree, BASEDIR);
 605         return ret;
 606 }
 607 
 608 
 609 /*
 610   test readbraw ops
 611 */
 612 static bool test_readbraw(struct torture_context *tctx, 
     /* [<][>][^][v][top][bottom][index][help] */
 613                                                   struct smbcli_state *cli)
 614 {
 615         union smb_read io;
 616         NTSTATUS status;
 617         bool ret = true;
 618         int fnum;
 619         uint8_t *buf;
 620         const int maxsize = 90000;
 621         const char *fname = BASEDIR "\\test.txt";
 622         const char *test_data = "TEST DATA";
 623         uint_t seed = time(NULL);
 624 
 625         buf = talloc_zero_array(tctx, uint8_t, maxsize);
 626 
 627         if (!torture_setup_dir(cli, BASEDIR)) {
 628                 return false;
 629         }
 630 
 631         printf("Testing RAW_READ_READBRAW\n");
 632         
 633         fnum = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT, DENY_NONE);
 634         if (fnum == -1) {
 635                 printf("Failed to create %s - %s\n", fname, smbcli_errstr(cli->tree));
 636                 ret = false;
 637                 goto done;
 638         }
 639 
 640         printf("Trying empty file read\n");
 641         io.generic.level = RAW_READ_READBRAW;
 642         io.readbraw.in.file.fnum = fnum;
 643         io.readbraw.in.mincnt = 1;
 644         io.readbraw.in.maxcnt = 1;
 645         io.readbraw.in.offset = 0;
 646         io.readbraw.in.timeout = 0;
 647         io.readbraw.out.data = buf;
 648         status = smb_raw_read(cli->tree, &io);
 649 
 650         CHECK_STATUS(status, NT_STATUS_OK);
 651         CHECK_VALUE(io.readbraw.out.nread, 0);
 652 
 653         printf("Trying zero file read\n");
 654         io.readbraw.in.mincnt = 0;
 655         io.readbraw.in.maxcnt = 0;
 656         status = smb_raw_read(cli->tree, &io);
 657         CHECK_STATUS(status, NT_STATUS_OK);
 658         CHECK_VALUE(io.readbraw.out.nread, 0);
 659 
 660         printf("Trying bad fnum\n");
 661         io.readbraw.in.file.fnum = fnum+1;
 662         status = smb_raw_read(cli->tree, &io);
 663         CHECK_STATUS(status, NT_STATUS_OK);
 664         CHECK_VALUE(io.readbraw.out.nread, 0);
 665         io.readbraw.in.file.fnum = fnum;
 666 
 667         smbcli_write(cli->tree, fnum, 0, test_data, 0, strlen(test_data));
 668 
 669         printf("Trying small read\n");
 670         io.readbraw.in.file.fnum = fnum;
 671         io.readbraw.in.offset = 0;
 672         io.readbraw.in.mincnt = strlen(test_data);
 673         io.readbraw.in.maxcnt = strlen(test_data);
 674         status = smb_raw_read(cli->tree, &io);
 675         CHECK_STATUS(status, NT_STATUS_OK);
 676         CHECK_VALUE(io.readbraw.out.nread, strlen(test_data));
 677         if (memcmp(buf, test_data, strlen(test_data)) != 0) {
 678                 ret = false;
 679                 printf("incorrect data at %d!? (%s:%s)\n", __LINE__, test_data, buf);
 680                 goto done;
 681         }
 682 
 683         printf("Trying short read\n");
 684         io.readbraw.in.offset = 1;
 685         io.readbraw.in.mincnt = strlen(test_data);
 686         io.readbraw.in.maxcnt = strlen(test_data);
 687         status = smb_raw_read(cli->tree, &io);
 688         CHECK_STATUS(status, NT_STATUS_OK);
 689         CHECK_VALUE(io.readbraw.out.nread, strlen(test_data)-1);
 690         if (memcmp(buf, test_data+1, strlen(test_data)-1) != 0) {
 691                 ret = false;
 692                 printf("incorrect data at %d!? (%s:%s)\n", __LINE__, test_data+1, buf);
 693                 goto done;
 694         }
 695 
 696         if (cli->transport->negotiate.capabilities & CAP_LARGE_FILES) {
 697                 printf("Trying max offset\n");
 698                 io.readbraw.in.offset = ~0;
 699                 io.readbraw.in.mincnt = strlen(test_data);
 700                 io.readbraw.in.maxcnt = strlen(test_data);
 701                 status = smb_raw_read(cli->tree, &io);
 702                 CHECK_STATUS(status, NT_STATUS_OK);
 703                 CHECK_VALUE(io.readbraw.out.nread, 0);
 704         }
 705 
 706         setup_buffer(buf, seed, maxsize);
 707         smbcli_write(cli->tree, fnum, 0, buf, 0, maxsize);
 708         memset(buf, 0, maxsize);
 709 
 710         printf("Trying large read\n");
 711         io.readbraw.in.offset = 0;
 712         io.readbraw.in.mincnt = ~0;
 713         io.readbraw.in.maxcnt = ~0;
 714         status = smb_raw_read(cli->tree, &io);
 715         CHECK_STATUS(status, NT_STATUS_OK);
 716         CHECK_VALUE(io.readbraw.out.nread, 0xFFFF);
 717         CHECK_BUFFER(buf, seed, io.readbraw.out.nread);
 718 
 719         printf("Trying mincnt > maxcnt\n");
 720         memset(buf, 0, maxsize);
 721         io.readbraw.in.offset = 0;
 722         io.readbraw.in.mincnt = 30000;
 723         io.readbraw.in.maxcnt = 20000;
 724         status = smb_raw_read(cli->tree, &io);
 725         CHECK_STATUS(status, NT_STATUS_OK);
 726         CHECK_VALUE(io.readbraw.out.nread, io.readbraw.in.maxcnt);
 727         CHECK_BUFFER(buf, seed, io.readbraw.out.nread);
 728 
 729         printf("Trying mincnt < maxcnt\n");
 730         memset(buf, 0, maxsize);
 731         io.readbraw.in.offset = 0;
 732         io.readbraw.in.mincnt = 20000;
 733         io.readbraw.in.maxcnt = 30000;
 734         status = smb_raw_read(cli->tree, &io);
 735         CHECK_STATUS(status, NT_STATUS_OK);
 736         CHECK_VALUE(io.readbraw.out.nread, io.readbraw.in.maxcnt);
 737         CHECK_BUFFER(buf, seed, io.readbraw.out.nread);
 738 
 739         printf("Trying locked region\n");
 740         cli->session->pid++;
 741         if (NT_STATUS_IS_ERR(smbcli_lock(cli->tree, fnum, 103, 1, 0, WRITE_LOCK))) {
 742                 printf("Failed to lock file at %d\n", __LINE__);
 743                 ret = false;
 744                 goto done;
 745         }
 746         cli->session->pid--;
 747         memset(buf, 0, maxsize);
 748         io.readbraw.in.offset = 0;
 749         io.readbraw.in.mincnt = 100;
 750         io.readbraw.in.maxcnt = 200;
 751         status = smb_raw_read(cli->tree, &io);
 752         CHECK_STATUS(status, NT_STATUS_OK);
 753         CHECK_VALUE(io.readbraw.out.nread, 0);
 754 
 755         printf("Trying locked region with timeout\n");
 756         memset(buf, 0, maxsize);
 757         io.readbraw.in.offset = 0;
 758         io.readbraw.in.mincnt = 100;
 759         io.readbraw.in.maxcnt = 200;
 760         io.readbraw.in.timeout = 10000;
 761         status = smb_raw_read(cli->tree, &io);
 762         CHECK_STATUS(status, NT_STATUS_OK);
 763         CHECK_VALUE(io.readbraw.out.nread, 0);
 764 
 765         if (cli->transport->negotiate.capabilities & CAP_LARGE_FILES) {
 766                 printf("Trying large offset read\n");
 767                 io.readbraw.in.offset = ((uint64_t)0x2) << 32;
 768                 io.readbraw.in.mincnt = 10;
 769                 io.readbraw.in.maxcnt = 10;
 770                 io.readbraw.in.timeout = 0;
 771                 status = smb_raw_read(cli->tree, &io);
 772                 CHECK_STATUS(status, NT_STATUS_OK);
 773                 CHECK_VALUE(io.readbraw.out.nread, 0);
 774         }
 775 
 776 done:
 777         smbcli_close(cli->tree, fnum);
 778         smbcli_deltree(cli->tree, BASEDIR);
 779         return ret;
 780 }
 781 
 782 /*
 783   test read for execute
 784 */
 785 static bool test_read_for_execute(struct torture_context *tctx, 
     /* [<][>][^][v][top][bottom][index][help] */
 786                                                                   struct smbcli_state *cli)
 787 {
 788         union smb_open op;
 789         union smb_write wr;
 790         union smb_read rd;
 791         NTSTATUS status;
 792         bool ret = true;
 793         int fnum=0;
 794         uint8_t *buf;
 795         const int maxsize = 900;
 796         const char *fname = BASEDIR "\\test.txt";
 797         const uint8_t data[] = "TEST DATA";
 798 
 799         buf = talloc_zero_array(tctx, uint8_t, maxsize);
 800 
 801         if (!torture_setup_dir(cli, BASEDIR)) {
 802                 return false;
 803         }
 804 
 805         printf("Testing RAW_READ_READX with read_for_execute\n");
 806 
 807         op.generic.level = RAW_OPEN_NTCREATEX;
 808         op.ntcreatex.in.root_fid = 0;
 809         op.ntcreatex.in.flags = 0;
 810         op.ntcreatex.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
 811         op.ntcreatex.in.create_options = 0;
 812         op.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
 813         op.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE;
 814         op.ntcreatex.in.alloc_size = 0;
 815         op.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
 816         op.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
 817         op.ntcreatex.in.security_flags = 0;
 818         op.ntcreatex.in.fname = fname;
 819         status = smb_raw_open(cli->tree, tctx, &op);
 820         CHECK_STATUS(status, NT_STATUS_OK);
 821         fnum = op.ntcreatex.out.file.fnum;
 822 
 823         wr.generic.level = RAW_WRITE_WRITEX;
 824         wr.writex.in.file.fnum = fnum;
 825         wr.writex.in.offset = 0;
 826         wr.writex.in.wmode = 0;
 827         wr.writex.in.remaining = 0;
 828         wr.writex.in.count = ARRAY_SIZE(data);
 829         wr.writex.in.data = data;
 830         status = smb_raw_write(cli->tree, &wr);
 831         CHECK_STATUS(status, NT_STATUS_OK);
 832         CHECK_VALUE(wr.writex.out.nwritten, ARRAY_SIZE(data));
 833 
 834         status = smbcli_close(cli->tree, fnum);
 835         CHECK_STATUS(status, NT_STATUS_OK);
 836 
 837         printf("open file with SEC_FILE_EXECUTE\n");
 838         op.generic.level = RAW_OPEN_NTCREATEX;
 839         op.ntcreatex.in.root_fid = 0;
 840         op.ntcreatex.in.flags = 0;
 841         op.ntcreatex.in.access_mask = SEC_FILE_EXECUTE;
 842         op.ntcreatex.in.create_options = 0;
 843         op.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
 844         op.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE;
 845         op.ntcreatex.in.alloc_size = 0;
 846         op.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
 847         op.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
 848         op.ntcreatex.in.security_flags = 0;
 849         op.ntcreatex.in.fname = fname;
 850         status = smb_raw_open(cli->tree, tctx, &op);
 851         CHECK_STATUS(status, NT_STATUS_OK);
 852         fnum = op.ntcreatex.out.file.fnum;
 853 
 854         printf("read with FLAGS2_READ_PERMIT_EXECUTE\n");
 855         rd.generic.level = RAW_READ_READX;
 856         rd.readx.in.file.fnum = fnum;
 857         rd.readx.in.mincnt = 0;
 858         rd.readx.in.maxcnt = maxsize;
 859         rd.readx.in.offset = 0;
 860         rd.readx.in.remaining = 0;
 861         rd.readx.in.read_for_execute = true;
 862         rd.readx.out.data = buf;
 863         status = smb_raw_read(cli->tree, &rd);
 864         CHECK_STATUS(status, NT_STATUS_OK);
 865         CHECK_VALUE(rd.readx.out.nread, ARRAY_SIZE(data));
 866         CHECK_VALUE(rd.readx.out.remaining, 0xFFFF);
 867         CHECK_VALUE(rd.readx.out.compaction_mode, 0);
 868 
 869         printf("read without FLAGS2_READ_PERMIT_EXECUTE (should fail)\n");
 870         rd.generic.level = RAW_READ_READX;
 871         rd.readx.in.file.fnum = fnum;
 872         rd.readx.in.mincnt = 0;
 873         rd.readx.in.maxcnt = maxsize;
 874         rd.readx.in.offset = 0;
 875         rd.readx.in.remaining = 0;
 876         rd.readx.in.read_for_execute = false;
 877         rd.readx.out.data = buf;
 878         status = smb_raw_read(cli->tree, &rd);
 879         CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
 880 
 881         status = smbcli_close(cli->tree, fnum);
 882         CHECK_STATUS(status, NT_STATUS_OK);
 883 
 884         printf("open file with SEC_FILE_READ_DATA\n");
 885         op.generic.level = RAW_OPEN_NTCREATEX;
 886         op.ntcreatex.in.root_fid = 0;
 887         op.ntcreatex.in.flags = 0;
 888         op.ntcreatex.in.access_mask = SEC_FILE_READ_DATA;
 889         op.ntcreatex.in.create_options = 0;
 890         op.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
 891         op.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE;
 892         op.ntcreatex.in.alloc_size = 0;
 893         op.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
 894         op.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
 895         op.ntcreatex.in.security_flags = 0;
 896         op.ntcreatex.in.fname = fname;
 897         status = smb_raw_open(cli->tree, tctx, &op);
 898         CHECK_STATUS(status, NT_STATUS_OK);
 899         fnum = op.ntcreatex.out.file.fnum;
 900 
 901         printf("read with FLAGS2_READ_PERMIT_EXECUTE\n");
 902         rd.generic.level = RAW_READ_READX;
 903         rd.readx.in.file.fnum = fnum;
 904         rd.readx.in.mincnt = 0;
 905         rd.readx.in.maxcnt = maxsize;
 906         rd.readx.in.offset = 0;
 907         rd.readx.in.remaining = 0;
 908         rd.readx.in.read_for_execute = true;
 909         rd.readx.out.data = buf;
 910         status = smb_raw_read(cli->tree, &rd);
 911         CHECK_STATUS(status, NT_STATUS_OK);
 912         CHECK_VALUE(rd.readx.out.nread, ARRAY_SIZE(data));
 913         CHECK_VALUE(rd.readx.out.remaining, 0xFFFF);
 914         CHECK_VALUE(rd.readx.out.compaction_mode, 0);
 915 
 916         printf("read without FLAGS2_READ_PERMIT_EXECUTE\n");
 917         rd.generic.level = RAW_READ_READX;
 918         rd.readx.in.file.fnum = fnum;
 919         rd.readx.in.mincnt = 0;
 920         rd.readx.in.maxcnt = maxsize;
 921         rd.readx.in.offset = 0;
 922         rd.readx.in.remaining = 0;
 923         rd.readx.in.read_for_execute = false;
 924         rd.readx.out.data = buf;
 925         status = smb_raw_read(cli->tree, &rd);
 926         CHECK_STATUS(status, NT_STATUS_OK);
 927         CHECK_VALUE(rd.readx.out.nread, ARRAY_SIZE(data));
 928         CHECK_VALUE(rd.readx.out.remaining, 0xFFFF);
 929         CHECK_VALUE(rd.readx.out.compaction_mode, 0);
 930 
 931 done:
 932         smbcli_close(cli->tree, fnum);
 933         smbcli_deltree(cli->tree, BASEDIR);
 934         return ret;
 935 }
 936 
 937 
 938 /* 
 939    basic testing of read calls
 940 */
 941 struct torture_suite *torture_raw_read(TALLOC_CTX *mem_ctx)
     /* [<][>][^][v][top][bottom][index][help] */
 942 {
 943         struct torture_suite *suite = torture_suite_create(mem_ctx, "READ");
 944 
 945         torture_suite_add_1smb_test(suite, "read", test_read);
 946         torture_suite_add_1smb_test(suite, "readx", test_readx);
 947         torture_suite_add_1smb_test(suite, "lockread", test_lockread);
 948         torture_suite_add_1smb_test(suite, "readbraw", test_readbraw);
 949         torture_suite_add_1smb_test(suite, "read for execute", 
 950                                                                 test_read_for_execute);
 951 
 952         return suite;
 953 }

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