1
0
mirror of https://github.com/samba-team/samba.git synced 2024-12-24 21:34:56 +03:00

Merge branch 'v4-0-test' of ssh://git.samba.org/data/git/samba into v4-0-test

(This used to be commit ece878c1f9)
This commit is contained in:
Jelmer Vernooij 2008-04-17 13:05:25 +02:00
commit dd0da89e84
17 changed files with 389 additions and 51 deletions

View File

@ -48,7 +48,8 @@ static double timeval_elapsed(struct timeval *tv)
}
#define torture_assert_str_equal(test, arg1, arg2, desc) \
if (strcmp(arg1, arg2)) { \
if (arg1 == NULL && arg2 == NULL) { \
} else if (strcmp(arg1, arg2)) { \
printf("failure: %s [\n%s: Expected %s, got %s: %s\n]\n", \
test, __location__, arg1, arg2, desc); \
return false; \

View File

@ -1587,6 +1587,14 @@ union smb_open {
/* optional list of extended attributes */
struct smb_ea_list eas;
struct smb2_create_blobs {
uint32_t num_blobs;
struct smb2_create_blob {
const char *tag;
DATA_BLOB data;
} *blobs;
} blobs;
} in;
struct {
union smb_handle file;

View File

@ -121,7 +121,7 @@ static void continue_socket(struct composite_context *creq)
struct smbcli_socket *sock;
struct smb2_transport *transport;
struct smb2_request *req;
uint16_t dialects[1];
uint16_t dialects[2];
c->status = smbcli_sock_connect_recv(creq, state, &sock);
if (!composite_is_ok(c)) return;
@ -130,11 +130,12 @@ static void continue_socket(struct composite_context *creq)
if (composite_nomem(transport, c)) return;
ZERO_STRUCT(state->negprot);
state->negprot.in.dialect_count = 1;
state->negprot.in.dialect_count = 2;
state->negprot.in.security_mode = 0;
state->negprot.in.capabilities = 0;
unix_to_nt_time(&state->negprot.in.start_time, time(NULL));
dialects[0] = SMB2_DIALECT_REVISION;
dialects[0] = 0;
dialects[1] = SMB2_DIALECT_REVISION;
state->negprot.in.dialects = dialects;
req = smb2_negprot_send(transport, &state->negprot);

View File

@ -28,30 +28,59 @@
/*
add a blob to a smb2_create attribute blob
*/
NTSTATUS smb2_create_blob_add(TALLOC_CTX *mem_ctx, DATA_BLOB *blob,
const char *tag,
DATA_BLOB add, bool last)
static NTSTATUS smb2_create_blob_push_one(TALLOC_CTX *mem_ctx, DATA_BLOB *buffer,
const struct smb2_create_blob *blob,
bool last)
{
uint32_t ofs = blob->length;
size_t tag_length = strlen(tag);
uint8_t pad = smb2_padding_size(add.length+tag_length, 8);
if (!data_blob_realloc(mem_ctx, blob,
blob->length + 0x14 + tag_length + add.length + pad))
uint32_t ofs = buffer->length;
size_t tag_length = strlen(blob->tag);
uint8_t pad = smb2_padding_size(blob->data.length+tag_length, 4);
if (!data_blob_realloc(mem_ctx, buffer,
buffer->length + 0x14 + tag_length + blob->data.length + pad))
return NT_STATUS_NO_MEMORY;
if (last) {
SIVAL(blob->data, ofs+0x00, 0);
SIVAL(buffer->data, ofs+0x00, 0);
} else {
SIVAL(blob->data, ofs+0x00, 0x14 + tag_length + add.length + pad);
SIVAL(buffer->data, ofs+0x00, 0x14 + tag_length + blob->data.length + pad);
}
SSVAL(blob->data, ofs+0x04, 0x10); /* offset of tag */
SIVAL(blob->data, ofs+0x06, tag_length); /* tag length */
SSVAL(blob->data, ofs+0x0A, 0x14 + tag_length); /* offset of data */
SIVAL(blob->data, ofs+0x0C, add.length);
memcpy(blob->data+ofs+0x10, tag, tag_length);
SIVAL(blob->data, ofs+0x10+tag_length, 0); /* pad? */
memcpy(blob->data+ofs+0x14+tag_length, add.data, add.length);
memset(blob->data+ofs+0x14+tag_length+add.length, 0, pad);
SSVAL(buffer->data, ofs+0x04, 0x10); /* offset of tag */
SIVAL(buffer->data, ofs+0x06, tag_length); /* tag length */
SSVAL(buffer->data, ofs+0x0A, 0x14 + tag_length); /* offset of data */
SIVAL(buffer->data, ofs+0x0C, blob->data.length);
memcpy(buffer->data+ofs+0x10, blob->tag, tag_length);
SIVAL(buffer->data, ofs+0x10+tag_length, 0); /* pad? */
memcpy(buffer->data+ofs+0x14+tag_length, blob->data.data, blob->data.length);
memset(buffer->data+ofs+0x14+tag_length+blob->data.length, 0, pad);
return NT_STATUS_OK;
}
NTSTATUS smb2_create_blob_add(TALLOC_CTX *mem_ctx, struct smb2_create_blobs *b,
const char *tag, DATA_BLOB data)
{
struct smb2_create_blob *array;
array = talloc_realloc(mem_ctx, b->blobs,
struct smb2_create_blob,
b->num_blobs + 1);
NT_STATUS_HAVE_NO_MEMORY(array);
b->blobs = array;
b->blobs[b->num_blobs].tag = talloc_strdup(b->blobs, tag);
NT_STATUS_HAVE_NO_MEMORY(b->blobs[b->num_blobs].tag);
if (data.data) {
b->blobs[b->num_blobs].data = data_blob_talloc(b->blobs,
data.data,
data.length);
NT_STATUS_HAVE_NO_MEMORY(b->blobs[b->num_blobs].data.data);
} else {
b->blobs[b->num_blobs].data = data_blob(NULL, 0);
}
b->num_blobs += 1;
return NT_STATUS_OK;
}
@ -64,6 +93,7 @@ struct smb2_request *smb2_create_send(struct smb2_tree *tree, struct smb2_create
struct smb2_request *req;
NTSTATUS status;
DATA_BLOB blob = data_blob(NULL, 0);
uint32_t i;
req = smb2_request_init_tree(tree, SMB2_OP_CREATE, 0x38, true, 0);
if (req == NULL) return NULL;
@ -89,7 +119,8 @@ struct smb2_request *smb2_create_send(struct smb2_tree *tree, struct smb2_create
DATA_BLOB b = data_blob_talloc(req, NULL,
ea_list_size_chained(io->in.eas.num_eas, io->in.eas.eas));
ea_put_list_chained(b.data, io->in.eas.num_eas, io->in.eas.eas);
status = smb2_create_blob_add(req, &blob, SMB2_CREATE_TAG_EXTA, b, false);
status = smb2_create_blob_add(req, &io->in.blobs,
SMB2_CREATE_TAG_EXTA, b);
if (!NT_STATUS_IS_OK(status)) {
talloc_free(req);
return NULL;
@ -99,13 +130,30 @@ struct smb2_request *smb2_create_send(struct smb2_tree *tree, struct smb2_create
/* an empty MxAc tag seems to be used to ask the server to
return the maximum access mask allowed on the file */
status = smb2_create_blob_add(req, &blob, SMB2_CREATE_TAG_MXAC,
data_blob(NULL, 0), true);
status = smb2_create_blob_add(req, &io->in.blobs,
SMB2_CREATE_TAG_MXAC, data_blob(NULL, 0));
if (!NT_STATUS_IS_OK(status)) {
talloc_free(req);
return NULL;
}
for (i=0; i < io->in.blobs.num_blobs; i++) {
bool last = false;
const struct smb2_create_blob *c;
if ((i + 1) == io->in.blobs.num_blobs) {
last = true;
}
c = &io->in.blobs.blobs[i];
status = smb2_create_blob_push_one(req, &blob,
c, last);
if (!NT_STATUS_IS_OK(status)) {
talloc_free(req);
return NULL;
}
}
status = smb2_push_o32s32_blob(&req->out, 0x30, blob);
if (!NT_STATUS_IS_OK(status)) {
talloc_free(req);

View File

@ -208,7 +208,21 @@ static NTSTATUS ntvfs_map_open_finish(struct ntvfs_module_context *ntvfs,
case RAW_OPEN_SMB2:
io->smb2.out.file.ntvfs = io2->generic.out.file.ntvfs;
io->smb2.out.oplock_level = 0;
switch (io2->generic.out.oplock_level) {
case OPLOCK_BATCH:
io->smb2.out.oplock_level = SMB2_OPLOCK_LEVEL_BATCH;
break;
case OPLOCK_EXCLUSIVE:
io->smb2.out.oplock_level = SMB2_OPLOCK_LEVEL_EXCLUSIVE;
break;
case OPLOCK_LEVEL_II:
io->smb2.out.oplock_level = SMB2_OPLOCK_LEVEL_II;
break;
default:
io->smb2.out.oplock_level = SMB2_OPLOCK_LEVEL_NONE;
break;
}
io->smb2.out.reserved = 0;
io->smb2.out.create_action = io2->generic.out.create_action;
io->smb2.out.create_time = io2->generic.out.create_time;
io->smb2.out.access_time = io2->generic.out.access_time;
@ -484,7 +498,18 @@ NTSTATUS ntvfs_map_open(struct ntvfs_module_context *ntvfs,
status = ntvfs->ops->open(ntvfs, req, io2);
break;
case RAW_OPEN_SMB2:
io2->generic.in.flags = 0;
switch (io->smb2.in.oplock_level) {
case SMB2_OPLOCK_LEVEL_BATCH:
io2->generic.in.flags = NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK |
NTCREATEX_FLAGS_REQUEST_OPLOCK;
break;
case SMB2_OPLOCK_LEVEL_EXCLUSIVE:
io2->generic.in.flags = NTCREATEX_FLAGS_REQUEST_OPLOCK;
break;
default:
io2->generic.in.flags = 0;
break;
}
io2->generic.in.root_fid = 0;
io2->generic.in.access_mask = io->smb2.in.desired_access;
io2->generic.in.alloc_size = 0;

View File

@ -135,7 +135,7 @@ static NTSTATUS pvfs_default_acl(struct pvfs_state *pvfs,
}
sd = *psd;
ids = talloc_array(sd, struct id_mapping, 2);
ids = talloc_zero_array(sd, struct id_mapping, 2);
NT_STATUS_HAVE_NO_MEMORY(ids);
ids[0].unixid = talloc(ids, struct unixid);

View File

@ -33,3 +33,11 @@ rpc.netlogon.*.GetTrustPasswords
base.charset.*.Testing partial surrogate
.*net.api.delshare.* # DelShare isn't implemented yet
rap.*netservergetinfo
smb2.persistent.handles1
samba4.winbind.struct.*.LIST_GROUPS # Not yet working in winbind
samba4.winbind.struct.*.SHOW_SEQUENCE # Not yet working in winbind
samba4.winbind.struct.*.GETPWENT # Not yet working in winbind
samba4.winbind.struct.*.SETPWENT # Not yet working in winbind
samba4.winbind.struct.*.LOOKUP_NAME_SID # Not yet working in winbind

View File

@ -5,11 +5,11 @@ base.casetable
base.nttrans
.*base.bench.holdcon.* # Very slow
base.scan.maxfid
raw.hold.oplock
raw.ping.pong
raw.hold.oplock # Not a test, but a way to block other clients for a test
raw.ping.pong # Needs second server to test
rpc.samr_accessmask
raw.scan.eamax
raw.qfileinfo.ipc
samba4.ntvfs.cifs.raw.qfileinfo.ipc
base.utable
base.smb
smb2.notify
@ -41,7 +41,6 @@ rpc.frsapi # Not provided by Samba 4
.*samba3.* # Samba3-specific test
^samba4.net.domopen.*$ # Hangs for some reason
^samba4.net.api.become.dc.*$ # Fails
winbind # FIXME: This should not be skipped
nss.test # Fails
samba4.samba3sam.python # Conversion from EJS not yet finished
samba4.samdb.python # Not finished yet

View File

@ -27,8 +27,8 @@ class UnixinfoTests(RpcInterfaceTestCase):
def test_getpwuid(self):
infos = self.conn.GetPWUid(range(512))
self.assertEquals(512, len(infos))
self.assertEquals("", infos[0].shell)
self.assertEquals("", infos[0].homedir)
self.assertEquals("/bin/false", infos[0].shell)
self.assertTrue(isinstance(infos[0].homedir, unicode))
def test_gidtosid(self):
self.conn.GidToSid(1000)

View File

@ -219,13 +219,16 @@ plantest "rpc.echo on ncacn_np over smb2" dc $smb4torture ncacn_np:"\$SERVER[smb
# Tests against the NTVFS POSIX backend
NTVFSARGS="--option=torture:sharedelay=100000 --option=torture:oplocktimeout=3"
smb2=`$smb4torture --list | grep "^SMB2-" | xargs`
raw=`$smb4torture --list | grep "^RAW-" | xargs`
#The QFILEINFO-IPC test needs to be on ipc$
raw=`$smb4torture --list | grep "^RAW-" | grep -v "RAW-QFILEINFO-IPC"| xargs`
base=`$smb4torture --list | grep "^BASE-" | xargs`
for t in $base $raw $smb2; do
plansmbtorturetest "$t" dc $ADDARGS //\$SERVER/tmp -U"\$USERNAME"%"\$PASSWORD" $NTVFSARGS
done
plansmbtorturetest "RAW-QFILEINFO-IPC" dc $ADDARGS //\$SERVER/ipc$ -U"\$USERNAME"%"\$PASSWORD"
rap=`$smb4torture --list | grep "^RAP-" | xargs`
for t in $rap; do
plansmbtorturetest "$t" dc $ADDARGS //\$SERVER/IPC\\\$ -U"\$USERNAME"%"\$PASSWORD"

View File

@ -35,6 +35,8 @@ from samba.provision import (provision,
FILL_FULL, FILL_NT4SYNC,
FILL_DRS)
# how do we make this case insensitive??
parser = optparse.OptionParser("provision [options]")
sambaopts = options.SambaOptions(parser)
parser.add_option_group(sambaopts)

View File

@ -79,6 +79,7 @@ void smb2srv_create_recv(struct smb2srv_request *req)
SMB2SRV_CHECK(smb2_pull_o32s32_blob(&req->in, io, req->in.body+0x30, &blob));
/* TODO: parse the blob */
ZERO_STRUCT(io->smb2.in.eas);
ZERO_STRUCT(io->smb2.in.blobs);
/* the VFS backend does not yet handle NULL filenames */
if (io->smb2.in.fname == NULL) {

View File

@ -114,9 +114,12 @@ static NTSTATUS smb2srv_negprot_backend(struct smb2srv_request *req, struct smb2
io->out.security_mode = 0; /* no signing yet */
io->out.dialect_revision = SMB2_DIALECT_REVISION;
io->out.capabilities = 0;
io->out.max_transact_size = 0x10000;
io->out.max_read_size = 0x10000;
io->out.max_write_size = 0x10000;
io->out.max_transact_size = lp_parm_ulong(req->smb_conn->lp_ctx, NULL,
"smb2", "max transaction size", 0x10000);
io->out.max_read_size = lp_parm_ulong(req->smb_conn->lp_ctx, NULL,
"smb2", "max read size", 0x10000);
io->out.max_write_size = lp_parm_ulong(req->smb_conn->lp_ctx, NULL,
"smb2", "max write size", 0x10000);
io->out.system_time = timeval_to_nttime(&current_time);
io->out.server_start_time = timeval_to_nttime(&boot_time);
io->out.reserved2 = 0;

View File

@ -36,18 +36,18 @@
/* global options */
static struct gentest_options {
bool showall;
bool analyze;
bool analyze_always;
bool analyze_continuous;
int showall;
int analyze;
int analyze_always;
int analyze_continuous;
uint_t max_open_handles;
uint_t seed;
uint_t numops;
bool use_oplocks;
int use_oplocks;
char **ignore_patterns;
const char *seeds_file;
bool use_preset_seeds;
bool fast_reconnect;
int use_preset_seeds;
int fast_reconnect;
} options;
/* mapping between open handles on the server and local handles */

View File

@ -20,5 +20,6 @@ TORTURE_SMB2_OBJ_FILES = $(addprefix torture/smb2/, \
find.o \
lock.o \
notify.o \
smb2.o)
smb2.o \
persistent_handles.o)

View File

@ -0,0 +1,182 @@
/*
Unix SMB/CIFS implementation.
test suite for SMB2 persistent file handles
Copyright (C) Stefan Metzmacher 2008
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 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
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, see <http://www.gnu.org/licenses/>.
*/
#include "includes.h"
#include "librpc/gen_ndr/security.h"
#include "libcli/smb2/smb2.h"
#include "libcli/smb2/smb2_calls.h"
#include "torture/torture.h"
#include "torture/smb2/proto.h"
#include "param/param.h"
#define CHECK_VAL(v, correct) do { \
if ((v) != (correct)) { \
torture_result(tctx, TORTURE_FAIL, "(%s): wrong value for %s got 0x%x - should be 0x%x\n", \
__location__, #v, (int)v, (int)correct); \
ret = false; \
}} while (0)
#define CHECK_STATUS(status, correct) do { \
if (!NT_STATUS_EQUAL(status, correct)) { \
torture_result(tctx, TORTURE_FAIL, __location__": Incorrect status %s - should be %s", \
nt_errstr(status), nt_errstr(correct)); \
ret = false; \
goto done; \
}} while (0)
/*
basic testing of SMB2 persistent file handles
regarding the position information on the handle
*/
bool torture_smb2_persistent_handles1(struct torture_context *tctx,
struct smb2_tree *tree1,
struct smb2_tree *tree2)
{
TALLOC_CTX *mem_ctx = talloc_new(tctx);
struct smb2_handle h1, h2;
struct smb2_create io1, io2;
NTSTATUS status;
const char *fname = "persistent_handles.dat";
DATA_BLOB b;
union smb_fileinfo qfinfo;
union smb_setfileinfo sfinfo;
bool ret = true;
uint64_t pos;
smb2_util_unlink(tree1, fname);
ZERO_STRUCT(io1);
io1.in.security_flags = 0x00;
io1.in.oplock_level = SMB2_OPLOCK_LEVEL_BATCH;
io1.in.impersonation_level = NTCREATEX_IMPERSONATION_IMPERSONATION;
io1.in.create_flags = 0x00000000;
io1.in.reserved = 0x00000000;
io1.in.desired_access = SEC_RIGHTS_FILE_ALL;
io1.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
io1.in.share_access = NTCREATEX_SHARE_ACCESS_READ |
NTCREATEX_SHARE_ACCESS_WRITE |
NTCREATEX_SHARE_ACCESS_DELETE;
io1.in.create_disposition = NTCREATEX_DISP_OPEN_IF;
io1.in.create_options = NTCREATEX_OPTIONS_SEQUENTIAL_ONLY |
NTCREATEX_OPTIONS_ASYNC_ALERT |
NTCREATEX_OPTIONS_NON_DIRECTORY_FILE |
0x00200000;
io1.in.fname = fname;
b = data_blob_talloc(mem_ctx, NULL, 16);
SBVAL(b.data, 0, 0);
SBVAL(b.data, 8, 0);
status = smb2_create_blob_add(tree1, &io1.in.blobs,
SMB2_CREATE_TAG_DHNQ,
b);
CHECK_STATUS(status, NT_STATUS_OK);
status = smb2_create(tree1, mem_ctx, &io1);
CHECK_STATUS(status, NT_STATUS_OK);
CHECK_VAL(io1.out.oplock_level, SMB2_OPLOCK_LEVEL_BATCH);
/*CHECK_VAL(io1.out.reserved, 0);*/
CHECK_VAL(io1.out.create_action, NTCREATEX_ACTION_CREATED);
CHECK_VAL(io1.out.alloc_size, 0);
CHECK_VAL(io1.out.size, 0);
CHECK_VAL(io1.out.file_attr, FILE_ATTRIBUTE_ARCHIVE);
CHECK_VAL(io1.out.reserved2, 0);
/* TODO: check extra blob content */
h1 = io1.out.file.handle;
ZERO_STRUCT(qfinfo);
qfinfo.generic.level = RAW_FILEINFO_POSITION_INFORMATION;
qfinfo.generic.in.file.handle = h1;
status = smb2_getinfo_file(tree1, mem_ctx, &qfinfo);
CHECK_STATUS(status, NT_STATUS_OK);
CHECK_VAL(qfinfo.position_information.out.position, 0);
pos = qfinfo.position_information.out.position;
torture_comment(tctx, "position: %llu\n",
(unsigned long long)pos);
ZERO_STRUCT(sfinfo);
sfinfo.generic.level = RAW_SFILEINFO_POSITION_INFORMATION;
sfinfo.generic.in.file.handle = h1;
sfinfo.position_information.in.position = 0x1000;
status = smb2_setinfo_file(tree1, &sfinfo);
CHECK_STATUS(status, NT_STATUS_OK);
ZERO_STRUCT(qfinfo);
qfinfo.generic.level = RAW_FILEINFO_POSITION_INFORMATION;
qfinfo.generic.in.file.handle = h1;
status = smb2_getinfo_file(tree1, mem_ctx, &qfinfo);
CHECK_STATUS(status, NT_STATUS_OK);
CHECK_VAL(qfinfo.position_information.out.position, 0x1000);
pos = qfinfo.position_information.out.position;
torture_comment(tctx, "position: %llu\n",
(unsigned long long)pos);
talloc_free(tree1);
tree1 = NULL;
ZERO_STRUCT(qfinfo);
qfinfo.generic.level = RAW_FILEINFO_POSITION_INFORMATION;
qfinfo.generic.in.file.handle = h1;
status = smb2_getinfo_file(tree2, mem_ctx, &qfinfo);
CHECK_STATUS(status, NT_STATUS_FILE_CLOSED);
ZERO_STRUCT(io2);
io2.in.fname = fname;
b = data_blob_talloc(tctx, NULL, 16);
SBVAL(b.data, 0, h1.data[0]);
SBVAL(b.data, 8, h1.data[1]);
status = smb2_create_blob_add(tree2, &io2.in.blobs,
SMB2_CREATE_TAG_DHNC,
b);
CHECK_STATUS(status, NT_STATUS_OK);
status = smb2_create(tree2, mem_ctx, &io2);
CHECK_STATUS(status, NT_STATUS_OK);
CHECK_VAL(io2.out.oplock_level, SMB2_OPLOCK_LEVEL_BATCH);
CHECK_VAL(io2.out.reserved, 0x00);
CHECK_VAL(io2.out.create_action, NTCREATEX_ACTION_EXISTED);
CHECK_VAL(io2.out.alloc_size, 0);
CHECK_VAL(io2.out.size, 0);
CHECK_VAL(io2.out.file_attr, FILE_ATTRIBUTE_ARCHIVE);
CHECK_VAL(io2.out.reserved2, 0);
h2 = io2.out.file.handle;
ZERO_STRUCT(qfinfo);
qfinfo.generic.level = RAW_FILEINFO_POSITION_INFORMATION;
qfinfo.generic.in.file.handle = h2;
status = smb2_getinfo_file(tree2, mem_ctx, &qfinfo);
CHECK_STATUS(status, NT_STATUS_OK);
CHECK_VAL(qfinfo.position_information.out.position, 0x1000);
pos = qfinfo.position_information.out.position;
torture_comment(tctx, "position: %llu\n",
(unsigned long long)pos);
talloc_free(mem_ctx);
smb2_util_unlink(tree2, fname);
done:
return ret;
}

View File

@ -47,9 +47,9 @@ static bool wrap_simple_1smb2_test(struct torture_context *torture_ctx,
}
struct torture_test *torture_suite_add_1smb2_test(struct torture_suite *suite,
const char *name,
bool (*run) (struct torture_context *,
struct smb2_tree *))
const char *name,
bool (*run)(struct torture_context *,
struct smb2_tree *))
{
struct torture_test *test;
struct torture_tcase *tcase;
@ -69,6 +69,61 @@ struct torture_test *torture_suite_add_1smb2_test(struct torture_suite *suite,
return test;
}
static bool wrap_simple_2smb2_test(struct torture_context *torture_ctx,
struct torture_tcase *tcase,
struct torture_test *test)
{
bool (*fn) (struct torture_context *, struct smb2_tree *, struct smb2_tree *);
bool ret;
struct smb2_tree *tree1;
struct smb2_tree *tree2;
TALLOC_CTX *mem_ctx = talloc_new(torture_ctx);
if (!torture_smb2_connection(torture_ctx, &tree1) ||
!torture_smb2_connection(torture_ctx, &tree2)) {
return false;
}
talloc_steal(mem_ctx, tree1);
talloc_steal(mem_ctx, tree2);
fn = test->fn;
ret = fn(torture_ctx, tree1, tree2);
/* the test may already closed some of the connections */
talloc_free(mem_ctx);
return ret;
}
_PUBLIC_ struct torture_test *torture_suite_add_2smb2_test(struct torture_suite *suite,
const char *name,
bool (*run)(struct torture_context *,
struct smb2_tree *,
struct smb2_tree *))
{
struct torture_test *test;
struct torture_tcase *tcase;
tcase = torture_suite_add_tcase(suite, name);
test = talloc(tcase, struct torture_test);
test->name = talloc_strdup(test, name);
test->description = NULL;
test->run = wrap_simple_2smb2_test;
test->fn = run;
test->dangerous = false;
DLIST_ADD_END(tcase->tests, test, struct torture_test *);
return test;
}
NTSTATUS torture_smb2_init(void)
{
struct torture_suite *suite = torture_suite_create(talloc_autofree_context(), "SMB2");
@ -82,6 +137,7 @@ NTSTATUS torture_smb2_init(void)
torture_suite_add_simple_test(suite, "FIND", torture_smb2_find);
torture_suite_add_suite(suite, torture_smb2_lock_init());
torture_suite_add_simple_test(suite, "NOTIFY", torture_smb2_notify);
torture_suite_add_2smb2_test(suite, "PERSISTENT-HANDLES1", torture_smb2_persistent_handles1);
suite->description = talloc_strdup(suite, "SMB2-specific tests");