#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"
#include "system/shmem.h"
#include "system/wait.h"
#include "system/time.h"
-#include "torture/ui.h"
#include "torture/torture.h"
-#include "util/dlinklist.h"
-#include "auth/credentials/credentials.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"
/**
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;
}
/*
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;
}
}
- /* 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)) {
}
/* 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);
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");
}
}
}
- /* 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)) {
}
/* 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);
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");
}
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");
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_transport *transport)
+bool wire_bad_flags(struct smb_wire_string *str, int flags,
+ struct smbcli_transport *transport)
{
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 = (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) {
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;
}
/*
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);
_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 = lp_parm_bool(NULL, "torture",
- "use_oplocks", false);
- (*c)->transport->options.use_level2_oplocks = lp_parm_bool(NULL, "torture",
- "use_level2_oplocks", false);
-
- return True;
+ return true;
}
_PUBLIC_ bool torture_get_conn_index(int conn_index,
TALLOC_CTX *mem_ctx,
+ struct torture_context *tctx,
char **host, char **share)
{
char **unc_list = NULL;
int num_unc_names = 0;
const char *p;
- (*host) = talloc_strdup(mem_ctx, lp_parm_string(NULL, "torture", "host"));
- (*share) = talloc_strdup(mem_ctx, lp_parm_string(NULL, "torture", "share"));
+ (*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(NULL, "torture", "unclist");
+ p = torture_setting_string(tctx, "unclist", NULL);
if (!p) {
- return True;
+ return true;
}
- unc_list = file_lines_load(p, &num_unc_names, NULL);
+ 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 false;
}
- if (!smbcli_parse_unc(unc_list[conn_index % num_unc_names],
- mem_ctx, host, share)) {
+ 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;
+ return false;
}
talloc_free(unc_list);
- return True;
+ return true;
}
_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)
{
char *host, *share;
bool ret;
- if (!torture_get_conn_index(conn_index, ev, &host, &share)) {
- return False;
+ if (!torture_get_conn_index(conn_index, ev, tctx, &host, &share)) {
+ return false;
}
- ret = torture_open_connection_share(NULL, c, host, share, ev);
+ ret = torture_open_connection_share(NULL, c, tctx, host, share, ev);
talloc_free(host);
talloc_free(share);
return ret;
}
-_PUBLIC_ bool torture_open_connection(struct smbcli_state **c, int conn_index)
+_PUBLIC_ bool torture_open_connection(struct smbcli_state **c, struct torture_context *tctx, int conn_index)
{
- return torture_open_connection_ev(c, conn_index,
- cli_credentials_get_event_context(cmdline_credentials));
+ return torture_open_connection_ev(c, conn_index, tctx, tctx->ev);
}
_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;
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;
double start_time_limit = 10 + (torture_nprocs * 1.5);
struct timeval tv;
- *result = True;
+ *result = true;
synccount = 0;
for (i = 0; i < torture_nprocs; i++) {
child_status[i] = 0;
- child_status_out[i] = True;
+ child_status_out[i] = true;
}
tv = timeval_current();
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) {
if (synccount != torture_nprocs) {
printf("FAILED TO START %d CLIENTS (started %d)\n", torture_nprocs, synccount);
- *result = False;
+ *result = false;
return timeval_elapsed(&tv);
}
int ret;
while ((ret=waitpid(0, &status, 0)) == -1 && errno == EINTR) /* noop */ ;
if (ret == -1 || WEXITSTATUS(status) != 0) {
- *result = False;
+ *result = false;
}
}
for (i=0;i<torture_nprocs;i++) {
if (!child_status_out[i]) {
- *result = False;
+ *result = false;
}
}
return timeval_elapsed(&tv);
struct smbcli_state *cli1, *cli2;
- if (!torture_open_connection(&cli1, 0) ||
- !torture_open_connection(&cli2, 1))
+ if (!torture_open_connection(&cli1, torture_ctx, 0) ||
+ !torture_open_connection(&cli2, torture_ctx, 1))
return false;
fn = test->fn;
struct smbcli_state *cli1;
- if (!torture_open_connection(&cli1, 0))
+ if (!torture_open_connection(&cli1, torture_ctx, 0))
return false;
fn = test->fn;
}
+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);
+}