X-Git-Url: http://git.samba.org/?p=samba.git;a=blobdiff_plain;f=source4%2Ftorture%2Futil_smb.c;h=216927ce70dcc3c527a32d59e38061ccb47ac5d7;hp=c1e4edc5e6f10a29de50b44c0de225f124b08fba;hb=8edab1b96c47e75b2f2c61739f9283fa2ecf5cfe;hpb=0329d755a7611ba3897fc1ee9bdce410cc33d7f8
diff --git a/source4/torture/util_smb.c b/source4/torture/util_smb.c
index c1e4edc5e6f..216927ce70d 100644
--- a/source4/torture/util_smb.c
+++ b/source4/torture/util_smb.c
@@ -2,10 +2,11 @@
Unix SMB/CIFS implementation.
SMB torture tester utility functions
Copyright (C) Andrew Tridgell 2003
+ Copyright (C) Jelmer Vernooij 2006
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,
@@ -14,13 +15,13 @@
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 .
*/
#include "includes.h"
#include "lib/cmdline/popt_common.h"
#include "libcli/raw/libcliraw.h"
+#include "libcli/raw/raw_proto.h"
#include "libcli/raw/ioctl.h"
#include "libcli/libcli.h"
#include "system/filesys.h"
@@ -28,20 +29,25 @@
#include "system/wait.h"
#include "system/time.h"
#include "torture/torture.h"
+#include "../lib/util/dlinklist.h"
+#include "libcli/resolve/resolve.h"
+#include "param/param.h"
+#include "libcli/security/security.h"
+#include "libcli/util/clilsa.h"
/**
setup a directory ready for a test
*/
-_PUBLIC_ BOOL torture_setup_dir(struct smbcli_state *cli, const char *dname)
+_PUBLIC_ bool torture_setup_dir(struct smbcli_state *cli, const char *dname)
{
smb_raw_exit(cli->session);
if (smbcli_deltree(cli->tree, dname) == -1 ||
NT_STATUS_IS_ERR(smbcli_mkdir(cli->tree, dname))) {
printf("Unable to setup %s - %s\n", dname, smbcli_errstr(cli->tree));
- return False;
+ return false;
}
- return True;
+ return true;
}
/*
@@ -53,15 +59,15 @@ NTSTATUS create_directory_handle(struct smbcli_tree *tree, const char *dname, in
union smb_open io;
TALLOC_CTX *mem_ctx;
- mem_ctx = talloc_init("create_directory_handle");
+ mem_ctx = talloc_named_const(tree, 0, "create_directory_handle");
io.generic.level = RAW_OPEN_NTCREATEX;
- io.ntcreatex.in.root_fid = 0;
+ io.ntcreatex.in.root_fid.fnum = 0;
io.ntcreatex.in.flags = 0;
io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
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;
+ io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE | NTCREATEX_SHARE_ACCESS_DELETE;
io.ntcreatex.in.alloc_size = 0;
io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
@@ -123,14 +129,17 @@ _PUBLIC_ int create_complex_file(struct smbcli_state *cli, TALLOC_CTX *mem_ctx,
}
}
- /* make sure all the timestamps aren't the same, and are also
- in different DST zones*/
- setfile.generic.level = RAW_SFILEINFO_SETATTRE;
+ /* make sure all the timestamps aren't the same */
+ ZERO_STRUCT(setfile);
+ setfile.generic.level = RAW_SFILEINFO_BASIC_INFO;
setfile.generic.in.file.fnum = fnum;
- setfile.setattre.in.create_time = t + 9*30*24*60*60;
- setfile.setattre.in.access_time = t + 6*30*24*60*60;
- setfile.setattre.in.write_time = t + 3*30*24*60*60;
+ unix_to_nt_time(&setfile.basic_info.in.create_time,
+ t + 9*30*24*60*60);
+ unix_to_nt_time(&setfile.basic_info.in.access_time,
+ t + 6*30*24*60*60);
+ unix_to_nt_time(&setfile.basic_info.in.write_time,
+ t + 3*30*24*60*60);
status = smb_raw_setfileinfo(cli->tree, &setfile);
if (!NT_STATUS_IS_OK(status)) {
@@ -138,7 +147,7 @@ _PUBLIC_ int create_complex_file(struct smbcli_state *cli, TALLOC_CTX *mem_ctx,
}
/* make sure all the timestamps aren't the same */
- fileinfo.generic.level = RAW_FILEINFO_GETATTRE;
+ fileinfo.generic.level = RAW_FILEINFO_BASIC_INFO;
fileinfo.generic.in.file.fnum = fnum;
status = smb_raw_fileinfo(cli->tree, mem_ctx, &fileinfo);
@@ -146,13 +155,13 @@ _PUBLIC_ int create_complex_file(struct smbcli_state *cli, TALLOC_CTX *mem_ctx,
printf("Failed to query file times - %s\n", nt_errstr(status));
}
- if (setfile.setattre.in.create_time != fileinfo.getattre.out.create_time) {
+ if (setfile.basic_info.in.create_time != fileinfo.basic_info.out.create_time) {
printf("create_time not setup correctly\n");
}
- if (setfile.setattre.in.access_time != fileinfo.getattre.out.access_time) {
+ if (setfile.basic_info.in.access_time != fileinfo.basic_info.out.access_time) {
printf("access_time not setup correctly\n");
}
- if (setfile.setattre.in.write_time != fileinfo.getattre.out.write_time) {
+ if (setfile.basic_info.in.write_time != fileinfo.basic_info.out.write_time) {
printf("write_time not setup correctly\n");
}
@@ -200,14 +209,17 @@ int create_complex_dir(struct smbcli_state *cli, TALLOC_CTX *mem_ctx, const char
}
}
- /* make sure all the timestamps aren't the same, and are also
- in different DST zones*/
- setfile.generic.level = RAW_SFILEINFO_SETATTRE;
+ /* make sure all the timestamps aren't the same */
+ ZERO_STRUCT(setfile);
+ setfile.generic.level = RAW_SFILEINFO_BASIC_INFO;
setfile.generic.in.file.fnum = fnum;
- setfile.setattre.in.create_time = t + 9*30*24*60*60;
- setfile.setattre.in.access_time = t + 6*30*24*60*60;
- setfile.setattre.in.write_time = t + 3*30*24*60*60;
+ unix_to_nt_time(&setfile.basic_info.in.create_time,
+ t + 9*30*24*60*60);
+ unix_to_nt_time(&setfile.basic_info.in.access_time,
+ t + 6*30*24*60*60);
+ unix_to_nt_time(&setfile.basic_info.in.write_time,
+ t + 3*30*24*60*60);
status = smb_raw_setfileinfo(cli->tree, &setfile);
if (!NT_STATUS_IS_OK(status)) {
@@ -215,7 +227,7 @@ int create_complex_dir(struct smbcli_state *cli, TALLOC_CTX *mem_ctx, const char
}
/* make sure all the timestamps aren't the same */
- fileinfo.generic.level = RAW_FILEINFO_GETATTRE;
+ fileinfo.generic.level = RAW_FILEINFO_BASIC_INFO;
fileinfo.generic.in.file.fnum = fnum;
status = smb_raw_fileinfo(cli->tree, mem_ctx, &fileinfo);
@@ -223,13 +235,13 @@ int create_complex_dir(struct smbcli_state *cli, TALLOC_CTX *mem_ctx, const char
printf("Failed to query file times - %s\n", nt_errstr(status));
}
- if (setfile.setattre.in.create_time != fileinfo.getattre.out.create_time) {
+ if (setfile.basic_info.in.create_time != fileinfo.basic_info.out.create_time) {
printf("create_time not setup correctly\n");
}
- if (setfile.setattre.in.access_time != fileinfo.getattre.out.access_time) {
+ if (setfile.basic_info.in.access_time != fileinfo.basic_info.out.access_time) {
printf("access_time not setup correctly\n");
}
- if (setfile.setattre.in.write_time != fileinfo.getattre.out.write_time) {
+ if (setfile.basic_info.in.write_time != fileinfo.basic_info.out.write_time) {
printf("write_time not setup correctly\n");
}
@@ -252,6 +264,23 @@ void *shm_setup(int size)
int shmid;
void *ret;
+#ifdef __QNXNTO__
+ shmid = shm_open("private", O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR);
+ if (shmid == -1) {
+ printf("can't get shared memory\n");
+ exit(1);
+ }
+ shm_unlink("private");
+ if (ftruncate(shmid, size) == -1) {
+ printf("can't set shared memory size\n");
+ exit(1);
+ }
+ ret = mmap(0, size, PROT_READ | PROT_WRITE, MAP_SHARED, shmid, 0);
+ if (ret == MAP_FAILED) {
+ printf("can't map shared memory\n");
+ exit(1);
+ }
+#else
shmid = shmget(IPC_PRIVATE, size, SHM_R | SHM_W);
if (shmid == -1) {
printf("can't get shared memory\n");
@@ -270,26 +299,28 @@ void *shm_setup(int size)
See Stevens "advanced programming in unix env" for details
*/
shmctl(shmid, IPC_RMID, 0);
+#endif
return ret;
}
-/*
+/**
check that a wire string matches the flags specified
not 100% accurate, but close enough for testing
*/
-BOOL wire_bad_flags(struct smb_wire_string *str, int flags, struct smbcli_state *cli)
+bool wire_bad_flags(struct smb_wire_string *str, int flags,
+ struct smbcli_transport *transport)
{
- BOOL server_unicode;
+ bool server_unicode;
int len;
- if (!str || !str->s) return True;
+ if (!str || !str->s) return true;
len = strlen(str->s);
if (flags & STR_TERMINATE) len++;
- server_unicode = (cli->transport->negotiate.capabilities&CAP_UNICODE)?True:False;
- if (getenv("CLI_FORCE_ASCII") || !lp_unicode()) {
- server_unicode = False;
+ server_unicode = (transport->negotiate.capabilities&CAP_UNICODE)?true:false;
+ if (getenv("CLI_FORCE_ASCII") || !transport->options.unicode) {
+ server_unicode = false;
}
if ((flags & STR_UNICODE) || server_unicode) {
@@ -300,9 +331,9 @@ BOOL wire_bad_flags(struct smb_wire_string *str, int flags, struct smbcli_state
if (str->private_length != len) {
printf("Expected wire_length %d but got %d for '%s'\n",
len, str->private_length, str->s);
- return True;
+ return true;
}
- return False;
+ return false;
}
/*
@@ -329,7 +360,7 @@ void dump_all_info(TALLOC_CTX *mem_ctx, union smb_fileinfo *finfo)
*/
void torture_all_info(struct smbcli_tree *tree, const char *fname)
{
- TALLOC_CTX *mem_ctx = talloc_init("%s", fname);
+ TALLOC_CTX *mem_ctx = talloc_named(tree, 0, "%s", fname);
union smb_fileinfo finfo;
NTSTATUS status;
@@ -350,7 +381,7 @@ void torture_all_info(struct smbcli_tree *tree, const char *fname)
/*
set a attribute on a file
*/
-BOOL torture_set_file_attribute(struct smbcli_tree *tree, const char *fname, uint16_t attrib)
+bool torture_set_file_attribute(struct smbcli_tree *tree, const char *fname, uint16_t attrib)
{
union smb_setfileinfo sfinfo;
NTSTATUS status;
@@ -373,7 +404,7 @@ NTSTATUS torture_set_sparse(struct smbcli_tree *tree, int fnum)
NTSTATUS status;
TALLOC_CTX *mem_ctx;
- mem_ctx = talloc_init("torture_set_sparse");
+ mem_ctx = talloc_named_const(tree, 0, "torture_set_sparse");
if (!mem_ctx) {
return NT_STATUS_NO_MEMORY;
}
@@ -381,7 +412,7 @@ NTSTATUS torture_set_sparse(struct smbcli_tree *tree, int fnum)
nt.ntioctl.level = RAW_IOCTL_NTIOCTL;
nt.ntioctl.in.function = FSCTL_SET_SPARSE;
nt.ntioctl.in.file.fnum = fnum;
- nt.ntioctl.in.fsctl = True;
+ nt.ntioctl.in.fsctl = true;
nt.ntioctl.in.filter = 0;
nt.ntioctl.in.max_data = 0;
nt.ntioctl.in.blob = data_blob(NULL, 0);
@@ -459,100 +490,113 @@ NTSTATUS torture_check_ea(struct smbcli_state *cli,
return NT_STATUS_EA_CORRUPT_ERROR;
}
-BOOL torture_open_connection_share(TALLOC_CTX *mem_ctx,
+_PUBLIC_ bool torture_open_connection_share(TALLOC_CTX *mem_ctx,
struct smbcli_state **c,
+ struct torture_context *tctx,
const char *hostname,
const char *sharename,
- struct event_context *ev)
+ struct tevent_context *ev)
{
NTSTATUS status;
+ struct smbcli_options options;
+ struct smbcli_session_options session_options;
+
+ lp_smbcli_options(tctx->lp_ctx, &options);
+ lp_smbcli_session_options(tctx->lp_ctx, &session_options);
+
+ options.use_oplocks = torture_setting_bool(tctx, "use_oplocks", true);
+ options.use_level2_oplocks = torture_setting_bool(tctx, "use_level2_oplocks", true);
+
status = smbcli_full_connection(mem_ctx, c, hostname,
+ lp_smb_ports(tctx->lp_ctx),
sharename, NULL,
- cmdline_credentials, ev);
+ lp_socket_options(tctx->lp_ctx),
+ cmdline_credentials,
+ lp_resolve_context(tctx->lp_ctx),
+ ev, &options, &session_options,
+ lp_iconv_convenience(tctx->lp_ctx),
+ lp_gensec_settings(tctx, tctx->lp_ctx));
if (!NT_STATUS_IS_OK(status)) {
printf("Failed to open connection - %s\n", nt_errstr(status));
- return False;
+ return false;
}
- (*c)->transport->options.use_oplocks = use_oplocks;
- (*c)->transport->options.use_level2_oplocks = use_level_II_oplocks;
-
- return True;
+ return true;
}
-_PUBLIC_ BOOL torture_open_connection(struct smbcli_state **c, int conn_index)
+_PUBLIC_ bool torture_get_conn_index(int conn_index,
+ TALLOC_CTX *mem_ctx,
+ struct torture_context *tctx,
+ char **host, char **share)
{
- const char *host = lp_parm_string(-1, "torture", "host");
- const char *share = lp_parm_string(-1, "torture", "share");
char **unc_list = NULL;
int num_unc_names = 0;
const char *p;
+
+ (*host) = talloc_strdup(mem_ctx, torture_setting_string(tctx, "host", NULL));
+ (*share) = talloc_strdup(mem_ctx, torture_setting_string(tctx, "share", NULL));
- p = lp_parm_string(-1, "torture", "unclist");
- if (p) {
- char *h, *s;
- unc_list = file_lines_load(p, &num_unc_names, NULL);
- if (!unc_list || num_unc_names <= 0) {
- printf("Failed to load unc names list from '%s'\n", p);
- exit(1);
- }
+ p = torture_setting_string(tctx, "unclist", NULL);
+ if (!p) {
+ return true;
+ }
- if (!smbcli_parse_unc(unc_list[conn_index % num_unc_names],
- NULL, &h, &s)) {
- printf("Failed to parse UNC name %s\n",
- unc_list[conn_index % num_unc_names]);
- exit(1);
- }
- host = h;
- share = s;
+ unc_list = file_lines_load(p, &num_unc_names, 0, NULL);
+ if (!unc_list || num_unc_names <= 0) {
+ DEBUG(0,("Failed to load unc names list from '%s'\n", p));
+ return false;
}
- return torture_open_connection_share(NULL, c, host, share, NULL);
+ p = unc_list[conn_index % num_unc_names];
+ if (p[0] != '/' && p[0] != '\\') {
+ /* allow UNC lists of hosts */
+ (*host) = talloc_strdup(mem_ctx, p);
+ } else if (!smbcli_parse_unc(p, mem_ctx, host, share)) {
+ DEBUG(0, ("Failed to parse UNC name %s\n",
+ unc_list[conn_index % num_unc_names]));
+ return false;
+ }
+
+ talloc_free(unc_list);
+ return true;
}
-_PUBLIC_ BOOL torture_open_connection_ev(struct smbcli_state **c,
+
+
+_PUBLIC_ bool torture_open_connection_ev(struct smbcli_state **c,
int conn_index,
- struct event_context *ev)
+ struct torture_context *tctx,
+ struct tevent_context *ev)
{
- const char *host = lp_parm_string(-1, "torture", "host");
- const char *share = lp_parm_string(-1, "torture", "share");
- char **unc_list = NULL;
- int num_unc_names = 0;
- const char *p;
-
- p = lp_parm_string(-1, "torture", "unclist");
- if (p) {
- char *h, *s;
- unc_list = file_lines_load(p, &num_unc_names, NULL);
- if (!unc_list || num_unc_names <= 0) {
- printf("Failed to load unc names list from '%s'\n", p);
- exit(1);
- }
+ char *host, *share;
+ bool ret;
- if (!smbcli_parse_unc(unc_list[conn_index % num_unc_names],
- NULL, &h, &s)) {
- printf("Failed to parse UNC name %s\n",
- unc_list[conn_index % num_unc_names]);
- exit(1);
- }
- host = h;
- share = s;
+ if (!torture_get_conn_index(conn_index, ev, tctx, &host, &share)) {
+ return false;
}
+ ret = torture_open_connection_share(NULL, c, tctx, host, share, ev);
+ talloc_free(host);
+ talloc_free(share);
- return torture_open_connection_share(NULL, c, host, share, ev);
+ return ret;
+}
+
+_PUBLIC_ bool torture_open_connection(struct smbcli_state **c, struct torture_context *tctx, int conn_index)
+{
+ return torture_open_connection_ev(c, conn_index, tctx, tctx->ev);
}
-_PUBLIC_ BOOL torture_close_connection(struct smbcli_state *c)
+_PUBLIC_ bool torture_close_connection(struct smbcli_state *c)
{
- BOOL ret = True;
- if (!c) return True;
+ bool ret = true;
+ if (!c) return true;
if (NT_STATUS_IS_ERR(smbcli_tdis(c))) {
printf("tdis failed (%s)\n", smbcli_errstr(c->tree));
- ret = False;
+ ret = false;
}
talloc_free(c);
return ret;
@@ -560,32 +604,32 @@ _PUBLIC_ BOOL torture_close_connection(struct smbcli_state *c)
/* check if the server produced the expected error code */
-_PUBLIC_ BOOL check_error(const char *location, struct smbcli_state *c,
+_PUBLIC_ bool check_error(const char *location, struct smbcli_state *c,
uint8_t eclass, uint32_t ecode, NTSTATUS nterr)
{
NTSTATUS status;
status = smbcli_nt_error(c->tree);
if (NT_STATUS_IS_DOS(status)) {
- int class, num;
- class = NT_STATUS_DOS_CLASS(status);
+ int classnum, num;
+ classnum = NT_STATUS_DOS_CLASS(status);
num = NT_STATUS_DOS_CODE(status);
- if (eclass != class || ecode != num) {
+ if (eclass != classnum || ecode != num) {
printf("unexpected error code %s\n", nt_errstr(status));
printf(" expected %s or %s (at %s)\n",
nt_errstr(NT_STATUS_DOS(eclass, ecode)),
nt_errstr(nterr), location);
- return False;
+ return false;
}
} else {
if (!NT_STATUS_EQUAL(nterr, status)) {
printf("unexpected error code %s\n", nt_errstr(status));
printf(" expected %s (at %s)\n", nt_errstr(nterr), location);
- return False;
+ return false;
}
}
- return True;
+ return true;
}
static struct smbcli_state *current_cli;
@@ -595,17 +639,19 @@ static void sigcont(int sig)
{
}
-double torture_create_procs(BOOL (*fn)(struct smbcli_state *, int), BOOL *result)
+double torture_create_procs(struct torture_context *tctx,
+ bool (*fn)(struct torture_context *, struct smbcli_state *, int), bool *result)
{
int i, status;
volatile pid_t *child_status;
- volatile BOOL *child_status_out;
+ volatile bool *child_status_out;
int synccount;
int tries = 8;
+ int torture_nprocs = torture_setting_int(tctx, "nprocs", 4);
double start_time_limit = 10 + (torture_nprocs * 1.5);
struct timeval tv;
- *result = True;
+ *result = true;
synccount = 0;
@@ -617,7 +663,7 @@ double torture_create_procs(BOOL (*fn)(struct smbcli_state *, int), BOOL *result
return -1;
}
- child_status_out = (volatile BOOL *)shm_setup(sizeof(BOOL)*torture_nprocs);
+ child_status_out = (volatile bool *)shm_setup(sizeof(bool)*torture_nprocs);
if (!child_status_out) {
printf("Failed to setup result status shared memory\n");
return -1;
@@ -625,7 +671,7 @@ double torture_create_procs(BOOL (*fn)(struct smbcli_state *, int), BOOL *result
for (i = 0; i < torture_nprocs; i++) {
child_status[i] = 0;
- child_status_out[i] = True;
+ child_status_out[i] = true;
}
tv = timeval_current();
@@ -638,13 +684,16 @@ double torture_create_procs(BOOL (*fn)(struct smbcli_state *, int), BOOL *result
pid_t mypid = getpid();
srandom(((int)mypid) ^ ((int)time(NULL)));
- asprintf(&myname, "CLIENT%d", i);
- lp_set_cmdline("netbios name", myname);
+ if (asprintf(&myname, "CLIENT%d", i) == -1) {
+ printf("asprintf failed\n");
+ return -1;
+ }
+ lp_set_cmdline(tctx->lp_ctx, "netbios name", myname);
free(myname);
while (1) {
- if (torture_open_connection(¤t_cli, i)) {
+ if (torture_open_connection(¤t_cli, tctx, i)) {
break;
}
if (tries-- == 0) {
@@ -664,7 +713,7 @@ double torture_create_procs(BOOL (*fn)(struct smbcli_state *, int), BOOL *result
_exit(1);
}
- child_status_out[i] = fn(current_cli, i);
+ child_status_out[i] = fn(tctx, current_cli, i);
_exit(0);
}
}
@@ -680,7 +729,7 @@ double torture_create_procs(BOOL (*fn)(struct smbcli_state *, int), BOOL *result
if (synccount != torture_nprocs) {
printf("FAILED TO START %d CLIENTS (started %d)\n", torture_nprocs, synccount);
- *result = False;
+ *result = false;
return timeval_elapsed(&tv);
}
@@ -700,7 +749,7 @@ double torture_create_procs(BOOL (*fn)(struct smbcli_state *, int), BOOL *result
int ret;
while ((ret=waitpid(0, &status, 0)) == -1 && errno == EINTR) /* noop */ ;
if (ret == -1 || WEXITSTATUS(status) != 0) {
- *result = False;
+ *result = false;
}
}
@@ -708,36 +757,217 @@ double torture_create_procs(BOOL (*fn)(struct smbcli_state *, int), BOOL *result
for (i=0;ifn;
+ bool result;
- torture_create_procs(fn, &result);
+ torture_create_procs(torture, fn, &result);
return result;
}
-_PUBLIC_ NTSTATUS register_torture_multi_op(const char *name,
- BOOL (*multi_fn)(struct smbcli_state *, int ))
+_PUBLIC_ struct torture_test *torture_suite_add_smb_multi_test(
+ struct torture_suite *suite,
+ const char *name,
+ bool (*run) (struct torture_context *,
+ struct smbcli_state *,
+ int i))
+{
+ 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_smb_multi_test;
+ test->fn = run;
+ test->dangerous = false;
+
+ DLIST_ADD_END(tcase->tests, test, struct torture_test *);
+
+ return test;
+
+}
+
+static bool wrap_simple_2smb_test(struct torture_context *torture_ctx,
+ struct torture_tcase *tcase,
+ struct torture_test *test)
+{
+ bool (*fn) (struct torture_context *, struct smbcli_state *,
+ struct smbcli_state *);
+ bool ret;
+
+ struct smbcli_state *cli1, *cli2;
+
+ if (!torture_open_connection(&cli1, torture_ctx, 0) ||
+ !torture_open_connection(&cli2, torture_ctx, 1))
+ return false;
+
+ fn = test->fn;
+
+ ret = fn(torture_ctx, cli1, cli2);
+
+ talloc_free(cli1);
+ talloc_free(cli2);
+
+ return ret;
+}
+
+
+
+_PUBLIC_ struct torture_test *torture_suite_add_2smb_test(
+ struct torture_suite *suite,
+ const char *name,
+ bool (*run) (struct torture_context *,
+ struct smbcli_state *,
+ struct smbcli_state *))
+{
+ 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_2smb_test;
+ test->fn = run;
+ test->dangerous = false;
+
+ DLIST_ADD_END(tcase->tests, test, struct torture_test *);
+
+ return test;
+
+}
+
+static bool wrap_simple_1smb_test(struct torture_context *torture_ctx,
+ struct torture_tcase *tcase,
+ struct torture_test *test)
{
- struct torture_suite *suite;
+ bool (*fn) (struct torture_context *, struct smbcli_state *);
+ bool ret;
+
+ struct smbcli_state *cli1;
+
+ if (!torture_open_connection(&cli1, torture_ctx, 0))
+ return false;
- suite = torture_suite_create(talloc_autofree_context(), name);
+ fn = test->fn;
+
+ ret = fn(torture_ctx, cli1);
+
+ talloc_free(cli1);
+
+ return ret;
+}
+
+_PUBLIC_ struct torture_test *torture_suite_add_1smb_test(
+ struct torture_suite *suite,
+ const char *name,
+ bool (*run) (struct torture_context *, struct smbcli_state *))
+{
+ 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_1smb_test;
+ test->fn = run;
+ test->dangerous = false;
+
+ DLIST_ADD_END(tcase->tests, test, struct torture_test *);
+
+ return test;
+}
- torture_suite_add_simple_tcase(suite, name,
- wrap_old_torture_multifn,
- multi_fn);
- torture_register_suite(suite);
+NTSTATUS torture_second_tcon(TALLOC_CTX *mem_ctx,
+ struct smbcli_session *session,
+ const char *sharename,
+ struct smbcli_tree **res)
+{
+ union smb_tcon tcon;
+ struct smbcli_tree *result;
+ TALLOC_CTX *tmp_ctx;
+ NTSTATUS status;
+
+ if ((tmp_ctx = talloc_new(mem_ctx)) == NULL) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ result = smbcli_tree_init(session, tmp_ctx, false);
+ if (result == NULL) {
+ talloc_free(tmp_ctx);
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ tcon.generic.level = RAW_TCON_TCONX;
+ tcon.tconx.in.flags = 0;
+
+ /* Ignore share mode security here */
+ tcon.tconx.in.password = data_blob(NULL, 0);
+ tcon.tconx.in.path = sharename;
+ tcon.tconx.in.device = "?????";
+
+ status = smb_raw_tcon(result, tmp_ctx, &tcon);
+ if (!NT_STATUS_IS_OK(status)) {
+ talloc_free(tmp_ctx);
+ return status;
+ }
+
+ result->tid = tcon.tconx.out.tid;
+ *res = talloc_steal(mem_ctx, result);
+ talloc_free(tmp_ctx);
return NT_STATUS_OK;
}
+/*
+ a wrapper around smblsa_sid_check_privilege, that tries to take
+ account of the fact that the lsa privileges calls don't expand
+ group memberships, using an explicit check for administrator. There
+ must be a better way ...
+ */
+NTSTATUS torture_check_privilege(struct smbcli_state *cli,
+ const char *sid_str,
+ const char *privilege)
+{
+ struct dom_sid *sid;
+ TALLOC_CTX *tmp_ctx = talloc_new(cli);
+ uint32_t rid;
+ NTSTATUS status;
+
+ sid = dom_sid_parse_talloc(tmp_ctx, sid_str);
+ if (sid == NULL) {
+ talloc_free(tmp_ctx);
+ return NT_STATUS_INVALID_SID;
+ }
+ status = dom_sid_split_rid(tmp_ctx, sid, NULL, &rid);
+ NT_STATUS_NOT_OK_RETURN_AND_FREE(status, tmp_ctx);
+
+ if (rid == DOMAIN_RID_ADMINISTRATOR) {
+ /* assume the administrator has them all */
+ return NT_STATUS_OK;
+ }
+
+ talloc_free(tmp_ctx);
+
+ return smblsa_sid_check_privilege(cli, sid_str, privilege);
+}