#include "lib/cmdline/popt_common.h"
#include "libcli/raw/libcliraw.h"
#include "libcli/raw/raw_proto.h"
-#include "libcli/raw/ioctl.h"
+#include "../libcli/smb/smb_constants.h"
#include "libcli/libcli.h"
#include "system/filesys.h"
#include "system/shmem.h"
#include "param/param.h"
#include "libcli/security/security.h"
#include "libcli/util/clilsa.h"
-
+#include "torture/util.h"
+#include "libcli/smb/smbXcli_base.h"
/**
setup a directory ready for a test
return fnum;
}
-
-
-/* return a pointer to a anonymous shared memory segment of size "size"
- which will persist across fork() but will disappear when all processes
- exit
-
- The memory is not zeroed
-
- This function uses system5 shared memory. It takes advantage of a property
- that the memory is not destroyed if it is attached when the id is removed
- */
-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");
- exit(1);
- }
- ret = (void *)shmat(shmid, 0, 0);
- if (!ret || ret == (void *)-1) {
- printf("can't attach to shared memory\n");
- return NULL;
- }
- /* the following releases the ipc, but note that this process
- and all its children will still have access to the memory, its
- just that the shmid is no longer valid for other shm calls. This
- means we don't leave behind lots of shm segments after we exit
-
- 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
lpcfg_smb_ports(tctx->lp_ctx),
sharename, NULL,
lpcfg_socket_options(tctx->lp_ctx),
- cmdline_credentials,
+ popt_get_cmdline_credentials(),
lpcfg_resolve_context(tctx->lp_ctx),
ev, &options, &session_options,
lpcfg_gensec_settings(tctx, tctx->lp_ctx));
{
}
-double torture_create_procs(struct torture_context *tctx,
- bool (*fn)(struct torture_context *, struct smbcli_state *, int), bool *result)
+struct child_status {
+ pid_t pid;
+ bool start;
+ enum torture_result result;
+ char reason[1024];
+};
+
+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;
+ struct child_status *child_status;
int synccount;
int tries = 8;
int torture_nprocs = torture_setting_int(tctx, "nprocs", 4);
signal(SIGCONT, sigcont);
- child_status = (volatile pid_t *)shm_setup(sizeof(pid_t)*torture_nprocs);
- if (!child_status) {
+ child_status = (struct child_status *)anonymous_shared_allocate(
+ sizeof(struct child_status)*torture_nprocs);
+ if (child_status == NULL) {
printf("Failed to setup shared memory\n");
return -1;
}
- 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;
- }
-
for (i = 0; i < torture_nprocs; i++) {
- child_status[i] = 0;
- child_status_out[i] = true;
+ ZERO_STRUCT(child_status[i]);
}
tv = timeval_current();
procnum = i;
if (fork() == 0) {
char *myname;
+ bool ok;
pid_t mypid = getpid();
srandom(((int)mypid) ^ ((int)time(NULL)));
smb_msleep(100);
}
- child_status[i] = getpid();
+ child_status[i].pid = getpid();
pause();
- if (child_status[i]) {
+ if (!child_status[i].start) {
+ child_status[i].result = TORTURE_ERROR;
printf("Child %d failed to start!\n", i);
- child_status_out[i] = 1;
_exit(1);
}
- child_status_out[i] = fn(tctx, current_cli, i);
+ ok = fn(tctx, current_cli, i);
+ if (!ok) {
+ if (tctx->last_result == TORTURE_OK) {
+ torture_result(tctx, TORTURE_ERROR,
+ "unknown error: missing "
+ "torture_result call?\n");
+ }
+
+ child_status[i].result = tctx->last_result;
+
+ if (strlen(tctx->last_reason) > 1023) {
+ /* note: reason already contains \n */
+ torture_comment(tctx,
+ "child %d (pid %u) failed: %s",
+ i,
+ (unsigned)child_status[i].pid,
+ tctx->last_reason);
+ }
+
+ snprintf(child_status[i].reason,
+ 1024, "child %d (pid %u) failed: %s",
+ i, (unsigned)child_status[i].pid,
+ tctx->last_reason);
+ /* ensure proper "\n\0" termination: */
+ if (child_status[i].reason[1022] != '\0') {
+ child_status[i].reason[1022] = '\n';
+ child_status[i].reason[1023] = '\0';
+ }
+ }
_exit(0);
}
}
do {
synccount = 0;
for (i=0;i<torture_nprocs;i++) {
- if (child_status[i]) synccount++;
+ if (child_status[i].pid != 0) {
+ synccount++;
+ }
+ }
+ if (synccount == torture_nprocs) {
+ break;
}
- if (synccount == torture_nprocs) break;
smb_msleep(100);
} while (timeval_elapsed(&tv) < start_time_limit);
if (synccount != torture_nprocs) {
printf("FAILED TO START %d CLIENTS (started %d)\n", torture_nprocs, synccount);
+
+ /* cleanup child processes */
+ for (i = 0; i < torture_nprocs; i++) {
+ if (child_status[i].pid != 0) {
+ kill(child_status[i].pid, SIGTERM);
+ }
+ }
+
*result = false;
return timeval_elapsed(&tv);
}
/* start the client load */
tv = timeval_current();
for (i=0;i<torture_nprocs;i++) {
- child_status[i] = 0;
+ child_status[i].start = true;
}
printf("%d clients started\n", torture_nprocs);
}
printf("\n");
-
+
for (i=0;i<torture_nprocs;i++) {
- if (!child_status_out[i]) {
+ if (child_status[i].result != TORTURE_OK) {
*result = false;
+ torture_result(tctx, child_status[i].result,
+ "%s", child_status[i].reason);
}
}
+
return timeval_elapsed(&tv);
}
test->fn = run;
test->dangerous = false;
- DLIST_ADD_END(tcase->tests, test, struct torture_test *);
+ DLIST_ADD_END(tcase->tests, test);
return test;
{
bool (*fn) (struct torture_context *, struct smbcli_state *,
struct smbcli_state *);
- bool ret;
+ bool ret = true;
- struct smbcli_state *cli1, *cli2;
+ struct smbcli_state *cli1 = NULL, *cli2 = NULL;
- if (!torture_open_connection(&cli1, torture_ctx, 0) ||
- !torture_open_connection(&cli2, torture_ctx, 1))
- return false;
+ torture_assert_goto(torture_ctx, torture_open_connection(&cli1, torture_ctx, 0), ret, fail, "Failed to open connection");
+ torture_assert_goto(torture_ctx, torture_open_connection(&cli2, torture_ctx, 1), ret, fail, "Failed to open connection");
fn = test->fn;
ret = fn(torture_ctx, cli1, cli2);
-
+fail:
talloc_free(cli1);
talloc_free(cli2);
test->fn = run;
test->dangerous = false;
- DLIST_ADD_END(tcase->tests, test, struct torture_test *);
+ DLIST_ADD_END(tcase->tests, test);
return test;
struct torture_test *test)
{
bool (*fn) (struct torture_context *, struct smbcli_state *);
- bool ret;
+ bool ret = true;
- struct smbcli_state *cli1;
+ struct smbcli_state *cli1 = NULL;
- if (!torture_open_connection(&cli1, torture_ctx, 0))
- return false;
+ torture_assert_goto(torture_ctx, torture_open_connection(&cli1, torture_ctx, 0), ret, fail, "Failed to open connection");
fn = test->fn;
ret = fn(torture_ctx, cli1);
-
+fail:
talloc_free(cli1);
return ret;
test->fn = run;
test->dangerous = false;
- DLIST_ADD_END(tcase->tests, test, struct torture_test *);
+ DLIST_ADD_END(tcase->tests, test);
return test;
}
}
tcon.generic.level = RAW_TCON_TCONX;
- tcon.tconx.in.flags = 0;
+ tcon.tconx.in.flags = TCONX_FLAG_EXTENDED_RESPONSE;
+ tcon.tconx.in.flags |= TCONX_FLAG_EXTENDED_SIGNATURES;
/* Ignore share mode security here */
tcon.tconx.in.password = data_blob(NULL, 0);
}
result->tid = tcon.tconx.out.tid;
+
+ if (tcon.tconx.out.options & SMB_EXTENDED_SIGNATURES) {
+ smb1cli_session_protect_session_key(result->session->smbXcli);
+ }
+
*res = talloc_steal(mem_ctx, result);
talloc_free(tmp_ctx);
return NT_STATUS_OK;
}
status = dom_sid_split_rid(tmp_ctx, sid, NULL, &rid);
- NT_STATUS_NOT_OK_RETURN_AND_FREE(status, tmp_ctx);
+ if (!NT_STATUS_IS_OK(status)) {
+ TALLOC_FREE(tmp_ctx);
+ return status;
+ }
if (rid == DOMAIN_RID_ADMINISTRATOR) {
/* assume the administrator has them all */