signed DCERPC over TCP now works !
[jra/samba/.git] / source4 / torture / torture.c
index c928846f1f33566b8f52631c92599f791f5c7885..11b27f12ebfb227d7de37e4d0daea27c8be3ccb5 100644 (file)
@@ -26,7 +26,6 @@ int torture_entries=1000;
 int torture_failures=1;
 static int procnum; /* records process count number when forking */
 static struct cli_state *current_cli;
-static char *randomfname;
 static BOOL use_oplocks;
 static BOOL use_level_II_oplocks;
 static const char *client_txt = "client_oplocks.txt";
@@ -98,11 +97,11 @@ BOOL torture_open_connection(struct cli_state **c)
 
        if (use_kerberos)
                flags |= CLI_FULL_CONNECTION_USE_KERBEROS;
-       
+
        status = cli_full_connection(c, lp_netbios_name(),
                                     host, NULL, 
                                     share, "?????", 
-                                    username, lp_workgroup(), 
+                                    username, username[0]?lp_workgroup():"",
                                     password, flags, &retry);
        if (!NT_STATUS_IS_OK(status)) {
                printf("Failed to open connection - %s\n", nt_errstr(status));
@@ -131,6 +130,104 @@ BOOL torture_close_connection(struct cli_state *c)
        return ret;
 }
 
+/* open a rpc connection to a named pipe */
+static NTSTATUS torture_rpc_tcp(struct dcerpc_pipe **p, 
+                               const char *pipe_name,
+                               const char *pipe_uuid, 
+                               uint32 pipe_version)
+{
+        NTSTATUS status;
+       char *host = lp_parm_string(-1, "torture", "host");
+       const char *port = lp_parm_string(-1, "torture", "share");
+
+       DEBUG(2,("Connecting to dcerpc server %s:%s\n", host, port));
+
+       status = dcerpc_pipe_open_tcp(p, host, atoi(port));
+       if (!NT_STATUS_IS_OK(status)) {
+                printf("Open of pipe '%s' failed with error (%s)\n",
+                      pipe_name, nt_errstr(status));
+                return status;
+        }
+
+       /* always do NDR validation in smbtorture */
+       (*p)->flags |= DCERPC_DEBUG_VALIDATE_BOTH;
+
+       /* bind to the pipe, using the uuid as the key */
+       status = dcerpc_bind_auth_ntlm(*p, pipe_uuid, pipe_version,
+                                      lp_workgroup(),
+                                      lp_parm_string(-1, "torture", "username"),
+                                      lp_parm_string(-1, "torture", "password"));
+       if (!NT_STATUS_IS_OK(status)) {
+               dcerpc_pipe_close(*p);
+               return status;
+       }
+        return status;
+}
+
+
+/* open a rpc connection to a named pipe */
+NTSTATUS torture_rpc_connection(struct dcerpc_pipe **p, 
+                               const char *pipe_name,
+                               const char *pipe_uuid, 
+                               uint32 pipe_version)
+{
+        struct cli_state *cli;
+        NTSTATUS status;
+       char *transport = lp_parm_string(-1, "torture", "transport");
+
+       if (strcmp(transport, "ncacn_ip_tcp") == 0) {
+               return torture_rpc_tcp(p, pipe_name, pipe_uuid, pipe_version);
+       }
+
+       if (strcmp(transport, "ncacn_np") != 0) {
+               printf("Unsupported RPC transport '%s'\n", transport);
+               return NT_STATUS_UNSUCCESSFUL;
+       }
+
+       if (! *lp_parm_string(-1, "torture", "share")) {
+               lp_set_cmdline("torture:share", "ipc$");
+       }
+
+       if (!torture_open_connection(&cli)) {
+                return NT_STATUS_UNSUCCESSFUL;
+       }
+
+       status = dcerpc_pipe_open_smb(p, cli->tree, pipe_name);
+       if (!NT_STATUS_IS_OK(status)) {
+                printf("Open of pipe '%s' failed with error (%s)\n",
+                      pipe_name, nt_errstr(status));
+               torture_close_connection(cli);
+                return status;
+        }
+
+       /* bind to the pipe, using the uuid as the key */
+#if 1
+       status = dcerpc_bind_auth_ntlm(*p, pipe_uuid, pipe_version,
+                                      lp_workgroup(),
+                                      lp_parm_string(-1, "torture", "username"),
+                                      lp_parm_string(-1, "torture", "password"));
+#else
+       status = dcerpc_bind_auth_none(*p, pipe_uuid, pipe_version);
+#endif
+       if (!NT_STATUS_IS_OK(status)) {
+               dcerpc_pipe_close(*p);
+               return status;
+       }
+
+       /* always do NDR validation in smbtorture */
+       (*p)->flags |= DCERPC_DEBUG_VALIDATE_BOTH;
+        return status;
+}
+
+/* close a rpc connection to a named pipe */
+NTSTATUS torture_rpc_close(struct dcerpc_pipe *p)
+{
+       dcerpc_pipe_close(p);
+       return NT_STATUS_OK;
+}
+
 
 /* check if the server produced the expected error code */
 static BOOL check_error(int line, struct cli_state *c, 
@@ -285,7 +382,7 @@ static BOOL run_torture(int dummy)
        return ret;
 }
 
-static BOOL rw_torture3(struct cli_state *c, char *lockfname)
+static BOOL rw_torture3(struct cli_state *c, const char *lockfname)
 {
        int fnum = -1;
        unsigned int i = 0;
@@ -503,8 +600,7 @@ static BOOL run_readwritemulti(int dummy)
 
        cli = current_cli;
 
-       printf("run_readwritemulti: fname %s\n", randomfname);
-       test = rw_torture3(cli, randomfname);
+       test = rw_torture3(cli, "\\multitest.txt");
 
        if (!torture_close_connection(cli)) {
                test = False;
@@ -2777,7 +2873,7 @@ static BOOL run_rename(int dummy)
 static BOOL run_pipe_number(int dummy)
 {
        struct cli_state *cli1;
-       const char *pipe_name = "\\SPOOLSS";
+       const char *pipe_name = "\\WKSSVC";
        int fnum;
        int num_pipes = 0;
 
@@ -3607,9 +3703,6 @@ BOOL torture_chkpath_test(int dummy)
        return ret;
 }
 
-
-
-
 static BOOL run_dirtest1(int dummy)
 {
        int i;
@@ -3758,6 +3851,9 @@ static BOOL run_deny3test(int dummy)
        return True;
 }
 
+static void sigcont(void)
+{
+}
 
 static double create_procs(BOOL (*fn)(int), BOOL *result)
 {
@@ -3766,9 +3862,12 @@ static double create_procs(BOOL (*fn)(int), BOOL *result)
        volatile BOOL *child_status_out;
        int synccount;
        int tries = 8;
+       double start_time_limit = 10 + (nprocs * 1.5);
 
        synccount = 0;
 
+       signal(SIGCONT, sigcont);
+
        child_status = (volatile pid_t *)shm_setup(sizeof(pid_t)*nprocs);
        if (!child_status) {
                printf("Failed to setup shared memory\n");
@@ -3805,12 +3904,18 @@ static double create_procs(BOOL (*fn)(int), BOOL *result)
                                        printf("pid %d failed to start\n", (int)getpid());
                                        _exit(1);
                                }
-                               msleep(10);     
+                               msleep(100);    
                        }
 
                        child_status[i] = getpid();
 
-                       while (child_status[i] && end_timer() < 5) msleep(2);
+                       pause();
+
+                       if (child_status[i]) {
+                               printf("Child %d failed to start!\n", i);
+                               child_status_out[i] = 1;
+                               _exit(1);
+                       }
 
                        child_status_out[i] = fn(i);
                        _exit(0);
@@ -3823,8 +3928,8 @@ static double create_procs(BOOL (*fn)(int), BOOL *result)
                        if (child_status[i]) synccount++;
                }
                if (synccount == nprocs) break;
-               msleep(10);
-       } while (end_timer() < 30);
+               msleep(100);
+       } while (end_timer() < start_time_limit);
 
        if (synccount != nprocs) {
                printf("FAILED TO START %d CLIENTS (started %d)\n", nprocs, synccount);
@@ -3832,17 +3937,23 @@ static double create_procs(BOOL (*fn)(int), BOOL *result)
                return end_timer();
        }
 
+       printf("Starting %d clients\n", nprocs);
+
        /* start the client load */
        start_timer();
-
        for (i=0;i<nprocs;i++) {
                child_status[i] = 0;
        }
+       kill(0, SIGCONT);
 
        printf("%d clients started\n", nprocs);
 
        for (i=0;i<nprocs;i++) {
-               while (waitpid(0, &status, 0) == -1 && errno == EINTR) /* noop */ ;
+               int ret;
+               while ((ret=waitpid(0, &status, 0)) == -1 && errno == EINTR) /* noop */ ;
+               if (ret == -1 || WEXITSTATUS(status) != 0) {
+                       *result = False;
+               }
        }
 
        printf("\n");
@@ -3929,6 +4040,18 @@ static struct {
        {"SCAN-NTTRANS", torture_nttrans_scan, 0},
        {"SCAN-ALIASES", torture_trans2_aliases, 0},
        {"SCAN-SMB", torture_smb_scan, 0},
+        {"RPC-LSA", torture_rpc_lsa, 0},
+        {"RPC-ECHO", torture_rpc_echo, 0},
+        {"RPC-DFS", torture_rpc_dfs, 0},
+        {"RPC-SPOOLSS", torture_rpc_spoolss, 0},
+        {"RPC-SAMR", torture_rpc_samr, 0},
+        {"RPC-WKSSVC", torture_rpc_wkssvc, 0},
+        {"RPC-SRVSVC", torture_rpc_srvsvc, 0},
+        {"RPC-ATSVC", torture_rpc_atsvc, 0},
+        {"RPC-EVENTLOG", torture_rpc_eventlog, 0},
+        {"RPC-EPMAPPER", torture_rpc_epmapper, 0},
+        {"RPC-WINREG", torture_rpc_winreg, 0},
+        {"RPC-MGMT", torture_rpc_mgmt, 0},
        {NULL, NULL, 0}};
 
 
@@ -3952,9 +4075,6 @@ static BOOL run_test(const char *name)
        }
 
        for (i=0;torture_ops[i].name;i++) {
-               asprintf(&randomfname, "\\XX%x", 
-                        (unsigned)random());
-
                if (gen_fnmatch(name, torture_ops[i].name) == 0) {
                        double t;
                        matched = True;
@@ -4068,27 +4188,50 @@ static void usage(void)
         for(p = argv[1]; *p; p++)
           if(*p == '\\')
             *p = '/';
-       if (strncmp(argv[1], "//", 2)) {
-               usage();
-       }
 
-       host = strdup(&argv[1][2]);
-       p = strchr_m(&host[2],'/');
-       if (!p) {
-               usage();
+
+       /* see if its a RPC transport specifier */
+       if (strncmp(argv[1], "ncacn", 5) == 0) {
+               char *transport = strdup(argv[1]);
+               p = strchr_m(transport, ':');
+               if (!p) usage();
+               *p = 0;
+               host = p+1;
+               p = strchr_m(host, ':');
+               if (p) {
+                       *p = 0;
+                       share = p+1;
+                       lp_set_cmdline("torture:share", share);
+               } else {
+                       share = "";
+                       lp_set_cmdline("torture:share", share);
+               }
+               lp_set_cmdline("torture:host", host);
+               lp_set_cmdline("torture:transport", transport);
+       } else {
+               if (strncmp(argv[1], "//", 2)) {
+                       usage();
+               }
+
+               host = strdup(&argv[1][2]);
+               p = strchr_m(&host[2],'/');
+               if (!p) {
+                       usage();
+               }
+               *p = 0;
+               share = strdup(p+1);
+               
+               lp_set_cmdline("torture:host", host);
+               lp_set_cmdline("torture:share", share);
+               lp_set_cmdline("torture:password", "");
+               lp_set_cmdline("torture:transport", "ncacn_np");
        }
-       *p = 0;
-       share = strdup(p+1);
 
        if (getenv("LOGNAME")) {
                username = strdup(getenv("LOGNAME"));
        }
-
-       lp_set_cmdline("torture:host", host);
-       lp_set_cmdline("torture:share", share);
        lp_set_cmdline("torture:username", username);
-       lp_set_cmdline("torture:password", "");
+
 
        argc--;
        argv++;