s4 torture: Add lockread_supported based off of CAP_LOCK_AND_READ
[samba.git] / source4 / torture / raw / read.c
index f1048f25ac0669953d67d1e64c1e27478df42337..efdd04045196a05d0d174f0329f9b0d5c4646bd7 100644 (file)
@@ -18,7 +18,6 @@
 */
 
 #include "includes.h"
-#include "torture/torture.h"
 #include "libcli/raw/libcliraw.h"
 #include "system/time.h"
 #include "system/filesys.h"
@@ -29,7 +28,7 @@
        if (!NT_STATUS_EQUAL(status, correct)) { \
                printf("(%s) Incorrect status %s - should be %s\n", \
                       __location__, nt_errstr(status), nt_errstr(correct)); \
-               ret = False; \
+               ret = false; \
                goto done; \
        }} while (0)
 
        if ((v) != (correct)) { \
                printf("(%s) Incorrect value %s=%ld - should be %ld\n", \
                       __location__, #v, (long)v, (long)correct); \
-               ret = False; \
+               ret = false; \
                goto done; \
        }} while (0)
 
 #define CHECK_BUFFER(buf, seed, len) do { \
        if (!check_buffer(buf, seed, len, __LINE__)) { \
-               ret = False; \
+               ret = false; \
                goto done; \
        }} while (0)
 
@@ -63,7 +62,7 @@ static void setup_buffer(uint8_t *buf, uint_t seed, int len)
 /*
   check a random buffer based on a seed
 */
-static BOOL check_buffer(uint8_t *buf, uint_t seed, int len, int line)
+static bool check_buffer(uint8_t *buf, uint_t seed, int len, int line)
 {
        int i;
        srandom(seed);
@@ -72,10 +71,10 @@ static BOOL check_buffer(uint8_t *buf, uint_t seed, int len, int line)
                if (buf[i] != v) {
                        printf("Buffer incorrect at line %d! ofs=%d v1=0x%x v2=0x%x\n", 
                               line, i, buf[i], v);
-                       return False;
+                       return false;
                }
        }
-       return True;
+       return true;
 }
 
 /*
@@ -85,7 +84,7 @@ static bool test_read(struct torture_context *tctx, struct smbcli_state *cli)
 {
        union smb_read io;
        NTSTATUS status;
-       BOOL ret = True;
+       bool ret = true;
        int fnum;
        uint8_t *buf;
        const int maxsize = 90000;
@@ -93,19 +92,24 @@ static bool test_read(struct torture_context *tctx, struct smbcli_state *cli)
        const char *test_data = "TEST DATA";
        uint_t seed = time(NULL);
 
-       buf = talloc_zero_size(tctx, maxsize);
+       buf = talloc_zero_array(tctx, uint8_t, maxsize);
+
+       if (!torture_setting_bool(tctx, "read_support", true)) {
+               printf("server refuses to support READ\n");
+               return true;
+       }
 
        if (!torture_setup_dir(cli, BASEDIR)) {
-               return False;
+               return false;
        }
 
        printf("Testing RAW_READ_READ\n");
        io.generic.level = RAW_READ_READ;
-       
+
        fnum = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT, DENY_NONE);
        if (fnum == -1) {
                printf("Failed to create %s - %s\n", fname, smbcli_errstr(cli->tree));
-               ret = False;
+               ret = false;
                goto done;
        }
 
@@ -143,7 +147,7 @@ static bool test_read(struct torture_context *tctx, struct smbcli_state *cli)
        CHECK_STATUS(status, NT_STATUS_OK);
        CHECK_VALUE(io.read.out.nread, strlen(test_data));
        if (memcmp(buf, test_data, strlen(test_data)) != 0) {
-               ret = False;
+               ret = false;
                printf("incorrect data at %d!? (%s:%s)\n", __LINE__, test_data, buf);
                goto done;
        }
@@ -155,7 +159,7 @@ static bool test_read(struct torture_context *tctx, struct smbcli_state *cli)
        CHECK_STATUS(status, NT_STATUS_OK);
        CHECK_VALUE(io.read.out.nread, strlen(test_data)-1);
        if (memcmp(buf, test_data+1, strlen(test_data)-1) != 0) {
-               ret = False;
+               ret = false;
                printf("incorrect data at %d!? (%s:%s)\n", __LINE__, test_data+1, buf);
                goto done;
        }
@@ -185,7 +189,7 @@ static bool test_read(struct torture_context *tctx, struct smbcli_state *cli)
        cli->session->pid++;
        if (NT_STATUS_IS_ERR(smbcli_lock(cli->tree, fnum, 103, 1, 0, WRITE_LOCK))) {
                printf("Failed to lock file at %d\n", __LINE__);
-               ret = False;
+               ret = false;
                goto done;
        }
        cli->session->pid--;
@@ -212,7 +216,7 @@ static bool test_lockread(struct torture_context *tctx,
 {
        union smb_read io;
        NTSTATUS status;
-       BOOL ret = True;
+       bool ret = true;
        int fnum;
        uint8_t *buf;
        const int maxsize = 90000;
@@ -220,10 +224,15 @@ static bool test_lockread(struct torture_context *tctx,
        const char *test_data = "TEST DATA";
        uint_t seed = time(NULL);
 
-       buf = talloc_zero_size(tctx, maxsize);
+       if (!cli->transport->negotiate.lockread_supported) {
+               printf("Server does not support lockread - skipping\n");
+               return true;
+       }
+
+       buf = talloc_zero_array(tctx, uint8_t, maxsize);
 
        if (!torture_setup_dir(cli, BASEDIR)) {
-               return False;
+               return false;
        }
 
        printf("Testing RAW_READ_LOCKREAD\n");
@@ -232,7 +241,7 @@ static bool test_lockread(struct torture_context *tctx,
        fnum = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT, DENY_NONE);
        if (fnum == -1) {
                printf("Failed to create %s - %s\n", fname, smbcli_errstr(cli->tree));
-               ret = False;
+               ret = false;
                goto done;
        }
 
@@ -282,7 +291,7 @@ static bool test_lockread(struct torture_context *tctx,
        CHECK_STATUS(status, NT_STATUS_OK);
        CHECK_VALUE(io.lockread.out.nread, strlen(test_data));
        if (memcmp(buf, test_data, strlen(test_data)) != 0) {
-               ret = False;
+               ret = false;
                printf("incorrect data at %d!? (%s:%s)\n", __LINE__, test_data, buf);
                goto done;
        }
@@ -298,7 +307,7 @@ static bool test_lockread(struct torture_context *tctx,
 
        CHECK_VALUE(io.lockread.out.nread, strlen(test_data)-1);
        if (memcmp(buf, test_data+1, strlen(test_data)-1) != 0) {
-               ret = False;
+               ret = false;
                printf("incorrect data at %d!? (%s:%s)\n", __LINE__, test_data+1, buf);
                goto done;
        }
@@ -332,7 +341,7 @@ static bool test_lockread(struct torture_context *tctx,
        cli->session->pid++;
        if (NT_STATUS_IS_ERR(smbcli_lock(cli->tree, fnum, 103, 1, 0, WRITE_LOCK))) {
                printf("Failed to lock file at %d\n", __LINE__);
-               ret = False;
+               ret = false;
                goto done;
        }
        cli->session->pid--;
@@ -357,7 +366,7 @@ static bool test_readx(struct torture_context *tctx, struct smbcli_state *cli)
 {
        union smb_read io;
        NTSTATUS status;
-       BOOL ret = True;
+       bool ret = true;
        int fnum;
        uint8_t *buf;
        const int maxsize = 90000;
@@ -365,10 +374,10 @@ static bool test_readx(struct torture_context *tctx, struct smbcli_state *cli)
        const char *test_data = "TEST DATA";
        uint_t seed = time(NULL);
 
-       buf = talloc_zero_size(tctx, maxsize);
+       buf = talloc_zero_array(tctx, uint8_t, maxsize);
 
        if (!torture_setup_dir(cli, BASEDIR)) {
-               return False;
+               return false;
        }
 
        printf("Testing RAW_READ_READX\n");
@@ -376,7 +385,7 @@ static bool test_readx(struct torture_context *tctx, struct smbcli_state *cli)
        fnum = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT, DENY_NONE);
        if (fnum == -1) {
                printf("Failed to create %s - %s\n", fname, smbcli_errstr(cli->tree));
-               ret = False;
+               ret = false;
                goto done;
        }
 
@@ -387,7 +396,7 @@ static bool test_readx(struct torture_context *tctx, struct smbcli_state *cli)
        io.readx.in.maxcnt = 1;
        io.readx.in.offset = 0;
        io.readx.in.remaining = 0;
-       io.readx.in.read_for_execute = False;
+       io.readx.in.read_for_execute = false;
        io.readx.out.data = buf;
        status = smb_raw_read(cli->tree, &io);
 
@@ -417,7 +426,7 @@ static bool test_readx(struct torture_context *tctx, struct smbcli_state *cli)
        io.readx.in.file.fnum = fnum;
        io.readx.in.offset = 0;
        io.readx.in.remaining = 0;
-       io.readx.in.read_for_execute = False;
+       io.readx.in.read_for_execute = false;
        io.readx.in.mincnt = strlen(test_data);
        io.readx.in.maxcnt = strlen(test_data);
        status = smb_raw_read(cli->tree, &io);
@@ -426,7 +435,7 @@ static bool test_readx(struct torture_context *tctx, struct smbcli_state *cli)
        CHECK_VALUE(io.readx.out.remaining, 0xFFFF);
        CHECK_VALUE(io.readx.out.compaction_mode, 0);
        if (memcmp(buf, test_data, strlen(test_data)) != 0) {
-               ret = False;
+               ret = false;
                printf("incorrect data at %d!? (%s:%s)\n", __LINE__, test_data, buf);
                goto done;
        }
@@ -441,7 +450,7 @@ static bool test_readx(struct torture_context *tctx, struct smbcli_state *cli)
        CHECK_VALUE(io.readx.out.remaining, 0xFFFF);
        CHECK_VALUE(io.readx.out.compaction_mode, 0);
        if (memcmp(buf, test_data+1, strlen(test_data)-1) != 0) {
-               ret = False;
+               ret = false;
                printf("incorrect data at %d!? (%s:%s)\n", __LINE__, test_data+1, buf);
                goto done;
        }
@@ -458,11 +467,50 @@ static bool test_readx(struct torture_context *tctx, struct smbcli_state *cli)
                CHECK_VALUE(io.readx.out.compaction_mode, 0);
        }
 
+       printf("Trying mincnt past EOF\n");
+       memset(buf, 0, maxsize);
+       io.readx.in.offset = 0;
+       io.readx.in.mincnt = 100;
+       io.readx.in.maxcnt = 110;
+       status = smb_raw_read(cli->tree, &io);
+       CHECK_STATUS(status, NT_STATUS_OK);
+       CHECK_VALUE(io.readx.out.remaining, 0xFFFF);
+       CHECK_VALUE(io.readx.out.compaction_mode, 0);
+       CHECK_VALUE(io.readx.out.nread, strlen(test_data));
+       if (memcmp(buf, test_data, strlen(test_data)) != 0) {
+               ret = false;
+               printf("incorrect data at %d!? (%s:%s)\n", __LINE__, test_data, buf);
+               goto done;
+       }
+
+
        setup_buffer(buf, seed, maxsize);
        smbcli_write(cli->tree, fnum, 0, buf, 0, maxsize);
        memset(buf, 0, maxsize);
 
-       printf("Trying large read\n");
+       printf("Trying page sized read\n");
+       io.readx.in.offset = 0;
+       io.readx.in.mincnt = 0x1000;
+       io.readx.in.maxcnt = 0x1000;
+       status = smb_raw_read(cli->tree, &io);
+       CHECK_STATUS(status, NT_STATUS_OK);
+       CHECK_VALUE(io.readx.out.remaining, 0xFFFF);
+       CHECK_VALUE(io.readx.out.compaction_mode, 0);
+       CHECK_VALUE(io.readx.out.nread, io.readx.in.maxcnt);
+       CHECK_BUFFER(buf, seed, io.readx.out.nread);
+
+       printf("Trying page + 1 sized read (check alignment)\n");
+       io.readx.in.offset = 0;
+       io.readx.in.mincnt = 0x1001;
+       io.readx.in.maxcnt = 0x1001;
+       status = smb_raw_read(cli->tree, &io);
+       CHECK_STATUS(status, NT_STATUS_OK);
+       CHECK_VALUE(io.readx.out.remaining, 0xFFFF);
+       CHECK_VALUE(io.readx.out.compaction_mode, 0);
+       CHECK_VALUE(io.readx.out.nread, io.readx.in.maxcnt);
+       CHECK_BUFFER(buf, seed, io.readx.out.nread);
+
+       printf("Trying large read (UINT16_MAX)\n");
        io.readx.in.offset = 0;
        io.readx.in.mincnt = 0xFFFF;
        io.readx.in.maxcnt = 0xFFFF;
@@ -481,8 +529,9 @@ static bool test_readx(struct torture_context *tctx, struct smbcli_state *cli)
        CHECK_STATUS(status, NT_STATUS_OK);
        CHECK_VALUE(io.readx.out.remaining, 0xFFFF);
        CHECK_VALUE(io.readx.out.compaction_mode, 0);
-       if (lp_parm_bool(-1, "torture", "samba3", False)) {
-               printf("SAMBA3: large read extension\n");
+       if (torture_setting_bool(tctx, "samba3", false) ||
+           torture_setting_bool(tctx, "samba4", false)) {
+               printf("SAMBA: large read extension\n");
                CHECK_VALUE(io.readx.out.nread, 80000);
        } else {
                CHECK_VALUE(io.readx.out.nread, 0);
@@ -525,8 +574,9 @@ static bool test_readx(struct torture_context *tctx, struct smbcli_state *cli)
                io.readx.in.maxcnt = 0x10000;
                status = smb_raw_read(cli->tree, &io);
                CHECK_STATUS(status, NT_STATUS_OK);
-               if (lp_parm_bool(-1, "torture", "samba3", False)) {
-                       printf("SAMBA3: large read extension\n");
+               if (torture_setting_bool(tctx, "samba3", false) || 
+                   torture_setting_bool(tctx, "samba4", false)) {
+                       printf("SAMBA: large read extension\n");
                        CHECK_VALUE(io.readx.out.nread, 0x10000);
                } else {
                        CHECK_VALUE(io.readx.out.nread, 0);
@@ -535,19 +585,22 @@ static bool test_readx(struct torture_context *tctx, struct smbcli_state *cli)
                io.readx.in.maxcnt = 0x10001;
                status = smb_raw_read(cli->tree, &io);
                CHECK_STATUS(status, NT_STATUS_OK);
-               if (lp_parm_bool(-1, "torture", "samba3", False)) {
-                       printf("SAMBA3: large read extension\n");
+               if (torture_setting_bool(tctx, "samba3", false) ||
+                   torture_setting_bool(tctx, "samba4", false)) {
+                       printf("SAMBA: large read extension\n");
                        CHECK_VALUE(io.readx.out.nread, 0x10001);
                } else {
                        CHECK_VALUE(io.readx.out.nread, 0);
                }
+       } else {
+               printf("Server does not support the CAP_LARGE_READX extension\n");
        }
 
        printf("Trying locked region\n");
        cli->session->pid++;
        if (NT_STATUS_IS_ERR(smbcli_lock(cli->tree, fnum, 103, 1, 0, WRITE_LOCK))) {
                printf("Failed to lock file at %d\n", __LINE__);
-               ret = False;
+               ret = false;
                goto done;
        }
        cli->session->pid--;
@@ -573,7 +626,7 @@ static bool test_readx(struct torture_context *tctx, struct smbcli_state *cli)
 
        if (NT_STATUS_IS_ERR(smbcli_lock64(cli->tree, fnum, io.readx.in.offset, 1, 0, WRITE_LOCK))) {
                printf("Failed to lock file at %d\n", __LINE__);
-               ret = False;
+               ret = false;
                goto done;
        }
 
@@ -596,7 +649,7 @@ static bool test_readbraw(struct torture_context *tctx,
 {
        union smb_read io;
        NTSTATUS status;
-       BOOL ret = True;
+       bool ret = true;
        int fnum;
        uint8_t *buf;
        const int maxsize = 90000;
@@ -604,10 +657,15 @@ static bool test_readbraw(struct torture_context *tctx,
        const char *test_data = "TEST DATA";
        uint_t seed = time(NULL);
 
-       buf = talloc_zero_size(tctx, maxsize);
+       if (!cli->transport->negotiate.readbraw_supported) {
+               printf("Server does not support readbraw - skipping\n");
+               return true;
+       }
+
+       buf = talloc_zero_array(tctx, uint8_t, maxsize);
 
        if (!torture_setup_dir(cli, BASEDIR)) {
-               return False;
+               return false;
        }
 
        printf("Testing RAW_READ_READBRAW\n");
@@ -615,7 +673,7 @@ static bool test_readbraw(struct torture_context *tctx,
        fnum = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT, DENY_NONE);
        if (fnum == -1) {
                printf("Failed to create %s - %s\n", fname, smbcli_errstr(cli->tree));
-               ret = False;
+               ret = false;
                goto done;
        }
 
@@ -657,7 +715,7 @@ static bool test_readbraw(struct torture_context *tctx,
        CHECK_STATUS(status, NT_STATUS_OK);
        CHECK_VALUE(io.readbraw.out.nread, strlen(test_data));
        if (memcmp(buf, test_data, strlen(test_data)) != 0) {
-               ret = False;
+               ret = false;
                printf("incorrect data at %d!? (%s:%s)\n", __LINE__, test_data, buf);
                goto done;
        }
@@ -670,7 +728,7 @@ static bool test_readbraw(struct torture_context *tctx,
        CHECK_STATUS(status, NT_STATUS_OK);
        CHECK_VALUE(io.readbraw.out.nread, strlen(test_data)-1);
        if (memcmp(buf, test_data+1, strlen(test_data)-1) != 0) {
-               ret = False;
+               ret = false;
                printf("incorrect data at %d!? (%s:%s)\n", __LINE__, test_data+1, buf);
                goto done;
        }
@@ -722,7 +780,7 @@ static bool test_readbraw(struct torture_context *tctx,
        cli->session->pid++;
        if (NT_STATUS_IS_ERR(smbcli_lock(cli->tree, fnum, 103, 1, 0, WRITE_LOCK))) {
                printf("Failed to lock file at %d\n", __LINE__);
-               ret = False;
+               ret = false;
                goto done;
        }
        cli->session->pid--;
@@ -771,23 +829,23 @@ static bool test_read_for_execute(struct torture_context *tctx,
        union smb_write wr;
        union smb_read rd;
        NTSTATUS status;
-       BOOL ret = True;
+       bool ret = true;
        int fnum=0;
        uint8_t *buf;
        const int maxsize = 900;
        const char *fname = BASEDIR "\\test.txt";
        const uint8_t data[] = "TEST DATA";
 
-       buf = talloc_zero_size(tctx, maxsize);
+       buf = talloc_zero_array(tctx, uint8_t, maxsize);
 
        if (!torture_setup_dir(cli, BASEDIR)) {
-               return False;
+               return false;
        }
 
        printf("Testing RAW_READ_READX with read_for_execute\n");
 
        op.generic.level = RAW_OPEN_NTCREATEX;
-       op.ntcreatex.in.root_fid = 0;
+       op.ntcreatex.in.root_fid.fnum = 0;
        op.ntcreatex.in.flags = 0;
        op.ntcreatex.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
        op.ntcreatex.in.create_options = 0;
@@ -818,7 +876,7 @@ static bool test_read_for_execute(struct torture_context *tctx,
 
        printf("open file with SEC_FILE_EXECUTE\n");
        op.generic.level = RAW_OPEN_NTCREATEX;
-       op.ntcreatex.in.root_fid = 0;
+       op.ntcreatex.in.root_fid.fnum = 0;
        op.ntcreatex.in.flags = 0;
        op.ntcreatex.in.access_mask = SEC_FILE_EXECUTE;
        op.ntcreatex.in.create_options = 0;
@@ -840,7 +898,7 @@ static bool test_read_for_execute(struct torture_context *tctx,
        rd.readx.in.maxcnt = maxsize;
        rd.readx.in.offset = 0;
        rd.readx.in.remaining = 0;
-       rd.readx.in.read_for_execute = True;
+       rd.readx.in.read_for_execute = true;
        rd.readx.out.data = buf;
        status = smb_raw_read(cli->tree, &rd);
        CHECK_STATUS(status, NT_STATUS_OK);
@@ -855,7 +913,7 @@ static bool test_read_for_execute(struct torture_context *tctx,
        rd.readx.in.maxcnt = maxsize;
        rd.readx.in.offset = 0;
        rd.readx.in.remaining = 0;
-       rd.readx.in.read_for_execute = False;
+       rd.readx.in.read_for_execute = false;
        rd.readx.out.data = buf;
        status = smb_raw_read(cli->tree, &rd);
        CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
@@ -865,7 +923,7 @@ static bool test_read_for_execute(struct torture_context *tctx,
 
        printf("open file with SEC_FILE_READ_DATA\n");
        op.generic.level = RAW_OPEN_NTCREATEX;
-       op.ntcreatex.in.root_fid = 0;
+       op.ntcreatex.in.root_fid.fnum = 0;
        op.ntcreatex.in.flags = 0;
        op.ntcreatex.in.access_mask = SEC_FILE_READ_DATA;
        op.ntcreatex.in.create_options = 0;
@@ -887,7 +945,7 @@ static bool test_read_for_execute(struct torture_context *tctx,
        rd.readx.in.maxcnt = maxsize;
        rd.readx.in.offset = 0;
        rd.readx.in.remaining = 0;
-       rd.readx.in.read_for_execute = True;
+       rd.readx.in.read_for_execute = true;
        rd.readx.out.data = buf;
        status = smb_raw_read(cli->tree, &rd);
        CHECK_STATUS(status, NT_STATUS_OK);
@@ -902,7 +960,7 @@ static bool test_read_for_execute(struct torture_context *tctx,
        rd.readx.in.maxcnt = maxsize;
        rd.readx.in.offset = 0;
        rd.readx.in.remaining = 0;
-       rd.readx.in.read_for_execute = False;
+       rd.readx.in.read_for_execute = false;
        rd.readx.out.data = buf;
        status = smb_raw_read(cli->tree, &rd);
        CHECK_STATUS(status, NT_STATUS_OK);