This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
+ the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "includes.h"
+#include "torture/torture.h"
+#include "system/filesys.h"
#include "libcli/raw/libcliraw.h"
-#include "librpc/gen_ndr/ndr_security.h"
+#include "libcli/libcli.h"
+#include "torture/util.h"
-extern BOOL torture_showall;
extern int torture_failures;
#define CHECK_MAX_FAILURES(label) do { if (++failures >= torture_failures) goto label; } while (0)
static const char *denystr(int denymode)
{
- struct {
+ const struct {
int v;
const char *name;
} deny_modes[] = {
static const char *openstr(int mode)
{
- struct {
+ const struct {
int v;
const char *name;
} open_modes[] = {
static const char *resultstr(enum deny_result res)
{
- struct {
+ const struct {
enum deny_result res;
const char *name;
} results[] = {
};
-static void progress_bar(uint_t i, uint_t total)
+static void progress_bar(struct torture_context *tctx, uint_t i, uint_t total)
{
- printf("%5d/%5d\r", i, total);
- fflush(stdout);
+ if (torture_setting_bool(tctx, "progress", true)) {
+ torture_comment(tctx, "%5d/%5d\r", i, total);
+ fflush(stdout);
+ }
}
/*
this produces a matrix of deny mode behaviour for 1 connection
*/
-BOOL torture_denytest1(void)
+BOOL torture_denytest1(struct torture_context *tctx,
+ struct smbcli_state *cli1)
{
- static struct smbcli_state *cli1;
int fnum1, fnum2;
int i;
BOOL correct = True;
const char *fnames[2] = {"\\denytest1.dat", "\\denytest1.exe"};
int failures=0;
- if (!torture_open_connection(&cli1)) {
- return False;
- }
-
- printf("starting denytest1\n");
-
- printf("Testing deny modes with 1 connection\n");
+ torture_comment(tctx, "Testing deny modes with 1 connection\n");
for (i=0;i<2;i++) {
smbcli_unlink(cli1->tree, fnames[i]);
smbcli_close(cli1->tree, fnum1);
}
- printf("testing %d entries\n", ARRAY_SIZE(denytable1));
+ torture_comment(tctx, "testing %d entries\n", (int)ARRAY_SIZE(denytable1));
GetTimeOfDay(&tv_start);
enum deny_result res;
const char *fname = fnames[denytable1[i].isexe];
- progress_bar(i, ARRAY_SIZE(denytable1));
+ progress_bar(tctx, i, ARRAY_SIZE(denytable1));
fnum1 = smbcli_open(cli1->tree, fname,
denytable1[i].mode1,
} else if (fnum2 == -1) {
res = A_0;
} else {
- char x = 1;
+ uint8_t x = 1;
res = A_0;
- if (smbcli_read(cli1->tree, fnum2, (void *)&x, 0, 1) == 1) {
+ if (smbcli_read(cli1->tree, fnum2, &x, 0, 1) == 1) {
res += A_R;
}
- if (smbcli_write(cli1->tree, fnum2, 0, (void *)&x, 0, 1) == 1) {
+ if (smbcli_write(cli1->tree, fnum2, 0, &x, 0, 1) == 1) {
res += A_W;
}
}
- if (torture_showall || res != denytable1[i].result) {
+ if (torture_setting_bool(tctx, "showall", False) ||
+ res != denytable1[i].result) {
int64_t tdif;
GetTimeOfDay(&tv);
tdif = usec_time_diff(&tv, &tv_start);
tdif /= 1000;
- printf("%lld: %s %8s %10s %8s %10s %s (correct=%s)\n",
- tdif,
+ torture_comment(tctx, "%lld: %s %8s %10s %8s %10s %s (correct=%s)\n",
+ (long long)tdif,
fname,
denystr(denytable1[i].deny1),
openstr(denytable1[i].mode1),
smbcli_unlink(cli1->tree, fnames[i]);
}
- if (!torture_close_connection(cli1)) {
- correct = False;
- }
-
- printf("finshed denytest1 (%d failures)\n", failures);
+ torture_comment(tctx, "finshed denytest1 (%d failures)\n", failures);
return correct;
}
/*
this produces a matrix of deny mode behaviour with 2 connections
*/
-BOOL torture_denytest2(void)
+BOOL torture_denytest2(struct torture_context *tctx,
+ struct smbcli_state *cli1,
+ struct smbcli_state *cli2)
{
- static struct smbcli_state *cli1, *cli2;
int fnum1, fnum2;
int i;
BOOL correct = True;
struct timeval tv, tv_start;
int failures=0;
- if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) {
- return False;
- }
-
- printf("starting denytest2\n");
-
- printf("Testing deny modes with 2 connections\n");
-
for (i=0;i<2;i++) {
smbcli_unlink(cli1->tree, fnames[i]);
fnum1 = smbcli_open(cli1->tree, fnames[i], O_RDWR|O_CREAT, DENY_NONE);
enum deny_result res;
const char *fname = fnames[denytable2[i].isexe];
- progress_bar(i, ARRAY_SIZE(denytable1));
+ progress_bar(tctx, i, ARRAY_SIZE(denytable1));
fnum1 = smbcli_open(cli1->tree, fname,
denytable2[i].mode1,
} else if (fnum2 == -1) {
res = A_0;
} else {
- char x = 1;
+ uint8_t x = 1;
res = A_0;
- if (smbcli_read(cli2->tree, fnum2, (void *)&x, 0, 1) == 1) {
+ if (smbcli_read(cli2->tree, fnum2, &x, 0, 1) == 1) {
res += A_R;
}
- if (smbcli_write(cli2->tree, fnum2, 0, (void *)&x, 0, 1) == 1) {
+ if (smbcli_write(cli2->tree, fnum2, 0, &x, 0, 1) == 1) {
res += A_W;
}
}
- if (torture_showall || res != denytable2[i].result) {
+ if (torture_setting_bool(tctx, "showall", False) ||
+ res != denytable2[i].result) {
int64_t tdif;
GetTimeOfDay(&tv);
tdif = usec_time_diff(&tv, &tv_start);
tdif /= 1000;
- printf("%lld: %s %8s %10s %8s %10s %s (correct=%s)\n",
- tdif,
+ torture_comment(tctx, "%lld: %s %8s %10s %8s %10s %s (correct=%s)\n",
+ (long long)tdif,
fname,
denystr(denytable2[i].deny1),
openstr(denytable2[i].mode1),
smbcli_unlink(cli1->tree, fnames[i]);
}
- if (!torture_close_connection(cli1)) {
- correct = False;
- }
- if (!torture_close_connection(cli2)) {
- correct = False;
- }
-
- printf("finshed denytest2 (%d failures)\n", failures);
+ torture_comment(tctx, "finshed denytest2 (%d failures)\n", failures);
return correct;
}
/*
simple test harness for playing with deny modes
*/
-BOOL torture_denytest3(void)
+BOOL torture_denytest3(struct torture_context *tctx,
+ struct smbcli_state *cli1,
+ struct smbcli_state *cli2)
{
- struct smbcli_state *cli1, *cli2;
int fnum1, fnum2;
const char *fname;
- printf("starting deny3 test\n");
-
- printf("Testing simple deny modes\n");
-
- if (!torture_open_connection(&cli1)) {
- return False;
- }
- if (!torture_open_connection(&cli2)) {
- return False;
- }
-
fname = "\\deny_dos1.dat";
smbcli_unlink(cli1->tree, fname);
if (fnum1 != -1) smbcli_close(cli1->tree, fnum1);
if (fnum2 != -1) smbcli_close(cli1->tree, fnum2);
smbcli_unlink(cli1->tree, fname);
- printf("fnum1=%d fnum2=%d\n", fnum1, fnum2);
+ torture_comment(tctx, "fnum1=%d fnum2=%d\n", fnum1, fnum2);
fname = "\\deny_dos2.dat";
if (fnum1 != -1) smbcli_close(cli1->tree, fnum1);
if (fnum2 != -1) smbcli_close(cli2->tree, fnum2);
smbcli_unlink(cli1->tree, fname);
- printf("fnum1=%d fnum2=%d\n", fnum1, fnum2);
-
-
- torture_close_connection(cli1);
- torture_close_connection(cli2);
+ torture_comment(tctx, "fnum1=%d fnum2=%d\n", fnum1, fnum2);
return True;
}
determine if two opens conflict
*/
static NTSTATUS predict_share_conflict(uint32_t sa1, uint32_t am1, uint32_t sa2, uint32_t am2,
- uint16_t flags2, enum deny_result *res)
+ BOOL read_for_execute, enum deny_result *res)
{
#define CHECK_MASK(am, sa, right, share) do { \
if (((am) & (right)) && !((sa) & (share))) { \
}
if (am2 & SEC_FILE_READ_DATA) {
*res += A_R;
- } else if ((am2 & SEC_FILE_EXECUTE) &&
- (flags2 & FLAGS2_READ_PERMIT_EXECUTE)) {
+ } else if ((am2 & SEC_FILE_EXECUTE) && read_for_execute) {
*res += A_R;
}
/*
a denytest for ntcreatex
*/
-static BOOL torture_ntdenytest(struct smbcli_state *cli1, struct smbcli_state *cli2, int client)
+static BOOL torture_ntdenytest(struct torture_context *tctx,
+ struct smbcli_state *cli1, struct smbcli_state *cli2, int client)
{
const struct bit_value share_access_bits[] = {
{ NTCREATEX_SHARE_ACCESS_READ, "S_R" },
union smb_open io1, io2;
extern int torture_numops;
int failures = 0;
- char buf[1];
+ uint8_t buf[1];
+
+ torture_comment(tctx, "format: server correct\n");
ZERO_STRUCT(buf);
io1.ntcreatex.in.fname = fname;
io2 = io1;
- printf("testing %d entries on %s\n", torture_numops, fname);
+ torture_comment(tctx, "testing %d entries on %s\n", torture_numops, fname);
for (i=0;i<torture_numops;i++) {
NTSTATUS status1, status2, status2_p;
int64_t tdif;
- TALLOC_CTX *mem_ctx = talloc(NULL, 0);
+ TALLOC_CTX *mem_ctx = talloc_new(NULL);
enum deny_result res, res2;
int b_sa1 = random() & ((1<<nbits1)-1);
int b_am1 = random() & ((1<<nbits2)-1);
int b_sa2 = random() & ((1<<nbits1)-1);
int b_am2 = random() & ((1<<nbits2)-1);
+ BOOL read_for_execute;
- progress_bar(i, torture_numops);
+ progress_bar(tctx, i, torture_numops);
io1.ntcreatex.in.share_access = map_bits(share_access_bits, b_sa1, nbits1);
io1.ntcreatex.in.access_mask = map_bits(access_mask_bits, b_am1, nbits2);
status2 = smb_raw_open(cli2->tree, mem_ctx, &io2);
if (random() % 2 == 0) {
- cli2->tree->session->flags2 |= FLAGS2_READ_PERMIT_EXECUTE;
+ read_for_execute = True;
} else {
- cli2->tree->session->flags2 &= ~FLAGS2_READ_PERMIT_EXECUTE;
+ read_for_execute = False;
}
if (!NT_STATUS_IS_OK(status1)) {
} else if (!NT_STATUS_IS_OK(status2)) {
res = A_0;
} else {
+ union smb_read r;
+ NTSTATUS status;
+
+ /* we can't use smbcli_read() as we need to
+ set read_for_execute */
+ r.readx.level = RAW_READ_READX;
+ r.readx.in.file.fnum = io2.ntcreatex.out.file.fnum;
+ r.readx.in.offset = 0;
+ r.readx.in.mincnt = sizeof(buf);
+ r.readx.in.maxcnt = sizeof(buf);
+ r.readx.in.remaining = 0;
+ r.readx.in.read_for_execute = read_for_execute;
+ r.readx.out.data = buf;
+
res = A_0;
- if (smbcli_read(cli2->tree,
- io2.ntcreatex.out.fnum, (void *)buf, 0, sizeof(buf)) >= 1) {
+ status = smb_raw_read(cli2->tree, &r);
+ if (NT_STATUS_IS_OK(status)) {
res += A_R;
}
- if (smbcli_write(cli2->tree,
- io2.ntcreatex.out.fnum, 0, (void *)buf, 0, sizeof(buf)) >= 1) {
+ if (smbcli_write(cli2->tree, io2.ntcreatex.out.file.fnum,
+ 0, buf, 0, sizeof(buf)) >= 1) {
res += A_W;
}
}
if (NT_STATUS_IS_OK(status1)) {
- smbcli_close(cli1->tree, io1.ntcreatex.out.fnum);
+ smbcli_close(cli1->tree, io1.ntcreatex.out.file.fnum);
}
if (NT_STATUS_IS_OK(status2)) {
- smbcli_close(cli2->tree, io2.ntcreatex.out.fnum);
+ smbcli_close(cli2->tree, io2.ntcreatex.out.file.fnum);
}
status2_p = predict_share_conflict(io1.ntcreatex.in.share_access,
io1.ntcreatex.in.access_mask,
io2.ntcreatex.in.share_access,
io2.ntcreatex.in.access_mask,
- cli2->tree->session->flags2,
+ read_for_execute,
&res2);
GetTimeOfDay(&tv);
tdif = usec_time_diff(&tv, &tv_start);
tdif /= 1000;
- if (torture_showall ||
+ if (torture_setting_bool(tctx, "showall", False) ||
!NT_STATUS_EQUAL(status2, status2_p) ||
res != res2) {
- printf("\n%-20s %-70s\n%-20s %-70s %4s %4s %s/%s\n",
+ torture_comment(tctx, "\n%-20s %-70s\n%-20s %-70s %4s %4s %s/%s\n",
bit_string(mem_ctx, share_access_bits, b_sa1, nbits1),
bit_string(mem_ctx, access_mask_bits, b_am1, nbits2),
bit_string(mem_ctx, share_access_bits, b_sa2, nbits1),
failed:
smbcli_unlink(cli1->tree, fname);
- printf("finshed ntdenytest (%d failures)\n", failures);
+ torture_comment(tctx, "finshed ntdenytest (%d failures)\n", failures);
return correct;
}
/*
a denytest for ntcreatex
*/
-BOOL torture_ntdenytest1(struct smbcli_state *cli, int client)
+BOOL torture_ntdenytest1(struct torture_context *tctx, struct smbcli_state *cli, int client)
{
extern int torture_seed;
srandom(torture_seed + client);
- printf("starting ntdenytest1 client %d\n", client);
+ torture_comment(tctx, "starting ntdenytest1 client %d\n", client);
- return torture_ntdenytest(cli, cli, client);
+ return torture_ntdenytest(tctx, cli, cli, client);
}
/*
a denytest for ntcreatex
*/
-BOOL torture_ntdenytest2(void)
+BOOL torture_ntdenytest2(struct torture_context *torture,
+ struct smbcli_state *cli1,
+ struct smbcli_state *cli2)
{
- struct smbcli_state *cli1, *cli2;
- BOOL ret;
-
- if (!torture_open_connection(&cli1)) {
- return False;
- }
-
- if (!torture_open_connection(&cli2)) {
- return False;
- }
-
- printf("starting ntdenytest2\n");
-
- ret = torture_ntdenytest(cli1, cli2, 0);
-
- torture_close_connection(cli1);
- torture_close_connection(cli2);
-
- return ret;
+ return torture_ntdenytest(torture, cli1, cli2, 0);
}
#define CHECK_STATUS(status, correct) do { \
if (!NT_STATUS_EQUAL(status, correct)) { \
- printf("(%s) Incorrect status %s - should be %s\n", \
+ torture_comment(tctx, "(%s) Incorrect status %s - should be %s\n", \
__location__, nt_errstr(status), nt_errstr(correct)); \
ret = False; \
goto done; \
#define CHECK_VAL(v, correct) do { \
if ((v) != (correct)) { \
- printf("(%s) wrong value for %s 0x%x - should be 0x%x\n", \
+ torture_comment(tctx, "(%s) wrong value for %s 0x%x - should be 0x%x\n", \
__location__, #v, (int)(v), (int)correct); \
ret = False; \
}} while (0)
/*
test sharing of handles with DENY_DOS on a single connection
*/
-BOOL torture_denydos_sharing(void)
+BOOL torture_denydos_sharing(struct torture_context *tctx,
+ struct smbcli_state *cli)
{
- struct smbcli_state *cli;
union smb_open io;
union smb_fileinfo finfo;
const char *fname = "\\torture_denydos.txt";
NTSTATUS status;
- int fnum1, fnum2;
+ int fnum1 = -1, fnum2 = -1;
BOOL ret = True;
union smb_setfileinfo sfinfo;
TALLOC_CTX *mem_ctx;
- if (!torture_open_connection(&cli)) {
- return False;
- }
-
- mem_ctx = talloc(cli, 0);
+ mem_ctx = talloc_new(cli);
- printf("Checking DENY_DOS shared handle semantics\n");
+ torture_comment(tctx, "Checking DENY_DOS shared handle semantics\n");
smbcli_unlink(cli->tree, fname);
io.openx.level = RAW_OPEN_OPENX;
io.openx.in.size = 0;
io.openx.in.timeout = 0;
- printf("openx twice with RDWR/DENY_DOS\n");
+ torture_comment(tctx, "openx twice with RDWR/DENY_DOS\n");
status = smb_raw_open(cli->tree, mem_ctx, &io);
CHECK_STATUS(status, NT_STATUS_OK);
- fnum1 = io.openx.out.fnum;
+ fnum1 = io.openx.out.file.fnum;
status = smb_raw_open(cli->tree, mem_ctx, &io);
CHECK_STATUS(status, NT_STATUS_OK);
- fnum2 = io.openx.out.fnum;
+ fnum2 = io.openx.out.file.fnum;
- printf("fnum1=%d fnum2=%d\n", fnum1, fnum2);
+ torture_comment(tctx, "fnum1=%d fnum2=%d\n", fnum1, fnum2);
sfinfo.generic.level = RAW_SFILEINFO_POSITION_INFORMATION;
- sfinfo.position_information.file.fnum = fnum1;
+ sfinfo.position_information.in.file.fnum = fnum1;
sfinfo.position_information.in.position = 1000;
status = smb_raw_setfileinfo(cli->tree, &sfinfo);
CHECK_STATUS(status, NT_STATUS_OK);
- printf("two handles should be same file handle\n");
+ torture_comment(tctx, "two handles should be same file handle\n");
finfo.position_information.level = RAW_FILEINFO_POSITION_INFORMATION;
- finfo.position_information.in.fnum = fnum1;
+ finfo.position_information.in.file.fnum = fnum1;
status = smb_raw_fileinfo(cli->tree, mem_ctx, &finfo);
CHECK_STATUS(status, NT_STATUS_OK);
CHECK_VAL(finfo.position_information.out.position, 1000);
- finfo.position_information.in.fnum = fnum2;
+ finfo.position_information.in.file.fnum = fnum2;
status = smb_raw_fileinfo(cli->tree, mem_ctx, &finfo);
CHECK_STATUS(status, NT_STATUS_OK);
CHECK_VAL(finfo.position_information.out.position, 1000);
smbcli_close(cli->tree, fnum1);
smbcli_close(cli->tree, fnum2);
- printf("openx twice with RDWR/DENY_NONE\n");
+ torture_comment(tctx, "openx twice with RDWR/DENY_NONE\n");
io.openx.in.open_mode = OPENX_MODE_ACCESS_RDWR | OPENX_MODE_DENY_NONE;
status = smb_raw_open(cli->tree, mem_ctx, &io);
CHECK_STATUS(status, NT_STATUS_OK);
- fnum1 = io.openx.out.fnum;
+ fnum1 = io.openx.out.file.fnum;
io.openx.in.open_func = OPENX_OPEN_FUNC_OPEN;
status = smb_raw_open(cli->tree, mem_ctx, &io);
CHECK_STATUS(status, NT_STATUS_OK);
- fnum2 = io.openx.out.fnum;
+ fnum2 = io.openx.out.file.fnum;
- printf("fnum1=%d fnum2=%d\n", fnum1, fnum2);
+ torture_comment(tctx, "fnum1=%d fnum2=%d\n", fnum1, fnum2);
- printf("two handles should be separate\n");
+ torture_comment(tctx, "two handles should be separate\n");
sfinfo.generic.level = RAW_SFILEINFO_POSITION_INFORMATION;
- sfinfo.position_information.file.fnum = fnum1;
+ sfinfo.position_information.in.file.fnum = fnum1;
sfinfo.position_information.in.position = 1000;
status = smb_raw_setfileinfo(cli->tree, &sfinfo);
CHECK_STATUS(status, NT_STATUS_OK);
finfo.position_information.level = RAW_FILEINFO_POSITION_INFORMATION;
- finfo.position_information.in.fnum = fnum1;
+ finfo.position_information.in.file.fnum = fnum1;
status = smb_raw_fileinfo(cli->tree, mem_ctx, &finfo);
CHECK_STATUS(status, NT_STATUS_OK);
CHECK_VAL(finfo.position_information.out.position, 1000);
- finfo.position_information.in.fnum = fnum2;
+ finfo.position_information.in.file.fnum = fnum2;
status = smb_raw_fileinfo(cli->tree, mem_ctx, &finfo);
CHECK_STATUS(status, NT_STATUS_OK);
CHECK_VAL(finfo.position_information.out.position, 0);