Add a test showing what ascii values cause an NTFS volume to
[ira/wip.git] / source3 / torture / torture.c
index c9199eb36fd01ca3311f1412d6304fa8b82fe0ff..99bf3785b6967912bb47eaa7b4a10441edfa6d96 100644 (file)
@@ -2471,7 +2471,7 @@ static bool run_attrtest(int dummy)
        cli_open(cli, fname, 
                        O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
        cli_close(cli, fnum);
-       if (!cli_getatr(cli, fname, NULL, NULL, &t)) {
+       if (!NT_STATUS_IS_OK(cli_getatr(cli, fname, NULL, NULL, &t))) {
                printf("getatr failed (%s)\n", cli_errstr(cli));
                correct = False;
        }
@@ -2485,12 +2485,12 @@ static bool run_attrtest(int dummy)
 
        t2 = t-60*60*24; /* 1 day ago */
 
-       if (!cli_setatr(cli, fname, 0, t2)) {
+       if (!NT_STATUS_IS_OK(cli_setatr(cli, fname, 0, t2))) {
                printf("setatr failed (%s)\n", cli_errstr(cli));
                correct = True;
        }
 
-       if (!cli_getatr(cli, fname, NULL, NULL, &t)) {
+       if (!NT_STATUS_IS_OK(cli_getatr(cli, fname, NULL, NULL, &t))) {
                printf("getatr failed (%s)\n", cli_errstr(cli));
                correct = True;
        }
@@ -3726,7 +3726,7 @@ static bool run_opentest(int dummy)
                return False;
        }
 
-       if (!cli_setatr(cli1, fname, aRONLY, 0)) {
+       if (!NT_STATUS_IS_OK(cli_setatr(cli1, fname, aRONLY, 0))) {
                printf("cli_setatr failed (%s)\n", cli_errstr(cli1));
                return False;
        }
@@ -3796,7 +3796,7 @@ static bool run_opentest(int dummy)
        }
 
        /* Ensure size == 20. */
-       if (!cli_getatr(cli1, fname, NULL, &fsize, NULL)) {
+       if (!NT_STATUS_IS_OK(cli_getatr(cli1, fname, NULL, &fsize, NULL))) {
                printf("(3) getatr failed (%s)\n", cli_errstr(cli1));
                return False;
        }
@@ -3819,7 +3819,7 @@ static bool run_opentest(int dummy)
        }
 
        /* Ensure size == 0. */
-       if (!cli_getatr(cli1, fname, NULL, &fsize, NULL)) {
+       if (!NT_STATUS_IS_OK(cli_getatr(cli1, fname, NULL, &fsize, NULL))) {
                printf("(3) getatr failed (%s)\n", cli_errstr(cli1));
                return False;
        }
@@ -4100,7 +4100,7 @@ static bool run_simple_posix_open_test(int dummy)
 
        /* Create a directory. */
        if (cli_posix_mkdir(cli1, dname, 0777) == -1) {
-               printf("Server doesn't support setting UNIX CIFS extensions.\n");
+               printf("POSIX mkdir of %s failed (%s)\n", dname, cli_errstr(cli1));
                goto out;
        }
 
@@ -4285,7 +4285,7 @@ static bool run_openattrtest(int dummy)
                                return False;
                        }
 
-                       if (!cli_getatr(cli1, fname, &attr, NULL, NULL)) {
+                       if (!NT_STATUS_IS_OK(cli_getatr(cli1, fname, &attr, NULL, NULL))) {
                                printf("getatr(2) failed (%s)\n", cli_errstr(cli1));
                                return False;
                        }
@@ -4959,6 +4959,7 @@ static bool run_chain1(int dummy)
        struct tevent_req *reqs[3], *smbreqs[3];
        bool done = false;
        const char *str = "foobar";
+       NTSTATUS status;
 
        printf("starting chain1 test\n");
        if (!torture_open_connection(&cli1, 0)) {
@@ -4983,7 +4984,62 @@ static bool run_chain1(int dummy)
        if (reqs[2] == NULL) return false;
        tevent_req_set_callback(reqs[2], chain1_close_completion, &done);
 
-       if (!cli_smb_chain_send(smbreqs, ARRAY_SIZE(smbreqs))) {
+       status = cli_smb_chain_send(smbreqs, ARRAY_SIZE(smbreqs));
+       if (!NT_STATUS_IS_OK(status)) {
+               return false;
+       }
+
+       while (!done) {
+               event_loop_once(evt);
+       }
+
+       torture_close_connection(cli1);
+       return True;
+}
+
+static void chain2_sesssetup_completion(struct tevent_req *req)
+{
+       NTSTATUS status;
+       status = cli_session_setup_guest_recv(req);
+       d_printf("sesssetup returned %s\n", nt_errstr(status));
+}
+
+static void chain2_tcon_completion(struct tevent_req *req)
+{
+       bool *done = (bool *)tevent_req_callback_data_void(req);
+       NTSTATUS status;
+       status = cli_tcon_andx_recv(req);
+       d_printf("tcon_and_x returned %s\n", nt_errstr(status));
+       *done = true;
+}
+
+static bool run_chain2(int dummy)
+{
+       struct cli_state *cli1;
+       struct event_context *evt = event_context_init(NULL);
+       struct tevent_req *reqs[2], *smbreqs[2];
+       bool done = false;
+       NTSTATUS status;
+
+       printf("starting chain2 test\n");
+       if (!torture_open_connection(&cli1, 0)) {
+               return False;
+       }
+
+       cli_sockopt(cli1, sockops);
+
+       reqs[0] = cli_session_setup_guest_create(talloc_tos(), evt, cli1,
+                                                &smbreqs[0]);
+       if (reqs[0] == NULL) return false;
+       tevent_req_set_callback(reqs[0], chain2_sesssetup_completion, NULL);
+
+       reqs[1] = cli_tcon_andx_create(talloc_tos(), evt, cli1, "IPC$",
+                                      "?????", NULL, 0, &smbreqs[1]);
+       if (reqs[1] == NULL) return false;
+       tevent_req_set_callback(reqs[1], chain2_tcon_completion, &done);
+
+       status = cli_smb_chain_send(smbreqs, ARRAY_SIZE(smbreqs));
+       if (!NT_STATUS_IS_OK(status)) {
                return false;
        }
 
@@ -5006,14 +5062,14 @@ static bool run_mangle1(int dummy)
        SMB_OFF_T size;
        uint16_t mode;
 
-       printf("starting chain1 test\n");
+       printf("starting mangle1 test\n");
        if (!torture_open_connection(&cli, 0)) {
                return False;
        }
 
        cli_sockopt(cli, sockops);
 
-       if (NT_STATUS_IS_OK(cli_ntcreate(
+       if (!NT_STATUS_IS_OK(cli_ntcreate(
                        cli, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS,
                        FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF, 0, 0, &fnum))) {
                d_printf("open %s failed: %s\n", fname, cli_errstr(cli));
@@ -5143,6 +5199,7 @@ static bool run_uid_regression_test(int dummy)
 {
        static struct cli_state *cli;
        int16_t old_vuid;
+       int16_t old_cnum;
        bool correct = True;
 
        printf("starting uid regression test\n");
@@ -5172,13 +5229,170 @@ static bool run_uid_regression_test(int dummy)
                                NT_STATUS_NO_SUCH_USER)) {
                        return False;
                }
-               goto out;
+       }
+
+       old_cnum = cli->cnum;
+
+       /* Now try a SMBtdis with the invald vuid set to zero. */
+       cli->vuid = 0;
+
+       /* This should succeed. */
+       if (cli_tdis(cli)) {
+               printf("First tdis with invalid vuid should succeed.\n");
+       } else {
+               printf("First tdis failed (%s)\n", cli_errstr(cli));
+       }
+
+       cli->vuid = old_vuid;
+       cli->cnum = old_cnum;
+
+       /* This should fail. */
+       if (cli_tdis(cli)) {
+               printf("Second tdis with invalid vuid should fail - succeeded instead !.\n");
+       } else {
+               /* Should be bad tid. */
+               if (!check_error(__LINE__, cli, ERRSRV, ERRinvnid,
+                               NT_STATUS_NETWORK_NAME_DELETED)) {
+                       return False;
+               }
        }
 
        cli_rmdir(cli, "\\uid_reg_test");
 
   out:
 
+       cli_shutdown(cli);
+       return correct;
+}
+
+
+static const char *illegal_chars = "*\\/?<>|\":";
+static char force_shortname_chars[] = " +,.[];=\177";
+
+static void shortname_del_fn(const char *mnt, file_info *finfo, const char *mask, void *state)
+{
+       struct cli_state *pcli = (struct cli_state *)state;
+       fstring fname;
+       slprintf(fname, sizeof(fname), "\\shortname\\%s", finfo->name);
+
+       if (strcmp(finfo->name, ".") == 0 || strcmp(finfo->name, "..") == 0)
+               return;
+
+       if (finfo->mode & aDIR) {
+               if (!NT_STATUS_IS_OK(cli_rmdir(pcli, fname)))
+                       printf("del_fn: failed to rmdir %s\n,", fname );
+       } else {
+               if (!NT_STATUS_IS_OK(cli_unlink(pcli, fname, aSYSTEM | aHIDDEN)))
+                       printf("del_fn: failed to unlink %s\n,", fname );
+       }
+}
+
+struct sn_state {
+       int i;
+       bool val;
+};
+
+static void shortname_list_fn(const char *mnt, file_info *finfo, const char *name, void *state)
+{
+       struct sn_state *s = (struct sn_state  *)state;
+       int i = s->i;
+
+#if 0
+       printf("shortname list: i = %d, name = |%s|, shortname = |%s|\n",
+               i, finfo->name, finfo->short_name);
+#endif
+
+       if (strchr(force_shortname_chars, i)) {
+               if (!finfo->short_name[0]) {
+                       /* Shortname not created when it should be. */
+                       d_printf("(%s) ERROR: Shortname was not created for file %s\n",
+                               __location__, finfo->name);
+                       s->val = true;
+               }
+       } else if (finfo->short_name[0]){
+               /* Shortname created when it should not be. */
+               d_printf("(%s) ERROR: Shortname %s was created for file %s\n",
+                       __location__, finfo->short_name, finfo->name);
+               s->val = true;
+       }
+}
+
+static bool run_shortname_test(int dummy)
+{
+       static struct cli_state *cli;
+       bool correct = True;
+       int i;
+       struct sn_state s;
+       char fname[20];
+
+       printf("starting shortname test\n");
+
+       if (!torture_open_connection(&cli, 0)) {
+               return False;
+       }
+
+       cli_sockopt(cli, sockops);
+
+       cli_list(cli, "\\shortname\\*", 0, shortname_del_fn, cli);
+       cli_list(cli, "\\shortname\\*", aDIR, shortname_del_fn, cli);
+       cli_rmdir(cli, "\\shortname");
+
+       if (!NT_STATUS_IS_OK(cli_mkdir(cli, "\\shortname"))) {
+               d_printf("(%s) cli_mkdir of \\shortname failed: %s\n",
+                       __location__, cli_errstr(cli));
+               correct = false;
+               goto out;
+       }
+
+       strlcpy(fname, "\\shortname\\", sizeof(fname));
+       strlcat(fname, "test .txt", sizeof(fname));
+
+       s.val = false;
+
+       for (i = 32; i < 128; i++) {
+               NTSTATUS status;
+               uint16_t fnum = (uint16_t)-1;
+
+               s.i = i;
+
+               if (strchr(illegal_chars, i)) {
+                       continue;
+               }
+               fname[15] = i;
+
+               status = cli_ntcreate(cli, fname, 0, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_NORMAL,
+                                   FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0, &fnum);
+               if (!NT_STATUS_IS_OK(status)) {
+                       d_printf("(%s) cli_nt_create of %s failed: %s\n",
+                               __location__, fname, cli_errstr(cli));
+                       correct = false;
+                       goto out;
+               }
+               cli_close(cli, fnum);
+               if (cli_list(cli, "\\shortname\\test*.*", 0, shortname_list_fn, &s) != 1) {
+                       d_printf("(%s) failed to list %s: %s\n",
+                               __location__, fname, cli_errstr(cli));
+                       correct = false;
+                       goto out;
+               }
+               if (!NT_STATUS_IS_OK(cli_unlink(cli, fname, aSYSTEM | aHIDDEN))) {
+                       d_printf("(%s) failed to delete %s: %s\n",
+                               __location__, fname, cli_errstr(cli));
+                       correct = false;
+                       goto out;
+               }
+
+               if (s.val) {
+                       correct = false;
+                       goto out;
+               }
+       }
+
+  out:
+
+       cli_list(cli, "\\shortname\\*", 0, shortname_del_fn, cli);
+       cli_list(cli, "\\shortname\\*", aDIR, shortname_del_fn, cli);
+       cli_rmdir(cli, "\\shortname");
        torture_close_connection(cli);
        return correct;
 }
@@ -5817,6 +6031,7 @@ static struct {
        {"OPEN", run_opentest, 0},
        {"POSIX", run_simple_posix_open_test, 0},
        { "UID-REGRESSION-TEST", run_uid_regression_test, 0},
+       { "SHORTNAME-TEST", run_shortname_test, 0},
 #if 1
        {"OPENATTR", run_openattrtest, 0},
 #endif
@@ -5840,6 +6055,7 @@ static struct {
        { "EATEST", run_eatest, 0},
        { "SESSSETUP_BENCH", run_sesssetup_bench, 0},
        { "CHAIN1", run_chain1, 0},
+       { "CHAIN2", run_chain2, 0},
        { "WINDOWS-WRITE", run_windows_write, 0},
        { "CLI_ECHO", run_cli_echo, 0},
        { "GETADDRINFO", run_getaddrinfo_send, 0},