#include "includes.h"
#include "torture/torture.h"
#include "libcli/raw/libcliraw.h"
+#include "libcli/raw/raw_proto.h"
#include "system/time.h"
#include "system/filesys.h"
#include "librpc/gen_ndr/security.h"
#include "torture/util.h"
#include "auth/credentials/credentials.h"
#include "lib/cmdline/popt_common.h"
-#include "param/param.h"
/* enum for whether reads/writes are possible on a file */
enum rdwr_mode {RDWR_NONE, RDWR_RDONLY, RDWR_WRONLY, RDWR_RDWR};
}} while (0)
#define CREATE_FILE do { \
- fnum = create_complex_file(cli, mem_ctx, fname); \
+ fnum = create_complex_file(cli, tctx, fname); \
if (fnum == -1) { \
printf("(%s) Failed to create %s - %s\n", __location__, fname, smbcli_errstr(cli->tree)); \
ret = false; \
time_t t1, t2; \
finfo.all_info.level = RAW_FILEINFO_ALL_INFO; \
finfo.all_info.in.file.path = fname; \
- status = smb_raw_pathinfo(cli->tree, mem_ctx, &finfo); \
+ status = smb_raw_pathinfo(cli->tree, tctx, &finfo); \
CHECK_STATUS(status, NT_STATUS_OK); \
t1 = t & ~1; \
t2 = nt_time_to_unix(finfo.all_info.out.field) & ~1; \
if (abs(t1-t2) > 2) { \
printf("(%s) wrong time for field %s %s - %s\n", \
__location__, #field, \
- timestring(mem_ctx, t1), \
- timestring(mem_ctx, t2)); \
- dump_all_info(mem_ctx, &finfo); \
+ timestring(tctx, t1), \
+ timestring(tctx, t2)); \
+ dump_all_info(tctx, &finfo); \
ret = false; \
}} while (0)
NTTIME t2; \
finfo.all_info.level = RAW_FILEINFO_ALL_INFO; \
finfo.all_info.in.file.path = fname; \
- status = smb_raw_pathinfo(cli->tree, mem_ctx, &finfo); \
+ status = smb_raw_pathinfo(cli->tree, tctx, &finfo); \
CHECK_STATUS(status, NT_STATUS_OK); \
t2 = finfo.all_info.out.field; \
if (t != t2) { \
printf("(%s) wrong time for field %s %s - %s\n", \
__location__, #field, \
- nt_time_string(mem_ctx, t), \
- nt_time_string(mem_ctx, t2)); \
- dump_all_info(mem_ctx, &finfo); \
+ nt_time_string(tctx, t), \
+ nt_time_string(tctx, t2)); \
+ dump_all_info(tctx, &finfo); \
ret = false; \
}} while (0)
#define CHECK_ALL_INFO(v, field) do { \
finfo.all_info.level = RAW_FILEINFO_ALL_INFO; \
finfo.all_info.in.file.path = fname; \
- status = smb_raw_pathinfo(cli->tree, mem_ctx, &finfo); \
+ status = smb_raw_pathinfo(cli->tree, tctx, &finfo); \
CHECK_STATUS(status, NT_STATUS_OK); \
if ((v) != (finfo.all_info.out.field)) { \
printf("(%s) wrong value for field %s 0x%x - 0x%x\n", \
__location__, #field, (int)v, (int)(finfo.all_info.out.field)); \
- dump_all_info(mem_ctx, &finfo); \
+ dump_all_info(tctx, &finfo); \
ret = false; \
}} while (0)
/*
test RAW_OPEN_OPEN
*/
-static bool test_open(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
+static bool test_open(struct smbcli_state *cli, struct torture_context *tctx)
{
union smb_open io;
union smb_fileinfo finfo;
io.openold.in.fname = fname;
io.openold.in.open_mode = OPEN_FLAGS_FCB;
io.openold.in.search_attrs = 0;
- status = smb_raw_open(cli->tree, mem_ctx, &io);
+ status = smb_raw_open(cli->tree, tctx, &io);
CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_NOT_FOUND);
fnum = io.openold.out.file.fnum;
CREATE_FILE;
smbcli_close(cli->tree, fnum);
- status = smb_raw_open(cli->tree, mem_ctx, &io);
+ status = smb_raw_open(cli->tree, tctx, &io);
CHECK_STATUS(status, NT_STATUS_OK);
fnum = io.openold.out.file.fnum;
CHECK_RDWR(fnum, RDWR_RDWR);
- status = smb_raw_open(cli->tree, mem_ctx, &io);
+ status = smb_raw_open(cli->tree, tctx, &io);
CHECK_STATUS(status, NT_STATUS_OK);
fnum2 = io.openold.out.file.fnum;
CHECK_RDWR(fnum2, RDWR_RDWR);
io.openold.in.search_attrs = 0;
io.openold.in.open_mode = OPEN_FLAGS_OPEN_READ;
- status = smb_raw_open(cli->tree, mem_ctx, &io);
+ status = smb_raw_open(cli->tree, tctx, &io);
CHECK_STATUS(status, NT_STATUS_OK);
fnum = io.openold.out.file.fnum;
CHECK_RDWR(fnum, RDWR_RDONLY);
smbcli_close(cli->tree, fnum);
io.openold.in.open_mode = OPEN_FLAGS_OPEN_WRITE;
- status = smb_raw_open(cli->tree, mem_ctx, &io);
+ status = smb_raw_open(cli->tree, tctx, &io);
CHECK_STATUS(status, NT_STATUS_OK);
fnum = io.openold.out.file.fnum;
CHECK_RDWR(fnum, RDWR_WRONLY);
smbcli_close(cli->tree, fnum);
io.openold.in.open_mode = OPEN_FLAGS_OPEN_RDWR;
- status = smb_raw_open(cli->tree, mem_ctx, &io);
+ status = smb_raw_open(cli->tree, tctx, &io);
CHECK_STATUS(status, NT_STATUS_OK);
fnum = io.openold.out.file.fnum;
CHECK_RDWR(fnum, RDWR_RDWR);
/* check the share modes roughly - not a complete matrix */
io.openold.in.open_mode = OPEN_FLAGS_OPEN_RDWR | OPEN_FLAGS_DENY_WRITE;
- status = smb_raw_open(cli->tree, mem_ctx, &io);
+ status = smb_raw_open(cli->tree, tctx, &io);
CHECK_STATUS(status, NT_STATUS_OK);
fnum = io.openold.out.file.fnum;
CHECK_RDWR(fnum, RDWR_RDWR);
}
io.openold.in.open_mode = OPEN_FLAGS_OPEN_RDWR | OPEN_FLAGS_DENY_NONE;
- status = smb_raw_open(cli->tree, mem_ctx, &io);
+ status = smb_raw_open(cli->tree, tctx, &io);
CHECK_STATUS(status, NT_STATUS_SHARING_VIOLATION);
io.openold.in.open_mode = OPEN_FLAGS_OPEN_READ | OPEN_FLAGS_DENY_NONE;
- status = smb_raw_open(cli->tree, mem_ctx, &io);
+ status = smb_raw_open(cli->tree, tctx, &io);
CHECK_STATUS(status, NT_STATUS_OK);
fnum2 = io.openold.out.file.fnum;
CHECK_RDWR(fnum2, RDWR_RDONLY);
io.openold.in.fname = fname;
io.openold.in.search_attrs = 0;
io.openold.in.open_mode = OPEN_FLAGS_OPEN_READ;
- status = smb_raw_open(cli->tree, mem_ctx, &io);
+ status = smb_raw_open(cli->tree, tctx, &io);
CHECK_STATUS(status, NT_STATUS_OK);
fnum = io.openold.out.file.fnum;
/*
test RAW_OPEN_OPENX
*/
-static bool test_openx(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
+static bool test_openx(struct smbcli_state *cli, struct torture_context *tctx)
{
union smb_open io;
union smb_fileinfo finfo;
/* check all combinations of open_func */
for (i=0; i<ARRAY_SIZE(open_funcs); i++) {
if (open_funcs[i].with_file) {
- fnum = create_complex_file(cli, mem_ctx, fname);
+ fnum = create_complex_file(cli, tctx, fname);
if (fnum == -1) {
d_printf("Failed to create file %s - %s\n", fname, smbcli_errstr(cli->tree));
ret = false;
smbcli_close(cli->tree, fnum);
}
io.openx.in.open_func = open_funcs[i].open_func;
- status = smb_raw_open(cli->tree, mem_ctx, &io);
+ status = smb_raw_open(cli->tree, tctx, &io);
if (!NT_STATUS_EQUAL(status, open_funcs[i].correct_status)) {
printf("(%s) incorrect status %s should be %s (i=%d with_file=%d open_func=0x%x)\n",
__location__, nt_errstr(status), nt_errstr(open_funcs[i].correct_status),
/* check the basic return fields */
io.openx.in.open_func = OPENX_OPEN_FUNC_OPEN | OPENX_OPEN_FUNC_CREATE;
- status = smb_raw_open(cli->tree, mem_ctx, &io);
+ status = smb_raw_open(cli->tree, tctx, &io);
CHECK_STATUS(status, NT_STATUS_OK);
fnum = io.openx.out.file.fnum;
smbcli_unlink(cli->tree, fname);
/* check the fields when the file already existed */
- fnum2 = create_complex_file(cli, mem_ctx, fname);
+ fnum2 = create_complex_file(cli, tctx, fname);
if (fnum2 == -1) {
ret = false;
goto done;
smbcli_close(cli->tree, fnum2);
io.openx.in.open_func = OPENX_OPEN_FUNC_OPEN;
- status = smb_raw_open(cli->tree, mem_ctx, &io);
+ status = smb_raw_open(cli->tree, tctx, &io);
CHECK_STATUS(status, NT_STATUS_OK);
fnum = io.openx.out.file.fnum;
CHECK_ALL_INFO(FILE_ATTRIBUTE_HIDDEN, attrib);
io.openx.in.search_attrs = FILE_ATTRIBUTE_HIDDEN;
- status = smb_raw_open(cli->tree, mem_ctx, &io);
+ status = smb_raw_open(cli->tree, tctx, &io);
CHECK_STATUS(status, NT_STATUS_OK);
smbcli_close(cli->tree, io.openx.out.file.fnum);
io.openx.in.search_attrs = 0;
- status = smb_raw_open(cli->tree, mem_ctx, &io);
+ status = smb_raw_open(cli->tree, tctx, &io);
CHECK_STATUS(status, NT_STATUS_OK);
smbcli_close(cli->tree, io.openx.out.file.fnum);
io.openx.in.open_func = OPENX_OPEN_FUNC_FAIL | OPENX_OPEN_FUNC_CREATE;
io.openx.in.search_attrs = 0;
io.openx.in.file_attrs = FILE_ATTRIBUTE_SYSTEM;
- status = smb_raw_open(cli->tree, mem_ctx, &io);
+ status = smb_raw_open(cli->tree, tctx, &io);
CHECK_STATUS(status, NT_STATUS_OK);
- if (lp_parm_bool(global_loadparm, NULL, "torture", "samba3", false)) {
+ if (torture_setting_bool(tctx, "samba3", false)) {
CHECK_ALL_INFO(FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_ARCHIVE,
attrib & ~(FILE_ATTRIBUTE_NONINDEXED|
FILE_ATTRIBUTE_SPARSE));
io.openx.in.open_func = OPENX_OPEN_FUNC_OPEN | OPENX_OPEN_FUNC_CREATE;
io.openx.in.file_attrs = 0;
io.openx.in.open_mode = OPENX_MODE_ACCESS_RDWR | OPENX_MODE_DENY_ALL;
- status = smb_raw_open(cli->tree, mem_ctx, &io);
+ status = smb_raw_open(cli->tree, tctx, &io);
CHECK_STATUS(status, NT_STATUS_OK);
fnum = io.openx.out.file.fnum;
io.openx.in.timeout = 20000;
tv = timeval_current();
io.openx.in.open_mode = OPENX_MODE_ACCESS_RDWR | OPENX_MODE_DENY_NONE;
- status = smb_raw_open(cli->tree, mem_ctx, &io);
+ status = smb_raw_open(cli->tree, tctx, &io);
CHECK_STATUS(status, NT_STATUS_SHARING_VIOLATION);
if (timeval_elapsed(&tv) > 3.0) {
printf("(%s) Incorrect timing in openx with timeout - waited %.2f seconds\n",
io.openx.in.write_time = 0;
io.openx.in.size = 0;
io.openx.in.timeout = 0;
- status = smb_raw_open(cli->tree, mem_ctx, &io);
+ status = smb_raw_open(cli->tree, tctx, &io);
CHECK_STATUS(status, NT_STATUS_OK);
smbcli_close(cli->tree, io.openx.out.file.fnum);
/* check the extended return flag */
io.openx.in.flags = OPENX_FLAGS_ADDITIONAL_INFO | OPENX_FLAGS_EXTENDED_RETURN;
io.openx.in.open_func = OPENX_OPEN_FUNC_OPEN;
- status = smb_raw_open(cli->tree, mem_ctx, &io);
+ status = smb_raw_open(cli->tree, tctx, &io);
CHECK_STATUS(status, NT_STATUS_OK);
CHECK_VAL(io.openx.out.access_mask, SEC_STD_ALL);
smbcli_close(cli->tree, io.openx.out.file.fnum);
io.openx.in.fname = "\\A.+,;=[].B";
- status = smb_raw_open(cli->tree, mem_ctx, &io);
+ status = smb_raw_open(cli->tree, tctx, &io);
CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_NOT_FOUND);
/* Check the mapping for open exec. */
/* First create an .exe file. */
smbcli_unlink(cli->tree, fname_exe);
- fnum = create_complex_file(cli, mem_ctx, fname_exe);
+ fnum = create_complex_file(cli, tctx, fname_exe);
smbcli_close(cli->tree, fnum);
io.openx.level = RAW_OPEN_OPENX;
io.openx.in.write_time = 0;
io.openx.in.size = 0;
io.openx.in.timeout = 0;
- status = smb_raw_open(cli->tree, mem_ctx, &io);
+ status = smb_raw_open(cli->tree, tctx, &io);
CHECK_STATUS(status, NT_STATUS_OK);
/* Can we read and write ? */
many thanks to kukks for a sniff showing how this works with os2->w2k
*/
-static bool test_t2open(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
+static bool test_t2open(struct smbcli_state *cli, struct torture_context *tctx)
{
union smb_open io;
union smb_fileinfo finfo;
{ OPENX_OPEN_FUNC_TRUNC | OPENX_OPEN_FUNC_CREATE, false, NT_STATUS_OK },
};
- fnum = create_complex_file(cli, mem_ctx, fname1);
+ fnum = create_complex_file(cli, tctx, fname1);
if (fnum == -1) {
d_printf("Failed to create file %s - %s\n", fname1, smbcli_errstr(cli->tree));
ret = false;
io.t2open.in.timeout = 0;
io.t2open.in.num_eas = 3;
- io.t2open.in.eas = talloc_array(mem_ctx, struct ea_struct, io.t2open.in.num_eas);
+ io.t2open.in.eas = talloc_array(tctx, struct ea_struct, io.t2open.in.num_eas);
io.t2open.in.eas[0].flags = 0;
io.t2open.in.eas[0].name.s = ".CLASSINFO";
- io.t2open.in.eas[0].value = data_blob_talloc(mem_ctx, "first value", 11);
+ io.t2open.in.eas[0].value = data_blob_talloc(tctx, "first value", 11);
io.t2open.in.eas[1].flags = 0;
io.t2open.in.eas[1].name.s = "EA TWO";
- io.t2open.in.eas[1].value = data_blob_talloc(mem_ctx, "foo", 3);
+ io.t2open.in.eas[1].value = data_blob_talloc(tctx, "foo", 3);
io.t2open.in.eas[2].flags = 0;
io.t2open.in.eas[2].name.s = "X THIRD";
- io.t2open.in.eas[2].value = data_blob_talloc(mem_ctx, "xy", 2);
+ io.t2open.in.eas[2].value = data_blob_talloc(tctx, "xy", 2);
/* check all combinations of open_func */
for (i=0; i<ARRAY_SIZE(open_funcs); i++) {
io.t2open.in.fname = fname2;
}
io.t2open.in.open_func = open_funcs[i].open_func;
- status = smb_raw_open(cli->tree, mem_ctx, &io);
+ status = smb_raw_open(cli->tree, tctx, &io);
if ((io.t2open.in.num_eas != 0)
&& NT_STATUS_EQUAL(status, NT_STATUS_EAS_NOT_SUPPORTED)
- && lp_parm_bool(global_loadparm, NULL, "torture", "samba3", false)) {
+ && torture_setting_bool(tctx, "samba3", false)) {
printf("(%s) EAs not supported, not treating as fatal "
"in Samba3 test\n", __location__);
io.t2open.in.num_eas = 0;
io.t2open.in.open_func = OPENX_OPEN_FUNC_OPEN | OPENX_OPEN_FUNC_CREATE;
io.t2open.in.write_time = 0;
io.t2open.in.fname = fname;
- status = smb_raw_open(cli->tree, mem_ctx, &io);
+ status = smb_raw_open(cli->tree, tctx, &io);
CHECK_STATUS(status, NT_STATUS_OK);
fnum = io.t2open.out.file.fnum;
SET_ATTRIB(FILE_ATTRIBUTE_HIDDEN);
CHECK_ALL_INFO(FILE_ATTRIBUTE_HIDDEN, attrib);
- status = smb_raw_open(cli->tree, mem_ctx, &io);
+ status = smb_raw_open(cli->tree, tctx, &io);
CHECK_STATUS(status, NT_STATUS_OK);
smbcli_close(cli->tree, io.t2open.out.file.fnum);
- status = smb_raw_open(cli->tree, mem_ctx, &io);
+ status = smb_raw_open(cli->tree, tctx, &io);
CHECK_STATUS(status, NT_STATUS_OK);
smbcli_close(cli->tree, io.t2open.out.file.fnum);
/* and check attrib on create */
io.t2open.in.open_func = OPENX_OPEN_FUNC_FAIL | OPENX_OPEN_FUNC_CREATE;
io.t2open.in.file_attrs = FILE_ATTRIBUTE_SYSTEM;
- status = smb_raw_open(cli->tree, mem_ctx, &io);
+ status = smb_raw_open(cli->tree, tctx, &io);
CHECK_STATUS(status, NT_STATUS_OK);
/* check timeout on create - win2003 ignores the timeout! */
io.t2open.in.file_attrs = 0;
io.t2open.in.timeout = 20000;
io.t2open.in.open_mode = OPENX_MODE_ACCESS_RDWR | OPENX_MODE_DENY_ALL;
- status = smb_raw_open(cli->tree, mem_ctx, &io);
+ status = smb_raw_open(cli->tree, tctx, &io);
CHECK_STATUS(status, NT_STATUS_SHARING_VIOLATION);
done:
/*
test RAW_OPEN_NTCREATEX
*/
-static bool test_ntcreatex(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
+static bool test_ntcreatex(struct smbcli_state *cli, struct torture_context *tctx)
{
union smb_open io;
union smb_fileinfo finfo;
smbcli_close(cli->tree, fnum);
}
io.ntcreatex.in.open_disposition = open_funcs[i].open_disp;
- status = smb_raw_open(cli->tree, mem_ctx, &io);
+ status = smb_raw_open(cli->tree, tctx, &io);
if (!NT_STATUS_EQUAL(status, open_funcs[i].correct_status)) {
printf("(%s) incorrect status %s should be %s (i=%d with_file=%d open_disp=%d)\n",
__location__, nt_errstr(status), nt_errstr(open_funcs[i].correct_status),
/* basic field testing */
io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
- status = smb_raw_open(cli->tree, mem_ctx, &io);
+ status = smb_raw_open(cli->tree, tctx, &io);
CHECK_STATUS(status, NT_STATUS_OK);
fnum = io.ntcreatex.out.file.fnum;
/* check fields when the file already existed */
smbcli_close(cli->tree, fnum);
smbcli_unlink(cli->tree, fname);
- fnum = create_complex_file(cli, mem_ctx, fname);
+ fnum = create_complex_file(cli, tctx, fname);
if (fnum == -1) {
ret = false;
goto done;
smbcli_close(cli->tree, fnum);
io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
- status = smb_raw_open(cli->tree, mem_ctx, &io);
+ status = smb_raw_open(cli->tree, tctx, &io);
CHECK_STATUS(status, NT_STATUS_OK);
fnum = io.ntcreatex.out.file.fnum;
io.ntcreatex.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE;
- status = smb_raw_open(cli->tree, mem_ctx, &io);
+ status = smb_raw_open(cli->tree, tctx, &io);
CHECK_STATUS(status, NT_STATUS_OK);
fnum = io.ntcreatex.out.file.fnum;
/*
test RAW_OPEN_NTTRANS_CREATE
*/
-static bool test_nttrans_create(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
+static bool test_nttrans_create(struct smbcli_state *cli, struct torture_context *tctx)
{
union smb_open io;
union smb_fileinfo finfo;
int fnum = -1;
bool ret = true;
int i;
+ uint32_t ok_mask, not_supported_mask, invalid_parameter_mask;
+ uint32_t not_a_directory_mask, unexpected_mask;
struct {
uint32_t open_disp;
bool with_file;
smbcli_close(cli->tree, fnum);
}
io.ntcreatex.in.open_disposition = open_funcs[i].open_disp;
- status = smb_raw_open(cli->tree, mem_ctx, &io);
+ status = smb_raw_open(cli->tree, tctx, &io);
if (!NT_STATUS_EQUAL(status, open_funcs[i].correct_status)) {
printf("(%s) incorrect status %s should be %s (i=%d with_file=%d open_disp=%d)\n",
__location__, nt_errstr(status), nt_errstr(open_funcs[i].correct_status),
/* basic field testing */
io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
- status = smb_raw_open(cli->tree, mem_ctx, &io);
+ status = smb_raw_open(cli->tree, tctx, &io);
CHECK_STATUS(status, NT_STATUS_OK);
fnum = io.ntcreatex.out.file.fnum;
/* check fields when the file already existed */
smbcli_close(cli->tree, fnum);
smbcli_unlink(cli->tree, fname);
- fnum = create_complex_file(cli, mem_ctx, fname);
+ fnum = create_complex_file(cli, tctx, fname);
if (fnum == -1) {
ret = false;
goto done;
smbcli_close(cli->tree, fnum);
io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
- status = smb_raw_open(cli->tree, mem_ctx, &io);
+ status = smb_raw_open(cli->tree, tctx, &io);
CHECK_STATUS(status, NT_STATUS_OK);
fnum = io.ntcreatex.out.file.fnum;
CHECK_ALL_INFO(io.ntcreatex.out.is_directory, directory);
CHECK_VAL(io.ntcreatex.out.file_type, FILE_TYPE_DISK);
smbcli_close(cli->tree, fnum);
+
+ /* check no-recall - don't pull a file from tape on a HSM */
+ io.ntcreatex.in.create_options = NTCREATEX_OPTIONS_NO_RECALL;
+ status = smb_raw_open(cli->tree, tctx, &io);
+ CHECK_STATUS(status, NT_STATUS_OK);
+ fnum = io.ntcreatex.out.file.fnum;
+
+ CHECK_VAL(io.ntcreatex.out.oplock_level, 0);
+ CHECK_VAL(io.ntcreatex.out.create_action, NTCREATEX_ACTION_EXISTED);
+ CHECK_NTTIME(io.ntcreatex.out.create_time, create_time);
+ CHECK_NTTIME(io.ntcreatex.out.access_time, access_time);
+ CHECK_NTTIME(io.ntcreatex.out.write_time, write_time);
+ CHECK_NTTIME(io.ntcreatex.out.change_time, change_time);
+ CHECK_ALL_INFO(io.ntcreatex.out.attrib, attrib);
+ CHECK_ALL_INFO(io.ntcreatex.out.alloc_size, alloc_size);
+ CHECK_ALL_INFO(io.ntcreatex.out.size, size);
+ CHECK_ALL_INFO(io.ntcreatex.out.is_directory, directory);
+ CHECK_VAL(io.ntcreatex.out.file_type, FILE_TYPE_DISK);
+ smbcli_close(cli->tree, fnum);
+
+ /* Check some create options (these all should be ignored) */
+ for (i=0; i < 32; i++) {
+ uint32_t create_option = (1 << i) & NTCREATEX_OPTIONS_MUST_IGNORE_MASK;
+ if (create_option == 0) {
+ continue;
+ }
+ io.ntcreatex.in.create_options = create_option;
+ status = smb_raw_open(cli->tree, tctx, &io);
+ if (!NT_STATUS_IS_OK(status)) {
+ printf("ntcreatex create option 0x%08x gave %s - should give NT_STATUS_OK\n",
+ create_option, nt_errstr(status));
+ }
+ CHECK_STATUS(status, NT_STATUS_OK);
+ fnum = io.ntcreatex.out.file.fnum;
+
+ CHECK_VAL(io.ntcreatex.out.oplock_level, 0);
+ CHECK_VAL(io.ntcreatex.out.create_action, NTCREATEX_ACTION_EXISTED);
+ CHECK_NTTIME(io.ntcreatex.out.create_time, create_time);
+ CHECK_NTTIME(io.ntcreatex.out.access_time, access_time);
+ CHECK_NTTIME(io.ntcreatex.out.write_time, write_time);
+ CHECK_NTTIME(io.ntcreatex.out.change_time, change_time);
+ CHECK_ALL_INFO(io.ntcreatex.out.attrib, attrib);
+ CHECK_ALL_INFO(io.ntcreatex.out.alloc_size, alloc_size);
+ CHECK_ALL_INFO(io.ntcreatex.out.size, size);
+ CHECK_ALL_INFO(io.ntcreatex.out.is_directory, directory);
+ CHECK_VAL(io.ntcreatex.out.file_type, FILE_TYPE_DISK);
+ smbcli_close(cli->tree, fnum);
+ }
+
+ io.ntcreatex.in.file_attr = 0;
+ io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
+ io.ntcreatex.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
+
+ /* Check for options that should return NOT_SUPPORTED, OK or INVALID_PARAMETER */
+ ok_mask = 0;
+ not_supported_mask = 0;
+ invalid_parameter_mask = 0;
+ not_a_directory_mask = 0;
+ unexpected_mask = 0;
+ for (i=0; i < 32; i++) {
+ uint32_t create_option = 1<<i;
+ if (create_option & NTCREATEX_OPTIONS_DELETE_ON_CLOSE) {
+ continue;
+ }
+ io.ntcreatex.in.create_options = create_option;
+ status = smb_raw_open(cli->tree, tctx, &io);
+ if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_SUPPORTED)) {
+ not_supported_mask |= create_option;
+ } else if (NT_STATUS_EQUAL(status, NT_STATUS_OK)) {
+ ok_mask |= create_option;
+ smbcli_close(cli->tree, io.ntcreatex.out.file.fnum);
+ } else if (NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
+ invalid_parameter_mask |= create_option;
+ } else if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_A_DIRECTORY)) {
+ not_a_directory_mask |= 1<<i;
+ } else {
+ unexpected_mask |= 1<<i;
+ printf("create option 0x%08x returned %s\n", create_option, nt_errstr(status));
+ }
+ }
+
+ CHECK_VAL(ok_mask, 0x00efcfce);
+ CHECK_VAL(not_a_directory_mask, 0x00000001);
+ CHECK_VAL(not_supported_mask, 0x00002000);
+ CHECK_VAL(invalid_parameter_mask, 0xff100030);
+ CHECK_VAL(unexpected_mask, 0x00000000);
+
smbcli_unlink(cli->tree, fname);
io.ntcreatex.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE;
- status = smb_raw_open(cli->tree, mem_ctx, &io);
+ status = smb_raw_open(cli->tree, tctx, &io);
CHECK_STATUS(status, NT_STATUS_OK);
fnum = io.ntcreatex.out.file.fnum;
open_disposition==NTCREATEX_DISP_OVERWRITE_IF. Windows 2003 allows the
second open.
*/
-static bool test_ntcreatex_brlocked(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
+static bool test_ntcreatex_brlocked(struct smbcli_state *cli, struct torture_context *tctx)
{
union smb_open io, io1;
union smb_lock io2;
NTCREATEX_SECURITY_ALL;
io.ntcreatex.in.fname = fname;
- status = smb_raw_open(cli->tree, mem_ctx, &io);
+ status = smb_raw_open(cli->tree, tctx, &io);
CHECK_STATUS(status, NT_STATUS_OK);
io2.lockx.level = RAW_LOCK_LOCKX;
NTCREATEX_SECURITY_ALL;
io1.ntcreatex.in.fname = fname;
- status = smb_raw_open(cli->tree, mem_ctx, &io1);
+ status = smb_raw_open(cli->tree, tctx, &io1);
CHECK_STATUS(status, NT_STATUS_OK);
done:
/*
test RAW_OPEN_MKNEW
*/
-static bool test_mknew(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
+static bool test_mknew(struct smbcli_state *cli, struct torture_context *tctx)
{
union smb_open io;
const char *fname = BASEDIR "\\torture_mknew.txt";
io.mknew.in.attrib = 0;
io.mknew.in.write_time = 0;
io.mknew.in.fname = fname;
- status = smb_raw_open(cli->tree, mem_ctx, &io);
+ status = smb_raw_open(cli->tree, tctx, &io);
CHECK_STATUS(status, NT_STATUS_OK);
fnum = io.mknew.out.file.fnum;
- status = smb_raw_open(cli->tree, mem_ctx, &io);
+ status = smb_raw_open(cli->tree, tctx, &io);
CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_COLLISION);
smbcli_close(cli->tree, fnum);
/* make sure write_time works */
io.mknew.in.write_time = basetime;
- status = smb_raw_open(cli->tree, mem_ctx, &io);
+ status = smb_raw_open(cli->tree, tctx, &io);
CHECK_STATUS(status, NT_STATUS_OK);
fnum = io.mknew.out.file.fnum;
CHECK_TIME(basetime, write_time);
/* make sure file_attrs works */
io.mknew.in.attrib = FILE_ATTRIBUTE_HIDDEN;
- status = smb_raw_open(cli->tree, mem_ctx, &io);
+ status = smb_raw_open(cli->tree, tctx, &io);
CHECK_STATUS(status, NT_STATUS_OK);
fnum = io.mknew.out.file.fnum;
CHECK_ALL_INFO(FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_ARCHIVE,
/*
test RAW_OPEN_CREATE
*/
-static bool test_create(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
+static bool test_create(struct smbcli_state *cli, struct torture_context *tctx)
{
union smb_open io;
const char *fname = BASEDIR "\\torture_create.txt";
io.create.in.attrib = 0;
io.create.in.write_time = 0;
io.create.in.fname = fname;
- status = smb_raw_open(cli->tree, mem_ctx, &io);
+ status = smb_raw_open(cli->tree, tctx, &io);
CHECK_STATUS(status, NT_STATUS_OK);
fnum = io.create.out.file.fnum;
- status = smb_raw_open(cli->tree, mem_ctx, &io);
+ status = smb_raw_open(cli->tree, tctx, &io);
CHECK_STATUS(status, NT_STATUS_OK);
smbcli_close(cli->tree, io.create.out.file.fnum);
/* make sure write_time works */
io.create.in.write_time = basetime;
- status = smb_raw_open(cli->tree, mem_ctx, &io);
+ status = smb_raw_open(cli->tree, tctx, &io);
CHECK_STATUS(status, NT_STATUS_OK);
fnum = io.create.out.file.fnum;
CHECK_TIME(basetime, write_time);
/* make sure file_attrs works */
io.create.in.attrib = FILE_ATTRIBUTE_HIDDEN;
- status = smb_raw_open(cli->tree, mem_ctx, &io);
+ status = smb_raw_open(cli->tree, tctx, &io);
CHECK_STATUS(status, NT_STATUS_OK);
fnum = io.create.out.file.fnum;
CHECK_ALL_INFO(FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_ARCHIVE,
/*
test RAW_OPEN_CTEMP
*/
-static bool test_ctemp(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
+static bool test_ctemp(struct smbcli_state *cli, TALLOC_CTX *tctx)
{
union smb_open io;
NTSTATUS status;
io.ctemp.in.attrib = FILE_ATTRIBUTE_HIDDEN;
io.ctemp.in.write_time = basetime;
io.ctemp.in.directory = BASEDIR;
- status = smb_raw_open(cli->tree, mem_ctx, &io);
+ status = smb_raw_open(cli->tree, tctx, &io);
CHECK_STATUS(status, NT_STATUS_OK);
fnum = io.ctemp.out.file.fnum;
finfo.generic.level = RAW_FILEINFO_NAME_INFO;
finfo.generic.in.file.fnum = fnum;
- status = smb_raw_fileinfo(cli->tree, mem_ctx, &finfo);
+ status = smb_raw_fileinfo(cli->tree, tctx, &finfo);
CHECK_STATUS(status, NT_STATUS_OK);
fname = finfo.name_info.out.fname.s;
/*
test chained RAW_OPEN_OPENX_READX
*/
-static bool test_chained(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
+static bool test_chained(struct smbcli_state *cli, TALLOC_CTX *tctx)
{
union smb_open io;
const char *fname = BASEDIR "\\torture_chained.txt";
printf("Checking RAW_OPEN_OPENX chained with READX\n");
smbcli_unlink(cli->tree, fname);
- fnum = create_complex_file(cli, mem_ctx, fname);
+ fnum = create_complex_file(cli, tctx, fname);
smbcli_write(cli->tree, fnum, 0, buf, 0, sizeof(buf));
io.openxreadx.in.remaining = 0;
io.openxreadx.out.data = (uint8_t *)buf2;
- status = smb_raw_open(cli->tree, mem_ctx, &io);
+ status = smb_raw_open(cli->tree, tctx, &io);
CHECK_STATUS(status, NT_STATUS_OK);
fnum = io.openxreadx.out.file.fnum;
NetApp filers are known to fail on this.
*/
-static bool test_no_leading_slash(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
+static bool test_no_leading_slash(struct smbcli_state *cli, TALLOC_CTX *tctx)
{
union smb_open io;
const char *fname = BASEDIR "\\torture_no_leading_slash.txt";
smbcli_unlink(cli->tree, fname);
/* Create the file */
- fnum = create_complex_file(cli, mem_ctx, fname);
+ fnum = create_complex_file(cli, tctx, fname);
smbcli_write(cli->tree, fnum, 0, buf, 0, sizeof(buf));
smbcli_close(cli->tree, fnum);
io.openx.in.size = 1024*1024;
io.openx.in.timeout = 0;
- status = smb_raw_open(cli->tree, mem_ctx, &io);
+ status = smb_raw_open(cli->tree, tctx, &io);
CHECK_STATUS(status, NT_STATUS_OK);
fnum = io.openx.out.file.fnum;
return ret;
}
+/*
+ test RAW_OPEN_OPENX against an existing directory to
+ ensure it returns NT_STATUS_FILE_IS_A_DIRECTORY.
+ Samba 3.2.0 - 3.2.6 are known to fail this.
+
+*/
+static bool test_openx_over_dir(struct smbcli_state *cli, TALLOC_CTX *tctx)
+{
+ union smb_open io;
+ const char *fname = BASEDIR "\\openx_over_dir";
+ NTSTATUS status;
+ int d_fnum = -1;
+ int fnum = -1;
+ bool ret = true;
+
+ printf("Checking RAW_OPEN_OPENX over an existing directory\n");
+ smbcli_unlink(cli->tree, fname);
+
+ /* Create the Directory */
+ status = create_directory_handle(cli->tree, fname, &d_fnum);
+ smbcli_close(cli->tree, d_fnum);
+
+ /* Prepare to open the file over the directory. */
+ io.openx.level = RAW_OPEN_OPENX;
+ io.openx.in.fname = fname;
+ io.openx.in.flags = OPENX_FLAGS_ADDITIONAL_INFO;
+ io.openx.in.open_mode = OPENX_MODE_ACCESS_RDWR;
+ io.openx.in.open_func = OPENX_OPEN_FUNC_OPEN;
+ io.openx.in.search_attrs = 0;
+ io.openx.in.file_attrs = 0;
+ io.openx.in.write_time = 0;
+ io.openx.in.size = 1024*1024;
+ io.openx.in.timeout = 0;
+
+ status = smb_raw_open(cli->tree, tctx, &io);
+ CHECK_STATUS(status, NT_STATUS_FILE_IS_A_DIRECTORY);
+ fnum = io.openx.out.file.fnum;
+
+done:
+ smbcli_close(cli->tree, fnum);
+ smbcli_unlink(cli->tree, fname);
+
+ return ret;
+}
+
+
/* A little torture test to expose a race condition in Samba 3.0.20 ... :-) */
-static bool test_raw_open_multi(void)
+static bool test_raw_open_multi(struct torture_context *tctx)
{
struct smbcli_state *cli;
TALLOC_CTX *mem_ctx = talloc_init("torture_test_oplock_multi");
struct smbcli_state **clients;
struct smbcli_request **requests;
union smb_open *ios;
- const char *host = lp_parm_string(global_loadparm, NULL, "torture", "host");
- const char *share = lp_parm_string(global_loadparm, NULL, "torture", "share");
+ const char *host = torture_setting_string(tctx, "host", NULL);
+ const char *share = torture_setting_string(tctx, "share", NULL);
int i, num_files = 3;
- struct event_context *ev;
int num_ok = 0;
int num_collision = 0;
- ev = cli_credentials_get_event_context(cmdline_credentials);
clients = talloc_array(mem_ctx, struct smbcli_state *, num_files);
requests = talloc_array(mem_ctx, struct smbcli_request *, num_files);
ios = talloc_array(mem_ctx, union smb_open, num_files);
- if ((ev == NULL) || (clients == NULL) || (requests == NULL) ||
+ if ((tctx->ev == NULL) || (clients == NULL) || (requests == NULL) ||
(ios == NULL)) {
DEBUG(0, ("talloc failed\n"));
return false;
}
- if (!torture_open_connection_share(mem_ctx, &cli, host, share, ev)) {
+ if (!torture_open_connection_share(mem_ctx, &cli, tctx, host, share, tctx->ev)) {
return false;
}
- cli->tree->session->transport->options.request_timeout = 60000;
+ cli->tree->session->transport->options.request_timeout = 60;
for (i=0; i<num_files; i++) {
if (!torture_open_connection_share(mem_ctx, &(clients[i]),
- host, share, ev)) {
+ tctx, host, share, tctx->ev)) {
DEBUG(0, ("Could not open %d'th connection\n", i));
return false;
}
- clients[i]->tree->session->transport->
- options.request_timeout = 60000;
+ clients[i]->tree->session->transport->options.request_timeout = 60;
}
/* cleanup */
break;
}
- if (event_loop_once(ev) != 0) {
+ if (event_loop_once(tctx->ev) != 0) {
DEBUG(0, ("event_loop_once failed\n"));
return false;
}
return ret;
}
+/*
+ test opening for delete on a read-only attribute file.
+*/
+static bool test_open_for_delete(struct smbcli_state *cli, struct torture_context *tctx)
+{
+ union smb_open io;
+ union smb_fileinfo finfo;
+ const char *fname = BASEDIR "\\torture_open_for_delete.txt";
+ NTSTATUS status;
+ int fnum = -1;
+ bool ret = true;
+
+ printf("Checking RAW_NTCREATEX for delete on a readonly file.\n");
+
+ /* reasonable default parameters */
+ io.generic.level = RAW_OPEN_NTCREATEX;
+ io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED;
+ io.ntcreatex.in.root_fid = 0;
+ io.ntcreatex.in.alloc_size = 0;
+ io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
+ io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_READONLY;
+ io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
+ io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
+ io.ntcreatex.in.create_options = 0;
+ io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
+ io.ntcreatex.in.security_flags = 0;
+ io.ntcreatex.in.fname = fname;
+
+ /* Create the readonly file. */
+
+ status = smb_raw_open(cli->tree, tctx, &io);
+ CHECK_STATUS(status, NT_STATUS_OK);
+ fnum = io.ntcreatex.out.file.fnum;
+
+ CHECK_VAL(io.ntcreatex.out.oplock_level, 0);
+ io.ntcreatex.in.create_options = 0;
+ CHECK_VAL(io.ntcreatex.out.create_action, NTCREATEX_ACTION_CREATED);
+ CHECK_ALL_INFO(io.ntcreatex.out.attrib, attrib);
+ smbcli_close(cli->tree, fnum);
+
+ /* Now try and open for delete only - should succeed. */
+ io.ntcreatex.in.access_mask = SEC_STD_DELETE;
+ io.ntcreatex.in.file_attr = 0;
+ io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE | NTCREATEX_SHARE_ACCESS_DELETE;
+ io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
+ status = smb_raw_open(cli->tree, tctx, &io);
+ CHECK_STATUS(status, NT_STATUS_OK);
+
+ smbcli_unlink(cli->tree, fname);
+
+done:
+ smbcli_close(cli->tree, fnum);
+ smbcli_unlink(cli->tree, fname);
+
+ return ret;
+}
+
+
/* basic testing of all RAW_OPEN_* calls
*/
bool torture_raw_open(struct torture_context *torture, struct smbcli_state *cli)
ret &= test_ntcreatex_brlocked(cli, torture);
ret &= test_open(cli, torture);
- ret &= test_raw_open_multi();
+ ret &= test_raw_open_multi(torture);
ret &= test_openx(cli, torture);
ret &= test_ntcreatex(cli, torture);
ret &= test_nttrans_create(cli, torture);
ret &= test_ctemp(cli, torture);
ret &= test_chained(cli, torture);
ret &= test_no_leading_slash(cli, torture);
+ ret &= test_openx_over_dir(cli, torture);
+ ret &= test_open_for_delete(cli, torture);
smb_raw_exit(cli->session);
smbcli_deltree(cli->tree, BASEDIR);