r1481: add idl file and torture test dummies
[samba.git] / source4 / torture / torture.c
index 5caabc87ed5fc1fc27cd06c3e684de1f2d2777c8..8f72b63e6cb1ea317e8e5698b7f49270845b0ec8 100644 (file)
@@ -39,7 +39,7 @@ static struct cli_state *open_nbt_connection(void)
        struct nmb_name called, calling;
        struct in_addr ip;
        struct cli_state *cli;
-       char *host = lp_parm_string(-1, "torture", "host");
+       const char *host = lp_parm_string(-1, "torture", "host");
 
        make_nmb_name(&calling, lp_netbios_name(), 0x0);
        make_nmb_name(&called , host, 0x20);
@@ -89,8 +89,8 @@ BOOL torture_open_connection_share(struct cli_state **c,
        BOOL retry;
        int flags = 0;
        NTSTATUS status;
-       char *username = lp_parm_string(-1, "torture", "username");
-       char *password = lp_parm_string(-1, "torture", "password");
+       const char *username = lp_parm_string(-1, "torture", "username");
+       const char *password = lp_parm_string(-1, "torture", "password");
 
        if (use_kerberos)
                flags |= CLI_FULL_CONNECTION_USE_KERBEROS;
@@ -114,8 +114,8 @@ BOOL torture_open_connection_share(struct cli_state **c,
 
 BOOL torture_open_connection(struct cli_state **c)
 {
-       char *host = lp_parm_string(-1, "torture", "host");
-       char *share = lp_parm_string(-1, "torture", "share");
+       const char *host = lp_parm_string(-1, "torture", "host");
+       const char *share = lp_parm_string(-1, "torture", "share");
 
        return torture_open_connection_share(c, host, share);
 }
@@ -142,10 +142,10 @@ BOOL torture_close_connection(struct cli_state *c)
 NTSTATUS torture_rpc_connection(struct dcerpc_pipe **p, 
                                const char *pipe_name,
                                const char *pipe_uuid, 
-                               uint32 pipe_version)
+                               uint32_t pipe_version)
 {
         NTSTATUS status;
-       char *binding = lp_parm_string(-1, "torture", "binding");
+       const char *binding = lp_parm_string(-1, "torture", "binding");
 
        if (!binding) {
                printf("You must specify a ncacn binding string\n");
@@ -170,11 +170,11 @@ NTSTATUS torture_rpc_close(struct dcerpc_pipe *p)
 
 /* check if the server produced the expected error code */
 static BOOL check_error(int line, struct cli_state *c, 
-                       uint8 eclass, uint32 ecode, NTSTATUS nterr)
+                       uint8_t eclass, uint32_t ecode, NTSTATUS nterr)
 {
         if (cli_is_dos_error(c->tree)) {
-                uint8 class;
-                uint32 num;
+                uint8_t class;
+                uint32_t num;
 
                 /* Check DOS error */
 
@@ -206,7 +206,7 @@ static BOOL check_error(int line, struct cli_state *c,
 }
 
 
-static BOOL wait_lock(struct cli_state *c, int fnum, uint32 offset, uint32 len)
+static BOOL wait_lock(struct cli_state *c, int fnum, uint32_t offset, uint32_t len)
 {
        while (NT_STATUS_IS_ERR(cli_lock(c->tree, fnum, offset, len, -1, WRITE_LOCK))) {
                if (!check_error(__LINE__, c, ERRDOS, ERRlock, NT_STATUS_LOCK_NOT_GRANTED)) return False;
@@ -237,7 +237,7 @@ static BOOL rw_torture(struct cli_state *c)
 
 
        for (i=0;i<torture_numops;i++) {
-               unsigned n = (unsigned)sys_random()%10;
+               uint_t n = (uint_t)sys_random()%10;
                if (i % 10 == 0) {
                        printf("%d\r", i); fflush(stdout);
                }
@@ -321,16 +321,16 @@ static BOOL run_torture(struct cli_state *cli, int dummy)
 static BOOL rw_torture3(struct cli_state *c, const char *lockfname)
 {
        int fnum = -1;
-       unsigned int i = 0;
+       uint_t i = 0;
        char buf[131072];
        char buf_rd[131072];
-       unsigned count;
-       unsigned countprev = 0;
+       uint_t count;
+       uint_t countprev = 0;
        ssize_t sent = 0;
        BOOL correct = True;
 
        srandom(1);
-       for (i = 0; i < sizeof(buf); i += sizeof(uint32))
+       for (i = 0; i < sizeof(buf); i += sizeof(uint32_t))
        {
                SIVAL(buf, i, sys_random());
        }
@@ -372,7 +372,7 @@ static BOOL rw_torture3(struct cli_state *c, const char *lockfname)
 
                if (procnum == 0)
                {
-                       sent = ((unsigned)sys_random()%(20))+ 1;
+                       sent = ((uint_t)sys_random()%(20))+ 1;
                        if (sent > sizeof(buf) - count)
                        {
                                sent = sizeof(buf) - count;
@@ -424,8 +424,8 @@ static BOOL rw_torture2(struct cli_state *c1, struct cli_state *c2)
        int fnum1;
        int fnum2;
        int i;
-       uchar buf[131072];
-       uchar buf_rd[131072];
+       uint8_t buf[131072];
+       uint8_t buf_rd[131072];
        BOOL correct = True;
        ssize_t bytes_read, bytes_written;
 
@@ -453,7 +453,7 @@ static BOOL rw_torture2(struct cli_state *c1, struct cli_state *c2)
 
        for (i=0;i<torture_numops;i++)
        {
-               size_t buf_size = ((unsigned)sys_random()%(sizeof(buf)-1))+ 1;
+               size_t buf_size = ((uint_t)sys_random()%(sizeof(buf)-1))+ 1;
                if (i % 10 == 0) {
                        printf("%d\r", i); fflush(stdout);
                }
@@ -556,7 +556,7 @@ static BOOL run_locktest1(int dummy)
        const char *fname = "\\lockt1.lck";
        int fnum1, fnum2, fnum3;
        time_t t1, t2;
-       unsigned lock_timeout;
+       uint_t lock_timeout;
 
        if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) {
                return False;
@@ -613,7 +613,7 @@ static BOOL run_locktest1(int dummy)
                printf("error: This server appears not to support timed lock requests\n");
        }
        printf("server slept for %u seconds for a %u second timeout\n",
-              (unsigned int)(t2-t1), lock_timeout);
+              (uint_t)(t2-t1), lock_timeout);
 
        if (NT_STATUS_IS_ERR(cli_close(cli1->tree, fnum2))) {
                printf("close1 failed (%s)\n", cli_errstr(cli1->tree));
@@ -665,14 +665,14 @@ static BOOL run_tcon_test(int dummy)
        struct cli_state *cli;
        const char *fname = "\\tcontest.tmp";
        int fnum1;
-       uint16 cnum1, cnum2, cnum3;
-       uint16 vuid1, vuid2;
+       uint16_t cnum1, cnum2, cnum3;
+       uint16_t vuid1, vuid2;
        char buf[4];
        BOOL ret = True;
        struct cli_tree *tree1;
-       char *host = lp_parm_string(-1, "torture", "host");
-       char *share = lp_parm_string(-1, "torture", "share");
-       char *password = lp_parm_string(-1, "torture", "password");
+       const char *host = lp_parm_string(-1, "torture", "host");
+       const char *share = lp_parm_string(-1, "torture", "share");
+       const char *password = lp_parm_string(-1, "torture", "password");
 
        if (!torture_open_connection(&cli)) {
                return False;
@@ -776,7 +776,7 @@ static BOOL tcon_devtest(struct cli_state *cli,
 {
        BOOL status;
        BOOL ret;
-       char *password = lp_parm_string(-1, "torture", "password");
+       const char *password = lp_parm_string(-1, "torture", "password");
 
        status = NT_STATUS_IS_OK(cli_send_tconX(cli, myshare, devtype, 
                                                password));
@@ -822,10 +822,10 @@ static BOOL run_tcon_devtype_test(int dummy)
        int flags = 0;
        NTSTATUS status;
        BOOL ret = True;
-       char *host = lp_parm_string(-1, "torture", "host");
-       char *share = lp_parm_string(-1, "torture", "share");
-       char *username = lp_parm_string(-1, "torture", "username");
-       char *password = lp_parm_string(-1, "torture", "password");
+       const char *host = lp_parm_string(-1, "torture", "host");
+       const char *share = lp_parm_string(-1, "torture", "share");
+       const char *username = lp_parm_string(-1, "torture", "username");
+       const char *password = lp_parm_string(-1, "torture", "password");
        
        status = cli_full_connection(&cli1, lp_netbios_name(),
                                     host, NULL, 
@@ -1031,10 +1031,10 @@ static BOOL run_locktest3(int dummy)
        struct cli_state *cli1, *cli2;
        const char *fname = "\\lockt3.lck";
        int fnum1, fnum2, i;
-       uint32 offset;
+       uint32_t offset;
        BOOL correct = True;
 
-#define NEXT_OFFSET offset += (~(uint32)0) / torture_numops
+#define NEXT_OFFSET offset += (~(uint32_t)0) / torture_numops
 
        if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) {
                return False;
@@ -1489,6 +1489,8 @@ static BOOL run_locktest7(int dummy)
        struct cli_state *cli1;
        const char *fname = "\\lockt7.lck";
        int fnum1;
+       int fnum2;
+       size_t size;
        char buf[200];
        BOOL correct = False;
 
@@ -1603,11 +1605,38 @@ static BOOL run_locktest7(int dummy)
                goto fail;
        }
 
-       cli_unlock(cli1->tree, fnum1, 130, 0);
+       printf("Testing truncate of locked file.\n");
+
+       fnum2 = cli_open(cli1->tree, fname, O_RDWR|O_TRUNC, DENY_NONE);
+
+       if (fnum2 == -1) {
+               printf("Unable to truncate locked file.\n");
+               correct = False;
+               goto fail;
+       } else {
+               printf("Truncated locked file.\n");
+       }
+
+       if (NT_STATUS_IS_ERR(cli_getatr(cli1->tree, fname, NULL, &size, NULL))) {
+               printf("getatr failed (%s)\n", cli_errstr(cli1->tree));
+               correct = False;
+               goto fail;
+       }
+
+       if (size != 0) {
+               printf("Unable to truncate locked file. Size was %u\n", size);
+               correct = False;
+               goto fail;
+       }
+
+       cli1->session->pid = 1;
+
+       cli_unlock(cli1->tree, fnum1, 130, 4);
        correct = True;
 
 fail:
        cli_close(cli1->tree, fnum1);
+       cli_close(cli1->tree, fnum2);
        cli_unlink(cli1->tree, fname);
        torture_close_connection(cli1);
 
@@ -1728,6 +1757,79 @@ static BOOL run_unlinktest(int dummy)
 }
 
 
+/*
+test how many open files this server supports on the one socket
+*/
+
+static BOOL run_deferopen(struct cli_state *cli, int dummy)
+{
+       const char *fname = "\\defer_open_test.dat";
+       int retries=4;
+       int i = 0;
+       BOOL correct = True;
+
+       if (retries <= 0) {
+               printf("failed to connect\n");
+               return False;
+       }
+
+       printf("Testing deferred open requests.\n");
+
+       while (i < 4) {
+               int fnum = -1;
+
+               do {
+                       struct timeval tv_start, tv_end;
+                       GetTimeOfDay(&tv_start);
+                       fnum = cli_nt_create_full(cli->tree, fname, 0, GENERIC_RIGHTS_FILE_ALL_ACCESS,
+                               FILE_ATTRIBUTE_NORMAL, NTCREATEX_SHARE_ACCESS_NONE,
+                               NTCREATEX_DISP_OPEN_IF, 0, 0);
+                       if (fnum != -1) {
+                               break;
+                       }
+                       GetTimeOfDay(&tv_end);
+                       if (NT_STATUS_EQUAL(cli_nt_error(cli->tree),NT_STATUS_SHARING_VIOLATION)) {
+                               /* Sharing violation errors need to be 1 second apart. */
+                               int64_t tdif = usec_time_diff(&tv_end, &tv_start);
+                               if (tdif < 500000 || tdif > 1500000) {
+                                       fprintf(stderr,"Timing incorrect %lld.%lld for share violation\n",
+                                               tdif / (int64_t)1000000, 
+                                               tdif % (int64_t)1000000);
+                               }
+                       }
+               } while (NT_STATUS_EQUAL(cli_nt_error(cli->tree),NT_STATUS_SHARING_VIOLATION));
+
+               if (fnum == -1) {
+                       fprintf(stderr,"Failed to open %s, error=%s\n", fname, cli_errstr(cli->tree));
+                       return False;
+               }
+
+               printf("pid %u open %d\n", getpid(), i);
+
+               sleep(10);
+               i++;
+               if (NT_STATUS_IS_ERR(cli_close(cli->tree, fnum))) {
+                       fprintf(stderr,"Failed to close %s, error=%s\n", fname, cli_errstr(cli->tree));
+                       return False;
+               }
+               sleep(2);
+       }
+
+       if (NT_STATUS_IS_ERR(cli_unlink(cli->tree, fname))) {
+               /* All until the last unlink will fail with sharing violation. */
+               if (!NT_STATUS_EQUAL(cli_nt_error(cli->tree),NT_STATUS_SHARING_VIOLATION)) {
+                       printf("unlink of %s failed (%s)\n", fname, cli_errstr(cli->tree));
+                       correct = False;
+               }
+       }
+
+       printf("deferred test finished\n");
+       if (!torture_close_connection(cli)) {
+               correct = False;
+       }
+       return correct;
+}
+
 /*
 test how many open files this server supports on the one socket
 */
@@ -2756,7 +2858,72 @@ static BOOL run_pipe_number(int dummy)
        return True;
 }
 
+/*
+  Try with a wrong vuid and check error message.
+ */
+
+static BOOL run_vuidtest(int dummy)
+{
+       struct cli_state *cli;
+       const char *fname = "\\vuid.tst";
+       int fnum;
+       size_t size;
+       time_t c_time, a_time, m_time;
+       BOOL correct = True;
+
+       uint16_t orig_vuid;
+       NTSTATUS result;
+
+       printf("starting vuid test\n");
+
+       if (!torture_open_connection(&cli)) {
+               return False;
+       }
+
+       cli_unlink(cli->tree, fname);
+
+       fnum = cli_open(cli->tree, fname, 
+                       O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
+
+       orig_vuid = cli->session->vuid;
+
+       cli->session->vuid += 1234;
+
+       printf("Testing qfileinfo with wrong vuid\n");
+       
+       if (NT_STATUS_IS_OK(result = cli_qfileinfo(cli->tree, fnum, NULL,
+                                                  &size, &c_time, &a_time,
+                                                  &m_time, NULL, NULL))) {
+               printf("ERROR: qfileinfo passed with wrong vuid\n");
+               correct = False;
+       }
+
+       if ( (cli->transport->error.etype != ETYPE_DOS) ||
+            (cli->transport->error.e.dos.eclass != ERRSRV) ||
+            (cli->transport->error.e.dos.ecode != ERRbaduid) ) {
+               printf("ERROR: qfileinfo should have returned DOS error "
+                      "ERRSRV:ERRbaduid\n  but returned %s\n",
+                      cli_errstr(cli->tree));
+               correct = False;
+       }
+
+       cli->session->vuid -= 1234;
+
+       if (NT_STATUS_IS_ERR(cli_close(cli->tree, fnum))) {
+               printf("close failed (%s)\n", cli_errstr(cli->tree));
+               correct = False;
+       }
+
+       cli_unlink(cli->tree, fname);
+
+       if (!torture_close_connection(cli)) {
+               correct = False;
+       }
 
+       printf("vuid test finished\n");
+
+       return correct;
+}
 
 /*
   Test open mode returns on read-only files.
@@ -3160,7 +3327,81 @@ error_test60:
        }
 
        printf("non-io open test #7 passed.\n");
+
 error_test70:
+
+       printf("TEST #8 testing one normal open, followed by lock, followed by open with truncate\n");
+
+       cli_unlink(cli1->tree, fname);
+
+       fnum1 = cli_open(cli1->tree, fname, O_RDWR|O_CREAT, DENY_NONE);
+       if (fnum1 == -1) {
+               printf("(8) open (1) of %s failed (%s)\n", fname, cli_errstr(cli1->tree));
+               return False;
+       }
+       
+       /* write 20 bytes. */
+       
+       memset(buf, '\0', 20);
+
+       if (cli_write(cli1->tree, fnum1, 0, buf, 0, 20) != 20) {
+               printf("(8) write failed (%s)\n", cli_errstr(cli1->tree));
+               correct = False;
+       }
+
+       /* Ensure size == 20. */
+       if (NT_STATUS_IS_ERR(cli_getatr(cli1->tree, fname, NULL, &fsize, NULL))) {
+               printf("(8) getatr (1) failed (%s)\n", cli_errstr(cli1->tree));
+               CHECK_MAX_FAILURES(error_test80);
+               return False;
+       }
+       
+       if (fsize != 20) {
+               printf("(8) file size != 20\n");
+               CHECK_MAX_FAILURES(error_test80);
+               return False;
+       }
+
+       /* Get an exclusive lock on the open file. */
+       if (NT_STATUS_IS_ERR(cli_lock(cli1->tree, fnum1, 0, 4, 0, WRITE_LOCK))) {
+               printf("(8) lock1 failed (%s)\n", cli_errstr(cli1->tree));
+               CHECK_MAX_FAILURES(error_test80);
+               return False;
+       }
+
+       fnum2 = cli_open(cli1->tree, fname, O_RDWR|O_TRUNC, DENY_NONE);
+       if (fnum1 == -1) {
+               printf("(8) open (2) of %s with truncate failed (%s)\n", fname, cli_errstr(cli1->tree));
+               return False;
+       }
+
+       /* Ensure size == 0. */
+       if (NT_STATUS_IS_ERR(cli_getatr(cli1->tree, fname, NULL, &fsize, NULL))) {
+               printf("(8) getatr (2) failed (%s)\n", cli_errstr(cli1->tree));
+               CHECK_MAX_FAILURES(error_test80);
+               return False;
+       }
+       
+       if (fsize != 0) {
+               printf("(8) file size != 0\n");
+               CHECK_MAX_FAILURES(error_test80);
+               return False;
+       }
+
+       if (NT_STATUS_IS_ERR(cli_close(cli1->tree, fnum1))) {
+               printf("(8) close1 failed (%s)\n", cli_errstr(cli1->tree));
+               return False;
+       }
+       
+       if (NT_STATUS_IS_ERR(cli_close(cli1->tree, fnum2))) {
+               printf("(8) close1 failed (%s)\n", cli_errstr(cli1->tree));
+               return False;
+       }
+       
+error_test80:
+
+       printf("open test #8 passed.\n");
+
        cli_unlink(cli1->tree, fname);
 
        if (!torture_close_connection(cli1)) {
@@ -3174,7 +3415,7 @@ error_test70:
 }
 
 
-static uint32 open_attrs_table[] = {
+static uint32_t open_attrs_table[] = {
                FILE_ATTRIBUTE_NORMAL,
                FILE_ATTRIBUTE_ARCHIVE,
                FILE_ATTRIBUTE_READONLY,
@@ -3195,10 +3436,10 @@ static uint32 open_attrs_table[] = {
 };
 
 struct trunc_open_results {
-       unsigned int num;
-       uint32 init_attr;
-       uint32 trunc_attr;
-       uint32 result_attr;
+       uint_t num;
+       uint32_t init_attr;
+       uint32_t trunc_attr;
+       uint32_t result_attr;
 };
 
 static struct trunc_open_results attr_results[] = {
@@ -3236,8 +3477,8 @@ static BOOL run_openattrtest(int dummy)
        const char *fname = "\\openattr.file";
        int fnum1;
        BOOL correct = True;
-       uint16 attr;
-       unsigned int i, j, k, l;
+       uint16_t attr;
+       uint_t i, j, k, l;
        int failures = 0;
 
        printf("starting open attr test\n");
@@ -3246,7 +3487,7 @@ static BOOL run_openattrtest(int dummy)
                return False;
        }
        
-       for (k = 0, i = 0; i < sizeof(open_attrs_table)/sizeof(uint32); i++) {
+       for (k = 0, i = 0; i < sizeof(open_attrs_table)/sizeof(uint32_t); i++) {
                cli_setatr(cli1->tree, fname, 0, 0);
                cli_unlink(cli1->tree, fname);
                fnum1 = cli_nt_create_full(cli1->tree, fname, 0, SA_RIGHT_FILE_WRITE_DATA, open_attrs_table[i],
@@ -3317,7 +3558,7 @@ static BOOL run_openattrtest(int dummy)
                                                printf("[%d] getatr check failed. [0x%x] trunc [0x%x] got attr 0x%x, should be 0x%x\n",
                                                        k, open_attrs_table[i],
                                                        open_attrs_table[j],
-                                                       (unsigned int)attr,
+                                                       (uint_t)attr,
                                                        attr_results[l].result_attr);
                                                correct = False;
                                                CHECK_MAX_FAILURES(error_exit);
@@ -3428,7 +3669,7 @@ static void del_fn(file_info *finfo, const char *mask, void *state)
 BOOL torture_ioctl_test(int dummy)
 {
        struct cli_state *cli;
-       uint16 device, function;
+       uint16_t device, function;
        int fnum;
        const char *fname = "\\ioctl.dat";
        NTSTATUS status;
@@ -3746,7 +3987,7 @@ double torture_create_procs(BOOL (*fn)(struct cli_state *, int), BOOL *result)
        int tries = 8;
        double start_time_limit = 10 + (torture_nprocs * 1.5);
        char **unc_list = NULL;
-       char *p;
+       const char *p;
        int num_unc_names = 0;
 
        synccount = 0;
@@ -3885,7 +4126,7 @@ double torture_create_procs(BOOL (*fn)(struct cli_state *, int), BOOL *result)
 static struct {
        const char *name;
        BOOL (*fn)(int);
-       unsigned flags;
+       uint_t flags;
 } torture_ops[] = {
        {"FDPASS", run_fdpasstest, 0},
        {"LOCK1",  run_locktest1,  0},
@@ -3908,6 +4149,7 @@ static struct {
        {"DENY2",  torture_denytest2, 0},
        {"TCON",  run_tcon_test, 0},
        {"TCONDEV",  run_tcon_devtype_test, 0},
+       {"VUID", run_vuidtest, 0},
 #if 0
        {"DFSBASIC", torture_dfs_basic, 0},
        {"DFSRENAME", torture_dfs_rename, 0},
@@ -3920,6 +4162,7 @@ static struct {
 #if 1
        {"OPENATTR", run_openattrtest, 0},
 #endif
+       {"DEFER_OPEN", run_deferopen, FLAG_MULTIPROC},
        {"XCOPY", run_xcopy, 0},
        {"RENAME", run_rename, 0},
        {"DELETE", run_deletetest, 0},
@@ -3927,6 +4170,7 @@ static struct {
        {"MANGLE", torture_mangle, 0},
        {"UTABLE", torture_utable, 0},
        {"CASETABLE", torture_casetable, 0},
+       {"CHARSET", torture_charset, 0},
        {"PIPE_NUMBER", run_pipe_number, 0},
        {"IOCTL",  torture_ioctl_test, 0},
        {"CHKPATH",  torture_chkpath_test, 0},
@@ -3951,6 +4195,7 @@ static struct {
        {"RAW-CONTEXT", torture_raw_context, 0},
        {"RAW-RENAME", torture_raw_rename, 0},
        {"RAW-SEEK", torture_raw_seek, 0},
+       {"RAW-RAP", torture_raw_rap, 0},
        {"SCAN-TRANS2", torture_trans2_scan, 0},
        {"SCAN-NTTRANS", torture_nttrans_scan, 0},
        {"SCAN-ALIASES", torture_trans2_aliases, 0},
@@ -3961,6 +4206,7 @@ static struct {
         {"RPC-SPOOLSS", torture_rpc_spoolss, 0},
         {"RPC-SAMR", torture_rpc_samr, 0},
         {"RPC-NETLOGON", torture_rpc_netlogon, 0},
+        {"RPC-SCHANNEL", torture_rpc_schannel, 0},
         {"RPC-WKSSVC", torture_rpc_wkssvc, 0},
         {"RPC-SRVSVC", torture_rpc_srvsvc, 0},
         {"RPC-ATSVC", torture_rpc_atsvc, 0},
@@ -3970,6 +4216,9 @@ static struct {
         {"RPC-MGMT", torture_rpc_mgmt, 0},
         {"RPC-SCANNER", torture_rpc_scanner, 0},
         {"RPC-AUTOIDL", torture_rpc_autoidl, 0},
+       {"RPC-MULTIBIND", torture_multi_bind, 0},
+       {"RPC-DRSUAPI", torture_rpc_drsuapi, 0},
+       {"NTLMSSP-SELFCHECK", torture_ntlmssp_self_check, 0},
        {NULL, NULL, 0}};
 
 
@@ -4030,7 +4279,7 @@ static BOOL run_test(const char *name)
 */
 static void parse_user(const char *user)
 {
-       char *username, *password, *p;
+       char *username, *password = NULL, *p;
 
        username = strdup(user);
        p = strchr_m(username,'%');
@@ -4040,9 +4289,17 @@ static void parse_user(const char *user)
        }
 
        lp_set_cmdline("torture:username", username);
-       lp_set_cmdline("torture:password", password);
-}
 
+       if (password) {
+               lp_set_cmdline("torture:password", password);
+       }
+
+       if (!lp_parm_string(-1,"torture","password")) {
+               password = getpass("password:");
+
+               lp_set_cmdline("torture:password", password);
+       }
+}
 
 static void usage(void)
 {
@@ -4068,7 +4325,7 @@ static void usage(void)
        printf("\t-p port\n");
        printf("\t-s seed\n");
        printf("\t-f max failures\n");
-       printf("\t-b bypass I/O (NBENCH)\n");
+       printf("\t-X enable dangerous tests\n");
        printf("\n\n");
 
        printf("tests are:");
@@ -4122,7 +4379,6 @@ static void usage(void)
 
                lp_set_cmdline("torture:host", host);
                lp_set_cmdline("torture:share", share);
-               lp_set_cmdline("torture:password", "");
                asprintf(&binding, "ncacn_np:%s", host);
                lp_set_cmdline("torture:binding", binding);
        }
@@ -4138,7 +4394,7 @@ static void usage(void)
 
        srandom(time(NULL));
 
-       while ((opt = getopt(argc, argv, "p:hW:U:n:N:O:o:e:m:Ld:Ac:ks:f:s:t:C:")) != EOF) {
+       while ((opt = getopt(argc, argv, "p:hW:U:n:N:O:o:e:m:Ld:Ac:ks:f:s:t:C:X")) != EOF) {
                switch (opt) {
                case 'p':
                        lp_set_cmdline("smb ports", optarg);
@@ -4201,12 +4457,20 @@ static void usage(void)
                        torture_failures = atoi(optarg);
                        break;
 
+               case 'X':
+                       lp_set_cmdline("torture:dangerous", "1");
+                       break;
+
                default:
                        printf("Unknown option %c (%d)\n", (char)opt, opt);
                        usage();
                }
        }
 
+       if (!lp_parm_string(-1,"torture","password")) {
+               lp_set_cmdline("torture:password", "");
+       }
+
        if (argc == optind) {
                printf("You must specify a test to run, or 'ALL'\n");
        } else {