8c510efab48c03899c24edccc4c46bd3cb3c0276
[gd/samba-autobuild/.git] / source4 / torture / basic / base.c
1 /* 
2    Unix SMB/CIFS implementation.
3    SMB torture tester
4    Copyright (C) Andrew Tridgell 1997-2003
5    Copyright (C) Jelmer Vernooij 2006
6    
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 3 of the License, or
10    (at your option) any later version.
11    
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16    
17    You should have received a copy of the GNU General Public License
18    along with this program.  If not, see <http://www.gnu.org/licenses/>.
19 */
20
21 #include "includes.h"
22 #include "torture/torture.h"
23 #include "torture/basic/proto.h"
24 #include "libcli/libcli.h"
25 #include "torture/util.h"
26 #include "system/filesys.h"
27 #include "system/time.h"
28 #include "libcli/resolve/resolve.h"
29 #include "librpc/gen_ndr/ndr_nbt.h"
30 #include "lib/events/events.h"
31 #include "lib/cmdline/popt_common.h"
32
33
34 #define CHECK_MAX_FAILURES(label) do { if (++failures >= torture_failures) goto label; } while (0)
35
36
37 static struct smbcli_state *open_nbt_connection(struct torture_context *tctx)
38 {
39         struct nbt_name called, calling;
40         struct smbcli_state *cli;
41         const char *host = torture_setting_string(tctx, "host", NULL);
42
43         make_nbt_name_client(&calling, lp_netbios_name());
44
45         nbt_choose_called_name(NULL, &called, host, NBT_NAME_SERVER);
46
47         cli = smbcli_state_init(NULL);
48         if (!cli) {
49                 torture_comment(tctx, "Failed initialize smbcli_struct to connect with %s\n", host);
50                 goto failed;
51         }
52
53         if (!smbcli_socket_connect(cli, host)) {
54                 torture_comment(tctx, "Failed to connect with %s\n", host);
55                 goto failed;
56         }
57
58         if (!smbcli_transport_establish(cli, &calling, &called)) {
59                 torture_comment(tctx, "%s rejected the session\n",host);
60                 goto failed;
61         }
62
63         return cli;
64
65 failed:
66         talloc_free(cli);
67         return NULL;
68 }
69
70 static BOOL tcon_devtest(struct torture_context *tctx, 
71                                                  struct smbcli_state *cli,
72                                                  const char *myshare, const char *devtype,
73                                                  NTSTATUS expected_error)
74 {
75         BOOL status;
76         const char *password = torture_setting_string(tctx, "password", NULL);
77
78         status = NT_STATUS_IS_OK(smbcli_tconX(cli, myshare, devtype, 
79                                                 password));
80
81         torture_comment(tctx, "Trying share %s with devtype %s\n", myshare, devtype);
82
83         if (NT_STATUS_IS_OK(expected_error)) {
84                 if (!status) {
85                         torture_fail(tctx, talloc_asprintf(tctx, 
86                                    "tconX to share %s with type %s "
87                                "should have succeeded but failed",
88                                myshare, devtype));
89                 }
90                 smbcli_tdis(cli);
91         } else {
92                 if (status) {
93                         torture_fail(tctx, talloc_asprintf(tctx, 
94                                    "tconx to share %s with type %s "
95                                "should have failed but succeeded",
96                                myshare, devtype));
97                 } else {
98                         if (NT_STATUS_EQUAL(smbcli_nt_error(cli->tree),
99                                             expected_error)) {
100                         } else {
101                                 torture_fail(tctx, "Returned unexpected error");
102                         }
103                 }
104         }
105         return true;
106 }
107
108
109
110 /**
111 test whether fnums and tids open on one VC are available on another (a major
112 security hole)
113 */
114 static bool run_fdpasstest(struct torture_context *tctx,
115                                                    struct smbcli_state *cli1, 
116                                                    struct smbcli_state *cli2)
117 {
118         const char *fname = "\\fdpass.tst";
119         int fnum1, oldtid;
120         uint8_t buf[1024];
121
122         smbcli_unlink(cli1->tree, fname);
123
124         torture_comment(tctx, "Opening a file on connection 1\n");
125
126         fnum1 = smbcli_open(cli1->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
127         torture_assert(tctx, fnum1 != -1, 
128                         talloc_asprintf(tctx, 
129                         "open of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree)));
130
131         torture_comment(tctx, "writing to file on connection 1\n");
132
133         torture_assert(tctx, 
134                 smbcli_write(cli1->tree, fnum1, 0, "hello world\n", 0, 13) == 13,
135                 talloc_asprintf(tctx, 
136                 "write failed (%s)\n", smbcli_errstr(cli1->tree)));
137
138         oldtid = cli2->tree->tid;
139         cli2->session->vuid = cli1->session->vuid;
140         cli2->tree->tid = cli1->tree->tid;
141         cli2->session->pid = cli1->session->pid;
142
143         torture_comment(tctx, "reading from file on connection 2\n");
144
145         torture_assert(tctx, smbcli_read(cli2->tree, fnum1, buf, 0, 13) != 13,
146                                    talloc_asprintf(tctx,
147                 "read succeeded! nasty security hole [%s]\n", buf));
148
149         smbcli_close(cli1->tree, fnum1);
150         smbcli_unlink(cli1->tree, fname);
151
152         cli2->tree->tid = oldtid;
153
154         return true;
155 }
156
157 /**
158   This checks how the getatr calls works
159 */
160 static BOOL run_attrtest(struct torture_context *tctx, 
161                                                  struct smbcli_state *cli)
162 {
163         int fnum;
164         time_t t, t2;
165         const char *fname = "\\attrib123456789.tst";
166         BOOL correct = True;
167
168         smbcli_unlink(cli->tree, fname);
169         fnum = smbcli_open(cli->tree, fname, 
170                         O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
171         smbcli_close(cli->tree, fnum);
172
173         if (NT_STATUS_IS_ERR(smbcli_getatr(cli->tree, fname, NULL, NULL, &t))) {
174                 torture_comment(tctx, "getatr failed (%s)\n", smbcli_errstr(cli->tree));
175                 correct = False;
176         }
177
178         torture_comment(tctx, "New file time is %s", ctime(&t));
179
180         if (abs(t - time(NULL)) > 60*60*24*10) {
181                 torture_comment(tctx, "ERROR: SMBgetatr bug. time is %s",
182                        ctime(&t));
183                 t = time(NULL);
184                 correct = False;
185         }
186
187         t2 = t-60*60*24; /* 1 day ago */
188
189         torture_comment(tctx, "Setting file time to %s", ctime(&t2));
190
191         if (NT_STATUS_IS_ERR(smbcli_setatr(cli->tree, fname, 0, t2))) {
192                 torture_comment(tctx, "setatr failed (%s)\n", smbcli_errstr(cli->tree));
193                 correct = True;
194         }
195
196         if (NT_STATUS_IS_ERR(smbcli_getatr(cli->tree, fname, NULL, NULL, &t))) {
197                 torture_comment(tctx, "getatr failed (%s)\n", smbcli_errstr(cli->tree));
198                 correct = True;
199         }
200
201         torture_comment(tctx, "Retrieved file time as %s", ctime(&t));
202
203         if (t != t2) {
204                 torture_comment(tctx, "ERROR: getatr/setatr bug. times are\n%s",
205                        ctime(&t));
206                 torture_comment(tctx, "%s", ctime(&t2));
207                 correct = True;
208         }
209
210         smbcli_unlink(cli->tree, fname);
211
212         return correct;
213 }
214
215 /**
216   This checks a couple of trans2 calls
217 */
218 static BOOL run_trans2test(struct torture_context *tctx, 
219                                                    struct smbcli_state *cli)
220 {
221         int fnum;
222         size_t size;
223         time_t c_time, a_time, m_time, w_time, m_time2;
224         const char *fname = "\\trans2.tst";
225         const char *dname = "\\trans2";
226         const char *fname2 = "\\trans2\\trans2.tst";
227         const char *pname;
228         BOOL correct = True;
229
230         smbcli_unlink(cli->tree, fname);
231
232         torture_comment(tctx, "Testing qfileinfo\n");
233         
234         fnum = smbcli_open(cli->tree, fname, 
235                         O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
236         if (NT_STATUS_IS_ERR(smbcli_qfileinfo(cli->tree, fnum, NULL, &size, &c_time, &a_time, &m_time,
237                            NULL, NULL))) {
238                 torture_comment(tctx, "ERROR: qfileinfo failed (%s)\n", smbcli_errstr(cli->tree));
239                 correct = False;
240         }
241
242         torture_comment(tctx, "Testing NAME_INFO\n");
243
244         if (NT_STATUS_IS_ERR(smbcli_qfilename(cli->tree, fnum, &pname))) {
245                 torture_comment(tctx, "ERROR: qfilename failed (%s)\n", smbcli_errstr(cli->tree));
246                 correct = False;
247         }
248
249         if (!pname || strcmp(pname, fname)) {
250                 torture_comment(tctx, "qfilename gave different name? [%s] [%s]\n",
251                        fname, pname);
252                 correct = False;
253         }
254
255         smbcli_close(cli->tree, fnum);
256         smbcli_unlink(cli->tree, fname);
257
258         fnum = smbcli_open(cli->tree, fname, 
259                         O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
260         if (fnum == -1) {
261                 torture_comment(tctx, "open of %s failed (%s)\n", fname, smbcli_errstr(cli->tree));
262                 return False;
263         }
264         smbcli_close(cli->tree, fnum);
265
266         torture_comment(tctx, "Checking for sticky create times\n");
267
268         if (NT_STATUS_IS_ERR(smbcli_qpathinfo(cli->tree, fname, &c_time, &a_time, &m_time, &size, NULL))) {
269                 torture_comment(tctx, "ERROR: qpathinfo failed (%s)\n", smbcli_errstr(cli->tree));
270                 correct = False;
271         } else {
272                 if (c_time != m_time) {
273                         torture_comment(tctx, "create time=%s", ctime(&c_time));
274                         torture_comment(tctx, "modify time=%s", ctime(&m_time));
275                         torture_comment(tctx, "This system appears to have sticky create times\n");
276                 }
277                 if (a_time % (60*60) == 0) {
278                         torture_comment(tctx, "access time=%s", ctime(&a_time));
279                         torture_comment(tctx, "This system appears to set a midnight access time\n");
280                         correct = False;
281                 }
282
283                 if (abs(m_time - time(NULL)) > 60*60*24*7) {
284                         torture_comment(tctx, "ERROR: totally incorrect times - maybe word reversed? mtime=%s", ctime(&m_time));
285                         correct = False;
286                 }
287         }
288
289
290         smbcli_unlink(cli->tree, fname);
291         fnum = smbcli_open(cli->tree, fname, 
292                         O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
293         smbcli_close(cli->tree, fnum);
294         if (NT_STATUS_IS_ERR(smbcli_qpathinfo2(cli->tree, fname, &c_time, &a_time, &m_time, &w_time, &size, NULL, NULL))) {
295                 torture_comment(tctx, "ERROR: qpathinfo2 failed (%s)\n", smbcli_errstr(cli->tree));
296                 correct = False;
297         } else {
298                 if (w_time < 60*60*24*2) {
299                         torture_comment(tctx, "write time=%s", ctime(&w_time));
300                         torture_comment(tctx, "This system appears to set a initial 0 write time\n");
301                         correct = False;
302                 }
303         }
304
305         smbcli_unlink(cli->tree, fname);
306
307
308         /* check if the server updates the directory modification time
309            when creating a new file */
310         if (NT_STATUS_IS_ERR(smbcli_mkdir(cli->tree, dname))) {
311                 torture_comment(tctx, "ERROR: mkdir failed (%s)\n", smbcli_errstr(cli->tree));
312                 correct = False;
313         }
314         sleep(3);
315         if (NT_STATUS_IS_ERR(smbcli_qpathinfo2(cli->tree, "\\trans2\\", &c_time, &a_time, &m_time, &w_time, &size, NULL, NULL))) {
316                 torture_comment(tctx, "ERROR: qpathinfo2 failed (%s)\n", smbcli_errstr(cli->tree));
317                 correct = False;
318         }
319
320         fnum = smbcli_open(cli->tree, fname2, 
321                         O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
322         smbcli_write(cli->tree, fnum,  0, &fnum, 0, sizeof(fnum));
323         smbcli_close(cli->tree, fnum);
324         if (NT_STATUS_IS_ERR(smbcli_qpathinfo2(cli->tree, "\\trans2\\", &c_time, &a_time, &m_time2, &w_time, &size, NULL, NULL))) {
325                 torture_comment(tctx, "ERROR: qpathinfo2 failed (%s)\n", smbcli_errstr(cli->tree));
326                 correct = False;
327         } else {
328                 if (m_time2 == m_time) {
329                         torture_comment(tctx, "This system does not update directory modification times\n");
330                         correct = False;
331                 }
332         }
333         smbcli_unlink(cli->tree, fname2);
334         smbcli_rmdir(cli->tree, dname);
335
336         return correct;
337 }
338
339 /* send smb negprot commands, not reading the response */
340 static BOOL run_negprot_nowait(struct torture_context *tctx)
341 {
342         int i;
343         struct smbcli_state *cli, *cli2;
344         BOOL correct = True;
345
346         torture_comment(tctx, "starting negprot nowait test\n");
347
348         cli = open_nbt_connection(tctx);
349         if (!cli) {
350                 return False;
351         }
352
353         torture_comment(tctx, "Filling send buffer\n");
354
355         for (i=0;i<100;i++) {
356                 struct smbcli_request *req;
357                 req = smb_raw_negotiate_send(cli->transport, PROTOCOL_NT1);
358                 event_loop_once(cli->transport->socket->event.ctx);
359                 if (req->state == SMBCLI_REQUEST_ERROR) {
360                         if (i > 0) {
361                                 torture_comment(tctx, "Failed to fill pipe packet[%d] - %s (ignored)\n", i+1, nt_errstr(req->status));
362                                 break;
363                         } else {
364                                 torture_comment(tctx, "Failed to fill pipe - %s \n", nt_errstr(req->status));
365                                 torture_close_connection(cli);
366                                 return False;
367                         }
368                 }
369         }
370
371         torture_comment(tctx, "Opening secondary connection\n");
372         if (!torture_open_connection(&cli2, 1)) {
373                 torture_comment(tctx, "Failed to open secondary connection\n");
374                 correct = False;
375         }
376
377         if (!torture_close_connection(cli2)) {
378                 torture_comment(tctx, "Failed to close secondary connection\n");
379                 correct = False;
380         }
381
382         torture_close_connection(cli);
383
384         return correct;
385 }
386
387 /**
388   this checks to see if a secondary tconx can use open files from an
389   earlier tconx
390  */
391 static BOOL run_tcon_test(struct torture_context *tctx, struct smbcli_state *cli)
392 {
393         const char *fname = "\\tcontest.tmp";
394         int fnum1;
395         uint16_t cnum1, cnum2, cnum3;
396         uint16_t vuid1, vuid2;
397         uint8_t buf[4];
398         BOOL ret = True;
399         struct smbcli_tree *tree1;
400         const char *host = torture_setting_string(tctx, "host", NULL);
401         const char *share = torture_setting_string(tctx, "share", NULL);
402         const char *password = torture_setting_string(tctx, "password", NULL);
403
404         if (smbcli_deltree(cli->tree, fname) == -1) {
405                 torture_comment(tctx, "unlink of %s failed (%s)\n", fname, smbcli_errstr(cli->tree));
406         }
407
408         fnum1 = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
409         if (fnum1 == -1) {
410                 torture_comment(tctx, "open of %s failed (%s)\n", fname, smbcli_errstr(cli->tree));
411                 return False;
412         }
413
414         cnum1 = cli->tree->tid;
415         vuid1 = cli->session->vuid;
416
417         memset(&buf, 0, 4); /* init buf so valgrind won't complain */
418         if (smbcli_write(cli->tree, fnum1, 0, buf, 130, 4) != 4) {
419                 torture_comment(tctx, "initial write failed (%s)\n", smbcli_errstr(cli->tree));
420                 return False;
421         }
422
423         tree1 = cli->tree;      /* save old tree connection */
424         if (NT_STATUS_IS_ERR(smbcli_tconX(cli, share, "?????", password))) {
425                 torture_comment(tctx, "%s refused 2nd tree connect (%s)\n", host,
426                            smbcli_errstr(cli->tree));
427                 talloc_free(cli);
428                 return False;
429         }
430
431         cnum2 = cli->tree->tid;
432         cnum3 = MAX(cnum1, cnum2) + 1; /* any invalid number */
433         vuid2 = cli->session->vuid + 1;
434
435         /* try a write with the wrong tid */
436         cli->tree->tid = cnum2;
437
438         if (smbcli_write(cli->tree, fnum1, 0, buf, 130, 4) == 4) {
439                 torture_comment(tctx, "* server allows write with wrong TID\n");
440                 ret = False;
441         } else {
442                 torture_comment(tctx, "server fails write with wrong TID : %s\n", smbcli_errstr(cli->tree));
443         }
444
445
446         /* try a write with an invalid tid */
447         cli->tree->tid = cnum3;
448
449         if (smbcli_write(cli->tree, fnum1, 0, buf, 130, 4) == 4) {
450                 torture_comment(tctx, "* server allows write with invalid TID\n");
451                 ret = False;
452         } else {
453                 torture_comment(tctx, "server fails write with invalid TID : %s\n", smbcli_errstr(cli->tree));
454         }
455
456         /* try a write with an invalid vuid */
457         cli->session->vuid = vuid2;
458         cli->tree->tid = cnum1;
459
460         if (smbcli_write(cli->tree, fnum1, 0, buf, 130, 4) == 4) {
461                 torture_comment(tctx, "* server allows write with invalid VUID\n");
462                 ret = False;
463         } else {
464                 torture_comment(tctx, "server fails write with invalid VUID : %s\n", smbcli_errstr(cli->tree));
465         }
466
467         cli->session->vuid = vuid1;
468         cli->tree->tid = cnum1;
469
470         if (NT_STATUS_IS_ERR(smbcli_close(cli->tree, fnum1))) {
471                 torture_comment(tctx, "close failed (%s)\n", smbcli_errstr(cli->tree));
472                 return False;
473         }
474
475         cli->tree->tid = cnum2;
476
477         if (NT_STATUS_IS_ERR(smbcli_tdis(cli))) {
478                 torture_comment(tctx, "secondary tdis failed (%s)\n", smbcli_errstr(cli->tree));
479                 return False;
480         }
481
482         cli->tree = tree1;  /* restore initial tree */
483         cli->tree->tid = cnum1;
484
485         smbcli_unlink(tree1, fname);
486
487         return ret;
488 }
489
490 /**
491  checks for correct tconX support
492  */
493 static BOOL run_tcon_devtype_test(struct torture_context *tctx, 
494                                                                   struct smbcli_state *cli1)
495 {
496         const char *share = torture_setting_string(tctx, "share", NULL);
497
498         if (!tcon_devtest(tctx, cli1, "IPC$", "A:", NT_STATUS_BAD_DEVICE_TYPE))
499                 return false;
500
501         if (!tcon_devtest(tctx, cli1, "IPC$", "?????", NT_STATUS_OK))
502                 return false;
503
504         if (!tcon_devtest(tctx, cli1, "IPC$", "LPT:", NT_STATUS_BAD_DEVICE_TYPE))
505                 return false;
506
507         if (!tcon_devtest(tctx, cli1, "IPC$", "IPC", NT_STATUS_OK))
508                 return false;
509                         
510         if (!tcon_devtest(tctx, cli1, "IPC$", "FOOBA", NT_STATUS_BAD_DEVICE_TYPE))
511                 return false;
512
513         if (!tcon_devtest(tctx, cli1, share, "A:", NT_STATUS_OK))
514                 return false;
515
516         if (!tcon_devtest(tctx, cli1, share, "?????", NT_STATUS_OK))
517                 return false;
518
519         if (!tcon_devtest(tctx, cli1, share, "LPT:", NT_STATUS_BAD_DEVICE_TYPE))
520                 return false;
521
522         if (!tcon_devtest(tctx, cli1, share, "IPC", NT_STATUS_BAD_DEVICE_TYPE))
523                 return false;
524                         
525         if (!tcon_devtest(tctx, cli1, share, "FOOBA", NT_STATUS_BAD_DEVICE_TYPE))
526                 return false;
527
528         return true;
529 }
530
531 static BOOL rw_torture2(struct torture_context *tctx,
532                                                 struct smbcli_state *c1, struct smbcli_state *c2)
533 {
534         const char *lockfname = "\\torture2.lck";
535         int fnum1;
536         int fnum2;
537         int i;
538         uint8_t buf[131072];
539         uint8_t buf_rd[131072];
540         BOOL correct = True;
541         ssize_t bytes_read, bytes_written;
542
543         torture_assert(tctx, smbcli_deltree(c1->tree, lockfname) != -1,
544                                    talloc_asprintf(tctx, 
545                 "unlink failed (%s)", smbcli_errstr(c1->tree)));
546
547         fnum1 = smbcli_open(c1->tree, lockfname, O_RDWR | O_CREAT | O_EXCL, 
548                          DENY_NONE);
549         torture_assert(tctx, fnum1 != -1, 
550                                    talloc_asprintf(tctx, 
551                 "first open read/write of %s failed (%s)",
552                                 lockfname, smbcli_errstr(c1->tree)));
553         fnum2 = smbcli_open(c2->tree, lockfname, O_RDONLY, 
554                          DENY_NONE);
555         torture_assert(tctx, fnum2 != -1, 
556                                    talloc_asprintf(tctx, 
557                 "second open read-only of %s failed (%s)",
558                                 lockfname, smbcli_errstr(c2->tree)));
559
560         torture_comment(tctx, "Checking data integrity over %d ops\n", 
561                                         torture_numops);
562
563         for (i=0;i<torture_numops;i++)
564         {
565                 size_t buf_size = ((uint_t)random()%(sizeof(buf)-1))+ 1;
566                 if (i % 10 == 0) {
567                         if (torture_setting_bool(tctx, "progress", true)) {
568                                 torture_comment(tctx, "%d\r", i); fflush(stdout);
569                         }
570                 }
571
572                 generate_random_buffer(buf, buf_size);
573
574                 if ((bytes_written = smbcli_write(c1->tree, fnum1, 0, buf, 0, buf_size)) != buf_size) {
575                         torture_comment(tctx, "write failed (%s)\n", smbcli_errstr(c1->tree));
576                         torture_comment(tctx, "wrote %d, expected %d\n", (int)bytes_written, (int)buf_size); 
577                         correct = False;
578                         break;
579                 }
580
581                 if ((bytes_read = smbcli_read(c2->tree, fnum2, buf_rd, 0, buf_size)) != buf_size) {
582                         torture_comment(tctx, "read failed (%s)\n", smbcli_errstr(c2->tree));
583                         torture_comment(tctx, "read %d, expected %d\n", (int)bytes_read, (int)buf_size); 
584                         correct = False;
585                         break;
586                 }
587
588                 torture_assert(tctx, memcmp(buf_rd, buf, buf_size) == 0, 
589                         "read/write compare failed\n");
590         }
591
592         torture_assert_ntstatus_ok(tctx, smbcli_close(c2->tree, fnum2), 
593                 talloc_asprintf(tctx, "close failed (%s)", smbcli_errstr(c2->tree)));
594         torture_assert_ntstatus_ok(tctx, smbcli_close(c1->tree, fnum1),
595                 talloc_asprintf(tctx, "close failed (%s)", smbcli_errstr(c1->tree)));
596
597         torture_assert_ntstatus_ok(tctx, smbcli_unlink(c1->tree, lockfname),
598                 talloc_asprintf(tctx, "unlink failed (%s)", smbcli_errstr(c1->tree)));
599
600         torture_comment(tctx, "\n");
601
602         return correct;
603 }
604
605
606
607 static bool run_readwritetest(struct torture_context *tctx,
608                                                           struct smbcli_state *cli1,
609                                                           struct smbcli_state *cli2)
610 {
611         torture_comment(tctx, "Running readwritetest v1\n");
612         if (!rw_torture2(tctx, cli1, cli2)) 
613                 return false;
614
615         torture_comment(tctx, "Running readwritetest v2\n");
616
617         if (!rw_torture2(tctx, cli1, cli1))
618                 return false;
619
620         return true;
621 }
622
623 /*
624 test the timing of deferred open requests
625 */
626 static BOOL run_deferopen(struct torture_context *tctx, struct smbcli_state *cli, int dummy)
627 {
628         const char *fname = "\\defer_open_test.dat";
629         int retries=4;
630         int i = 0;
631         BOOL correct = True;
632
633         if (retries <= 0) {
634                 torture_comment(tctx, "failed to connect\n");
635                 return False;
636         }
637
638         torture_comment(tctx, "Testing deferred open requests.\n");
639
640         while (i < 4) {
641                 int fnum = -1;
642
643                 do {
644                         struct timeval tv;
645                         tv = timeval_current();
646                         fnum = smbcli_nt_create_full(cli->tree, fname, 0, 
647                                                      SEC_RIGHTS_FILE_ALL,
648                                                      FILE_ATTRIBUTE_NORMAL, 
649                                                      NTCREATEX_SHARE_ACCESS_NONE,
650                                                      NTCREATEX_DISP_OPEN_IF, 0, 0);
651                         if (fnum != -1) {
652                                 break;
653                         }
654                         if (NT_STATUS_EQUAL(smbcli_nt_error(cli->tree),NT_STATUS_SHARING_VIOLATION)) {
655                                 double e = timeval_elapsed(&tv);
656                                 if (e < 0.5 || e > 1.5) {
657                                         torture_comment(tctx,"Timing incorrect %.2f violation\n",
658                                                 e);
659                                 }
660                         }
661                 } while (NT_STATUS_EQUAL(smbcli_nt_error(cli->tree),NT_STATUS_SHARING_VIOLATION));
662
663                 if (fnum == -1) {
664                         torture_comment(tctx,"Failed to open %s, error=%s\n", fname, smbcli_errstr(cli->tree));
665                         return False;
666                 }
667
668                 torture_comment(tctx, "pid %u open %d\n", (unsigned)getpid(), i);
669
670                 sleep(10);
671                 i++;
672                 if (NT_STATUS_IS_ERR(smbcli_close(cli->tree, fnum))) {
673                         torture_comment(tctx,"Failed to close %s, error=%s\n", fname, smbcli_errstr(cli->tree));
674                         return False;
675                 }
676                 sleep(2);
677         }
678
679         if (NT_STATUS_IS_ERR(smbcli_unlink(cli->tree, fname))) {
680                 /* All until the last unlink will fail with sharing violation. */
681                 if (!NT_STATUS_EQUAL(smbcli_nt_error(cli->tree),NT_STATUS_SHARING_VIOLATION)) {
682                         torture_comment(tctx, "unlink of %s failed (%s)\n", fname, smbcli_errstr(cli->tree));
683                         correct = False;
684                 }
685         }
686
687         torture_comment(tctx, "deferred test finished\n");
688         return correct;
689 }
690
691 /**
692   Try with a wrong vuid and check error message.
693  */
694
695 static BOOL run_vuidtest(struct torture_context *tctx, 
696                                                  struct smbcli_state *cli)
697 {
698         const char *fname = "\\vuid.tst";
699         int fnum;
700         size_t size;
701         time_t c_time, a_time, m_time;
702
703         uint16_t orig_vuid;
704         NTSTATUS result;
705
706         smbcli_unlink(cli->tree, fname);
707
708         fnum = smbcli_open(cli->tree, fname, 
709                         O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
710
711         orig_vuid = cli->session->vuid;
712
713         cli->session->vuid += 1234;
714
715         torture_comment(tctx, "Testing qfileinfo with wrong vuid\n");
716         
717         if (NT_STATUS_IS_OK(result = smbcli_qfileinfo(cli->tree, fnum, NULL,
718                                                    &size, &c_time, &a_time,
719                                                    &m_time, NULL, NULL))) {
720                 torture_fail(tctx, "qfileinfo passed with wrong vuid");
721         }
722
723         if (!NT_STATUS_EQUAL(cli->transport->error.e.nt_status, 
724                              NT_STATUS_DOS(ERRSRV, ERRbaduid)) &&
725             !NT_STATUS_EQUAL(cli->transport->error.e.nt_status, 
726                              NT_STATUS_INVALID_HANDLE)) {
727                 torture_fail(tctx, talloc_asprintf(tctx, 
728                                 "qfileinfo should have returned DOS error "
729                        "ERRSRV:ERRbaduid\n  but returned %s",
730                        smbcli_errstr(cli->tree)));
731         }
732
733         cli->session->vuid -= 1234;
734
735         torture_assert_ntstatus_ok(tctx, smbcli_close(cli->tree, fnum),
736                 talloc_asprintf(tctx, "close failed (%s)", smbcli_errstr(cli->tree)));
737
738         smbcli_unlink(cli->tree, fname);
739
740         return true;
741 }
742
743 /*
744   Test open mode returns on read-only files.
745  */
746  static BOOL run_opentest(struct torture_context *tctx, struct smbcli_state *cli1, 
747                                                   struct smbcli_state *cli2)
748 {
749         const char *fname = "\\readonly.file";
750         char *control_char_fname;
751         int fnum1, fnum2;
752         uint8_t buf[20];
753         size_t fsize;
754         BOOL correct = True;
755         char *tmp_path;
756         int failures = 0;
757         int i;
758
759         asprintf(&control_char_fname, "\\readonly.afile");
760         for (i = 1; i <= 0x1f; i++) {
761                 control_char_fname[10] = i;
762                 fnum1 = smbcli_nt_create_full(cli1->tree, control_char_fname, 0, SEC_FILE_WRITE_DATA, FILE_ATTRIBUTE_NORMAL,
763                                    NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
764                 
765                 if (!check_error(__location__, cli1, ERRDOS, ERRinvalidname, 
766                                 NT_STATUS_OBJECT_NAME_INVALID)) {
767                         torture_comment(tctx, "Error code should be NT_STATUS_OBJECT_NAME_INVALID, was %s for file with %d char\n",
768                                         smbcli_errstr(cli1->tree), i);
769                         failures++;
770                 }
771
772                 if (fnum1 != -1) {
773                         smbcli_close(cli1->tree, fnum1);
774                 }
775                 smbcli_setatr(cli1->tree, control_char_fname, 0, 0);
776                 smbcli_unlink(cli1->tree, control_char_fname);
777         }
778         free(control_char_fname);
779
780         if (!failures)
781                 torture_comment(tctx, "Create file with control char names passed.\n");
782
783         smbcli_setatr(cli1->tree, fname, 0, 0);
784         smbcli_unlink(cli1->tree, fname);
785         
786         fnum1 = smbcli_open(cli1->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
787         if (fnum1 == -1) {
788                 torture_comment(tctx, "open of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
789                 return False;
790         }
791
792         if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
793                 torture_comment(tctx, "close2 failed (%s)\n", smbcli_errstr(cli1->tree));
794                 return False;
795         }
796         
797         if (NT_STATUS_IS_ERR(smbcli_setatr(cli1->tree, fname, FILE_ATTRIBUTE_READONLY, 0))) {
798                 torture_comment(tctx, "smbcli_setatr failed (%s)\n", smbcli_errstr(cli1->tree));
799                 CHECK_MAX_FAILURES(error_test1);
800                 return False;
801         }
802         
803         fnum1 = smbcli_open(cli1->tree, fname, O_RDONLY, DENY_WRITE);
804         if (fnum1 == -1) {
805                 torture_comment(tctx, "open of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
806                 CHECK_MAX_FAILURES(error_test1);
807                 return False;
808         }
809         
810         /* This will fail - but the error should be ERRnoaccess, not ERRbadshare. */
811         fnum2 = smbcli_open(cli1->tree, fname, O_RDWR, DENY_ALL);
812         
813         if (check_error(__location__, cli1, ERRDOS, ERRnoaccess, 
814                         NT_STATUS_ACCESS_DENIED)) {
815                 torture_comment(tctx, "correct error code ERRDOS/ERRnoaccess returned\n");
816         }
817         
818         torture_comment(tctx, "finished open test 1\n");
819 error_test1:
820         smbcli_close(cli1->tree, fnum1);
821         
822         /* Now try not readonly and ensure ERRbadshare is returned. */
823         
824         smbcli_setatr(cli1->tree, fname, 0, 0);
825         
826         fnum1 = smbcli_open(cli1->tree, fname, O_RDONLY, DENY_WRITE);
827         if (fnum1 == -1) {
828                 torture_comment(tctx, "open of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
829                 return False;
830         }
831         
832         /* This will fail - but the error should be ERRshare. */
833         fnum2 = smbcli_open(cli1->tree, fname, O_RDWR, DENY_ALL);
834         
835         if (check_error(__location__, cli1, ERRDOS, ERRbadshare, 
836                         NT_STATUS_SHARING_VIOLATION)) {
837                 torture_comment(tctx, "correct error code ERRDOS/ERRbadshare returned\n");
838         }
839         
840         if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
841                 torture_comment(tctx, "close2 failed (%s)\n", smbcli_errstr(cli1->tree));
842                 return False;
843         }
844         
845         smbcli_unlink(cli1->tree, fname);
846         
847         torture_comment(tctx, "finished open test 2\n");
848         
849         /* Test truncate open disposition on file opened for read. */
850         
851         fnum1 = smbcli_open(cli1->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
852         if (fnum1 == -1) {
853                 torture_comment(tctx, "(3) open (1) of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
854                 return False;
855         }
856         
857         /* write 20 bytes. */
858         
859         memset(buf, '\0', 20);
860
861         if (smbcli_write(cli1->tree, fnum1, 0, buf, 0, 20) != 20) {
862                 torture_comment(tctx, "write failed (%s)\n", smbcli_errstr(cli1->tree));
863                 correct = False;
864         }
865
866         if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
867                 torture_comment(tctx, "(3) close1 failed (%s)\n", smbcli_errstr(cli1->tree));
868                 return False;
869         }
870         
871         /* Ensure size == 20. */
872         if (NT_STATUS_IS_ERR(smbcli_getatr(cli1->tree, fname, NULL, &fsize, NULL))) {
873                 torture_comment(tctx, "(3) getatr failed (%s)\n", smbcli_errstr(cli1->tree));
874                 CHECK_MAX_FAILURES(error_test3);
875                 return False;
876         }
877         
878         if (fsize != 20) {
879                 torture_comment(tctx, "(3) file size != 20\n");
880                 CHECK_MAX_FAILURES(error_test3);
881                 return False;
882         }
883
884         /* Now test if we can truncate a file opened for readonly. */
885         
886         fnum1 = smbcli_open(cli1->tree, fname, O_RDONLY|O_TRUNC, DENY_NONE);
887         if (fnum1 == -1) {
888                 torture_comment(tctx, "(3) open (2) of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
889                 CHECK_MAX_FAILURES(error_test3);
890                 return False;
891         }
892         
893         if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
894                 torture_comment(tctx, "close2 failed (%s)\n", smbcli_errstr(cli1->tree));
895                 return False;
896         }
897
898         /* Ensure size == 0. */
899         if (NT_STATUS_IS_ERR(smbcli_getatr(cli1->tree, fname, NULL, &fsize, NULL))) {
900                 torture_comment(tctx, "(3) getatr failed (%s)\n", smbcli_errstr(cli1->tree));
901                 CHECK_MAX_FAILURES(error_test3);
902                 return False;
903         }
904
905         if (fsize != 0) {
906                 torture_comment(tctx, "(3) file size != 0\n");
907                 CHECK_MAX_FAILURES(error_test3);
908                 return False;
909         }
910         torture_comment(tctx, "finished open test 3\n");
911 error_test3:    
912         smbcli_unlink(cli1->tree, fname);
913
914
915         torture_comment(tctx, "testing ctemp\n");
916         fnum1 = smbcli_ctemp(cli1->tree, "\\", &tmp_path);
917         if (fnum1 == -1) {
918                 torture_comment(tctx, "ctemp failed (%s)\n", smbcli_errstr(cli1->tree));
919                 CHECK_MAX_FAILURES(error_test4);
920                 return False;
921         }
922         torture_comment(tctx, "ctemp gave path %s\n", tmp_path);
923         if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
924                 torture_comment(tctx, "close of temp failed (%s)\n", smbcli_errstr(cli1->tree));
925         }
926         if (NT_STATUS_IS_ERR(smbcli_unlink(cli1->tree, tmp_path))) {
927                 torture_comment(tctx, "unlink of temp failed (%s)\n", smbcli_errstr(cli1->tree));
928         }
929 error_test4:    
930         /* Test the non-io opens... */
931
932         smbcli_setatr(cli2->tree, fname, 0, 0);
933         smbcli_unlink(cli2->tree, fname);
934         
935         torture_comment(tctx, "TEST #1 testing 2 non-io opens (no delete)\n");
936         
937         fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
938                                    NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
939
940         if (fnum1 == -1) {
941                 torture_comment(tctx, "test 1 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
942                 CHECK_MAX_FAILURES(error_test10);
943                 return False;
944         }
945
946         fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
947                                    NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OPEN_IF, 0, 0);
948         if (fnum2 == -1) {
949                 torture_comment(tctx, "test 1 open 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
950                 CHECK_MAX_FAILURES(error_test10);
951                 return False;
952         }
953
954         if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
955                 torture_comment(tctx, "test 1 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
956                 return False;
957         }
958         if (NT_STATUS_IS_ERR(smbcli_close(cli2->tree, fnum2))) {
959                 torture_comment(tctx, "test 1 close 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
960                 return False;
961         }
962
963         torture_comment(tctx, "non-io open test #1 passed.\n");
964 error_test10:
965         smbcli_unlink(cli1->tree, fname);
966
967         torture_comment(tctx, "TEST #2 testing 2 non-io opens (first with delete)\n");
968         
969         fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SEC_STD_DELETE|SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
970                                    NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
971
972         if (fnum1 == -1) {
973                 torture_comment(tctx, "test 2 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
974                 CHECK_MAX_FAILURES(error_test20);
975                 return False;
976         }
977
978         fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
979                                    NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OPEN_IF, 0, 0);
980
981         if (fnum2 == -1) {
982                 torture_comment(tctx, "test 2 open 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
983                 CHECK_MAX_FAILURES(error_test20);
984                 return False;
985         }
986
987         if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
988                 torture_comment(tctx, "test 1 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
989                 return False;
990         }
991         if (NT_STATUS_IS_ERR(smbcli_close(cli2->tree, fnum2))) {
992                 torture_comment(tctx, "test 1 close 2 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
993                 return False;
994         }
995
996         torture_comment(tctx, "non-io open test #2 passed.\n");
997 error_test20:
998         smbcli_unlink(cli1->tree, fname);
999
1000         torture_comment(tctx, "TEST #3 testing 2 non-io opens (second with delete)\n");
1001         
1002         fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1003                                    NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
1004
1005         if (fnum1 == -1) {
1006                 torture_comment(tctx, "test 3 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1007                 CHECK_MAX_FAILURES(error_test30);
1008                 return False;
1009         }
1010
1011         fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, SEC_STD_DELETE|SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1012                                    NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OPEN_IF, 0, 0);
1013
1014         if (fnum2 == -1) {
1015                 torture_comment(tctx, "test 3 open 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1016                 CHECK_MAX_FAILURES(error_test30);
1017                 return False;
1018         }
1019
1020         if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1021                 torture_comment(tctx, "test 3 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1022                 return False;
1023         }
1024         if (NT_STATUS_IS_ERR(smbcli_close(cli2->tree, fnum2))) {
1025                 torture_comment(tctx, "test 3 close 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1026                 return False;
1027         }
1028
1029         torture_comment(tctx, "non-io open test #3 passed.\n");
1030 error_test30:
1031         smbcli_unlink(cli1->tree, fname);
1032
1033         torture_comment(tctx, "TEST #4 testing 2 non-io opens (both with delete)\n");
1034         
1035         fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SEC_STD_DELETE|SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1036                                    NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
1037
1038         if (fnum1 == -1) {
1039                 torture_comment(tctx, "test 4 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1040                 CHECK_MAX_FAILURES(error_test40);
1041                 return False;
1042         }
1043
1044         fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, SEC_STD_DELETE|SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1045                                    NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OPEN_IF, 0, 0);
1046
1047         if (fnum2 != -1) {
1048                 torture_comment(tctx, "test 4 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1049                 CHECK_MAX_FAILURES(error_test40);
1050                 return False;
1051         }
1052
1053         torture_comment(tctx, "test 4 open 2 of %s gave %s (correct error should be %s)\n", fname, smbcli_errstr(cli2->tree), "sharing violation");
1054
1055         if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1056                 torture_comment(tctx, "test 4 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1057                 return False;
1058         }
1059
1060         torture_comment(tctx, "non-io open test #4 passed.\n");
1061 error_test40:
1062         smbcli_unlink(cli1->tree, fname);
1063
1064         torture_comment(tctx, "TEST #5 testing 2 non-io opens (both with delete - both with file share delete)\n");
1065         
1066         fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SEC_STD_DELETE|SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1067                                    NTCREATEX_SHARE_ACCESS_DELETE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
1068
1069         if (fnum1 == -1) {
1070                 torture_comment(tctx, "test 5 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1071                 CHECK_MAX_FAILURES(error_test50);
1072                 return False;
1073         }
1074
1075         fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, SEC_STD_DELETE|SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1076                                    NTCREATEX_SHARE_ACCESS_DELETE, NTCREATEX_DISP_OPEN_IF, 0, 0);
1077
1078         if (fnum2 == -1) {
1079                 torture_comment(tctx, "test 5 open 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1080                 CHECK_MAX_FAILURES(error_test50);
1081                 return False;
1082         }
1083
1084         if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1085                 torture_comment(tctx, "test 5 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1086                 return False;
1087         }
1088
1089         if (NT_STATUS_IS_ERR(smbcli_close(cli2->tree, fnum2))) {
1090                 torture_comment(tctx, "test 5 close 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1091                 return False;
1092         }
1093
1094         torture_comment(tctx, "non-io open test #5 passed.\n");
1095 error_test50:
1096         torture_comment(tctx, "TEST #6 testing 1 non-io open, one io open\n");
1097         
1098         smbcli_unlink(cli1->tree, fname);
1099
1100         fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SEC_FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
1101                                    NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
1102
1103         if (fnum1 == -1) {
1104                 torture_comment(tctx, "test 6 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1105                 CHECK_MAX_FAILURES(error_test60);
1106                 return False;
1107         }
1108
1109         fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1110                                    NTCREATEX_SHARE_ACCESS_READ, NTCREATEX_DISP_OPEN_IF, 0, 0);
1111
1112         if (fnum2 == -1) {
1113                 torture_comment(tctx, "test 6 open 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1114                 CHECK_MAX_FAILURES(error_test60);
1115                 return False;
1116         }
1117
1118         if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1119                 torture_comment(tctx, "test 6 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1120                 return False;
1121         }
1122
1123         if (NT_STATUS_IS_ERR(smbcli_close(cli2->tree, fnum2))) {
1124                 torture_comment(tctx, "test 6 close 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1125                 return False;
1126         }
1127
1128         torture_comment(tctx, "non-io open test #6 passed.\n");
1129 error_test60:
1130         torture_comment(tctx, "TEST #7 testing 1 non-io open, one io open with delete\n");
1131
1132         smbcli_unlink(cli1->tree, fname);
1133
1134         fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SEC_FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
1135                                    NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
1136
1137         if (fnum1 == -1) {
1138                 torture_comment(tctx, "test 7 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1139                 CHECK_MAX_FAILURES(error_test70);
1140                 return False;
1141         }
1142
1143         fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, SEC_STD_DELETE|SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1144                                    NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_DELETE, NTCREATEX_DISP_OPEN_IF, 0, 0);
1145
1146         if (fnum2 != -1) {
1147                 torture_comment(tctx, "test 7 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1148                 CHECK_MAX_FAILURES(error_test70);
1149                 return False;
1150         }
1151
1152         torture_comment(tctx, "test 7 open 2 of %s gave %s (correct error should be %s)\n", fname, smbcli_errstr(cli2->tree), "sharing violation");
1153
1154         if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1155                 torture_comment(tctx, "test 7 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1156                 return False;
1157         }
1158
1159         torture_comment(tctx, "non-io open test #7 passed.\n");
1160
1161 error_test70:
1162
1163         torture_comment(tctx, "TEST #8 testing one normal open, followed by lock, followed by open with truncate\n");
1164
1165         smbcli_unlink(cli1->tree, fname);
1166
1167         fnum1 = smbcli_open(cli1->tree, fname, O_RDWR|O_CREAT, DENY_NONE);
1168         if (fnum1 == -1) {
1169                 torture_comment(tctx, "(8) open (1) of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1170                 return False;
1171         }
1172         
1173         /* write 20 bytes. */
1174         
1175         memset(buf, '\0', 20);
1176
1177         if (smbcli_write(cli1->tree, fnum1, 0, buf, 0, 20) != 20) {
1178                 torture_comment(tctx, "(8) write failed (%s)\n", smbcli_errstr(cli1->tree));
1179                 correct = False;
1180         }
1181
1182         /* Ensure size == 20. */
1183         if (NT_STATUS_IS_ERR(smbcli_getatr(cli1->tree, fname, NULL, &fsize, NULL))) {
1184                 torture_comment(tctx, "(8) getatr (1) failed (%s)\n", smbcli_errstr(cli1->tree));
1185                 CHECK_MAX_FAILURES(error_test80);
1186                 return False;
1187         }
1188         
1189         if (fsize != 20) {
1190                 torture_comment(tctx, "(8) file size != 20\n");
1191                 CHECK_MAX_FAILURES(error_test80);
1192                 return False;
1193         }
1194
1195         /* Get an exclusive lock on the open file. */
1196         if (NT_STATUS_IS_ERR(smbcli_lock(cli1->tree, fnum1, 0, 4, 0, WRITE_LOCK))) {
1197                 torture_comment(tctx, "(8) lock1 failed (%s)\n", smbcli_errstr(cli1->tree));
1198                 CHECK_MAX_FAILURES(error_test80);
1199                 return False;
1200         }
1201
1202         fnum2 = smbcli_open(cli1->tree, fname, O_RDWR|O_TRUNC, DENY_NONE);
1203         if (fnum1 == -1) {
1204                 torture_comment(tctx, "(8) open (2) of %s with truncate failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1205                 return False;
1206         }
1207
1208         /* Ensure size == 0. */
1209         if (NT_STATUS_IS_ERR(smbcli_getatr(cli1->tree, fname, NULL, &fsize, NULL))) {
1210                 torture_comment(tctx, "(8) getatr (2) failed (%s)\n", smbcli_errstr(cli1->tree));
1211                 CHECK_MAX_FAILURES(error_test80);
1212                 return False;
1213         }
1214         
1215         if (fsize != 0) {
1216                 torture_comment(tctx, "(8) file size != 0\n");
1217                 CHECK_MAX_FAILURES(error_test80);
1218                 return False;
1219         }
1220
1221         if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1222                 torture_comment(tctx, "(8) close1 failed (%s)\n", smbcli_errstr(cli1->tree));
1223                 return False;
1224         }
1225         
1226         if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum2))) {
1227                 torture_comment(tctx, "(8) close1 failed (%s)\n", smbcli_errstr(cli1->tree));
1228                 return False;
1229         }
1230         
1231 error_test80:
1232
1233         torture_comment(tctx, "open test #8 passed.\n");
1234
1235         smbcli_unlink(cli1->tree, fname);
1236
1237         return correct;
1238 }
1239
1240 /* FIRST_DESIRED_ACCESS   0xf019f */
1241 #define FIRST_DESIRED_ACCESS   SEC_FILE_READ_DATA|SEC_FILE_WRITE_DATA|SEC_FILE_APPEND_DATA|\
1242                                SEC_FILE_READ_EA|                           /* 0xf */ \
1243                                SEC_FILE_WRITE_EA|SEC_FILE_READ_ATTRIBUTE|     /* 0x90 */ \
1244                                SEC_FILE_WRITE_ATTRIBUTE|                  /* 0x100 */ \
1245                                SEC_STD_DELETE|SEC_STD_READ_CONTROL|\
1246                                SEC_STD_WRITE_DAC|SEC_STD_WRITE_OWNER     /* 0xf0000 */
1247 /* SECOND_DESIRED_ACCESS  0xe0080 */
1248 #define SECOND_DESIRED_ACCESS  SEC_FILE_READ_ATTRIBUTE|                   /* 0x80 */ \
1249                                SEC_STD_READ_CONTROL|SEC_STD_WRITE_DAC|\
1250                                SEC_STD_WRITE_OWNER                      /* 0xe0000 */
1251
1252 #if 0
1253 #define THIRD_DESIRED_ACCESS   FILE_READ_ATTRIBUTE|                   /* 0x80 */ \
1254                                READ_CONTROL|WRITE_DAC|\
1255                                SEC_FILE_READ_DATA|\
1256                                WRITE_OWNER                      /* */
1257 #endif
1258
1259
1260
1261 /**
1262   Test ntcreate calls made by xcopy
1263  */
1264 static bool run_xcopy(struct torture_context *tctx,
1265                                           struct smbcli_state *cli1)
1266 {
1267         const char *fname = "\\test.txt";
1268         int fnum1, fnum2;
1269
1270         fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0,
1271                                       FIRST_DESIRED_ACCESS, 
1272                                       FILE_ATTRIBUTE_ARCHIVE,
1273                                       NTCREATEX_SHARE_ACCESS_NONE, 
1274                                       NTCREATEX_DISP_OVERWRITE_IF, 
1275                                       0x4044, 0);
1276
1277         torture_assert(tctx, fnum1 != -1, talloc_asprintf(tctx, 
1278                                 "First open failed - %s", smbcli_errstr(cli1->tree)));
1279
1280         fnum2 = smbcli_nt_create_full(cli1->tree, fname, 0,
1281                                    SECOND_DESIRED_ACCESS, 0,
1282                                    NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE|NTCREATEX_SHARE_ACCESS_DELETE, NTCREATEX_DISP_OPEN, 
1283                                    0x200000, 0);
1284         torture_assert(tctx, fnum2 != -1, talloc_asprintf(tctx, 
1285                                 "second open failed - %s", smbcli_errstr(cli1->tree)));
1286         
1287         return true;
1288 }
1289
1290 static bool run_iometer(struct torture_context *tctx,
1291                                                 struct smbcli_state *cli)
1292 {
1293         const char *fname = "\\iobw.tst";
1294         int fnum;
1295         size_t filesize;
1296         NTSTATUS status;
1297         char buf[2048];
1298         int ops;
1299
1300         memset(buf, 0, sizeof(buf));
1301
1302         status = smbcli_getatr(cli->tree, fname, NULL, &filesize, NULL);
1303         torture_assert_ntstatus_ok(tctx, status, 
1304                 talloc_asprintf(tctx, "smbcli_getatr failed: %s", nt_errstr(status)));
1305
1306         torture_comment(tctx, "size: %d\n", (int)filesize);
1307
1308         filesize -= (sizeof(buf) - 1);
1309
1310         fnum = smbcli_nt_create_full(cli->tree, fname, 0x16,
1311                                      0x2019f, 0, 0x3, 3, 0x42, 0x3);
1312         torture_assert(tctx, fnum != -1, talloc_asprintf(tctx, "open failed: %s", 
1313                                    smbcli_errstr(cli->tree)));
1314
1315         ops = 0;
1316
1317         while (True) {
1318                 int i, num_reads, num_writes;
1319
1320                 num_reads = random() % 10;
1321                 num_writes = random() % 3;
1322
1323                 for (i=0; i<num_reads; i++) {
1324                         ssize_t res;
1325                         if (ops++ > torture_numops) {
1326                                 return true;
1327                         }
1328                         res = smbcli_read(cli->tree, fnum, buf,
1329                                           random() % filesize, sizeof(buf));
1330                         torture_assert(tctx, res == sizeof(buf), 
1331                                                    talloc_asprintf(tctx, "read failed: %s",
1332                                                                                    smbcli_errstr(cli->tree)));
1333                 }
1334                 for (i=0; i<num_writes; i++) {
1335                         ssize_t res;
1336                         if (ops++ > torture_numops) {
1337                                 return true;
1338                         }
1339                         res = smbcli_write(cli->tree, fnum, 0, buf,
1340                                           random() % filesize, sizeof(buf));
1341                         torture_assert(tctx, res == sizeof(buf),
1342                                                    talloc_asprintf(tctx, "read failed: %s",
1343                                        smbcli_errstr(cli->tree)));
1344                 }
1345         }
1346
1347         return true;
1348 }
1349
1350 /**
1351   tries variants of chkpath
1352  */
1353 static BOOL torture_chkpath_test(struct torture_context *tctx, 
1354                                                                  struct smbcli_state *cli)
1355 {
1356         int fnum;
1357         BOOL ret;
1358
1359         torture_comment(tctx, "Testing valid and invalid paths\n");
1360
1361         /* cleanup from an old run */
1362         smbcli_rmdir(cli->tree, "\\chkpath.dir\\dir2");
1363         smbcli_unlink(cli->tree, "\\chkpath.dir\\*");
1364         smbcli_rmdir(cli->tree, "\\chkpath.dir");
1365
1366         if (NT_STATUS_IS_ERR(smbcli_mkdir(cli->tree, "\\chkpath.dir"))) {
1367                 torture_comment(tctx, "mkdir1 failed : %s\n", smbcli_errstr(cli->tree));
1368                 return False;
1369         }
1370
1371         if (NT_STATUS_IS_ERR(smbcli_mkdir(cli->tree, "\\chkpath.dir\\dir2"))) {
1372                 torture_comment(tctx, "mkdir2 failed : %s\n", smbcli_errstr(cli->tree));
1373                 return False;
1374         }
1375
1376         fnum = smbcli_open(cli->tree, "\\chkpath.dir\\foo.txt", O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1377         if (fnum == -1) {
1378                 torture_comment(tctx, "open1 failed (%s)\n", smbcli_errstr(cli->tree));
1379                 return False;
1380         }
1381         smbcli_close(cli->tree, fnum);
1382
1383         if (NT_STATUS_IS_ERR(smbcli_chkpath(cli->tree, "\\chkpath.dir"))) {
1384                 torture_comment(tctx, "chkpath1 failed: %s\n", smbcli_errstr(cli->tree));
1385                 ret = False;
1386         }
1387
1388         if (NT_STATUS_IS_ERR(smbcli_chkpath(cli->tree, "\\chkpath.dir\\dir2"))) {
1389                 torture_comment(tctx, "chkpath2 failed: %s\n", smbcli_errstr(cli->tree));
1390                 ret = False;
1391         }
1392
1393         if (NT_STATUS_IS_ERR(smbcli_chkpath(cli->tree, "\\chkpath.dir\\foo.txt"))) {
1394                 ret = check_error(__location__, cli, ERRDOS, ERRbadpath, 
1395                                   NT_STATUS_NOT_A_DIRECTORY);
1396         } else {
1397                 torture_comment(tctx, "* chkpath on a file should fail\n");
1398                 ret = False;
1399         }
1400
1401         if (NT_STATUS_IS_ERR(smbcli_chkpath(cli->tree, "\\chkpath.dir\\bar.txt"))) {
1402                 ret = check_error(__location__, cli, ERRDOS, ERRbadpath, 
1403                                   NT_STATUS_OBJECT_NAME_NOT_FOUND);
1404         } else {
1405                 torture_comment(tctx, "* chkpath on a non existent file should fail\n");
1406                 ret = False;
1407         }
1408
1409         if (NT_STATUS_IS_ERR(smbcli_chkpath(cli->tree, "\\chkpath.dir\\dirxx\\bar.txt"))) {
1410                 ret = check_error(__location__, cli, ERRDOS, ERRbadpath, 
1411                                   NT_STATUS_OBJECT_PATH_NOT_FOUND);
1412         } else {
1413                 torture_comment(tctx, "* chkpath on a non existent component should fail\n");
1414                 ret = False;
1415         }
1416
1417         smbcli_rmdir(cli->tree, "\\chkpath.dir\\dir2");
1418         smbcli_unlink(cli->tree, "\\chkpath.dir\\*");
1419         smbcli_rmdir(cli->tree, "\\chkpath.dir");
1420
1421         return ret;
1422 }
1423
1424 /*
1425  * This is a test to excercise some weird Samba3 error paths.
1426  */
1427
1428 static BOOL torture_samba3_errorpaths(struct torture_context *tctx)
1429 {
1430         BOOL nt_status_support;
1431         struct smbcli_state *cli_nt = NULL, *cli_dos = NULL;
1432         BOOL result = False;
1433         int fnum;
1434         const char *os2_fname = ".+,;=[].";
1435         const char *dname = "samba3_errordir";
1436         union smb_open io;
1437         TALLOC_CTX *mem_ctx = talloc_init("samba3_errorpaths");
1438         NTSTATUS status;
1439
1440         if (mem_ctx == NULL) {
1441                 torture_comment(tctx, "talloc_init failed\n");
1442                 return False;
1443         }
1444
1445         nt_status_support = lp_nt_status_support();
1446
1447         if (!lp_set_cmdline("nt status support", "yes")) {
1448                 torture_comment(tctx, "Could not set 'nt status support = yes'\n");
1449                 goto fail;
1450         }
1451
1452         if (!torture_open_connection(&cli_nt, 0)) {
1453                 goto fail;
1454         }
1455
1456         if (!lp_set_cmdline("nt status support", "no")) {
1457                 torture_comment(tctx, "Could not set 'nt status support = yes'\n");
1458                 goto fail;
1459         }
1460
1461         if (!torture_open_connection(&cli_dos, 1)) {
1462                 goto fail;
1463         }
1464
1465         if (!lp_set_cmdline("nt status support",
1466                             nt_status_support ? "yes":"no")) {
1467                 torture_comment(tctx, "Could not reset 'nt status support = yes'");
1468                 goto fail;
1469         }
1470
1471         smbcli_unlink(cli_nt->tree, os2_fname);
1472         smbcli_rmdir(cli_nt->tree, dname);
1473
1474         if (!NT_STATUS_IS_OK(smbcli_mkdir(cli_nt->tree, dname))) {
1475                 torture_comment(tctx, "smbcli_mkdir(%s) failed: %s\n", dname,
1476                        smbcli_errstr(cli_nt->tree));
1477                 goto fail;
1478         }
1479
1480         io.generic.level = RAW_OPEN_NTCREATEX;
1481         io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED;
1482         io.ntcreatex.in.root_fid = 0;
1483         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1484         io.ntcreatex.in.alloc_size = 1024*1024;
1485         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_DIRECTORY;
1486         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1487         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
1488         io.ntcreatex.in.create_options = 0;
1489         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1490         io.ntcreatex.in.security_flags = 0;
1491         io.ntcreatex.in.fname = dname;
1492
1493         status = smb_raw_open(cli_nt->tree, mem_ctx, &io);
1494         if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_COLLISION)) {
1495                 torture_comment(tctx, "(%s) incorrect status %s should be %s\n",
1496                        __location__, nt_errstr(status),
1497                        nt_errstr(NT_STATUS_OBJECT_NAME_COLLISION));
1498                 goto fail;
1499         }
1500         status = smb_raw_open(cli_dos->tree, mem_ctx, &io);
1501         if (!NT_STATUS_EQUAL(status, NT_STATUS_DOS(ERRDOS, ERRfilexists))) {
1502                 torture_comment(tctx, "(%s) incorrect status %s should be %s\n",
1503                        __location__, nt_errstr(status),
1504                        nt_errstr(NT_STATUS_DOS(ERRDOS, ERRfilexists)));
1505                 goto fail;
1506         }
1507
1508         status = smbcli_mkdir(cli_nt->tree, dname);
1509         if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_COLLISION)) {
1510                 torture_comment(tctx, "(%s) incorrect status %s should be %s\n",
1511                        __location__, nt_errstr(status),
1512                        nt_errstr(NT_STATUS_OBJECT_NAME_COLLISION));
1513                 goto fail;
1514         }
1515         status = smbcli_mkdir(cli_dos->tree, dname);
1516         if (!NT_STATUS_EQUAL(status, NT_STATUS_DOS(ERRDOS, ERRnoaccess))) {
1517                 torture_comment(tctx, "(%s) incorrect status %s should be %s\n",
1518                        __location__, nt_errstr(status),
1519                        nt_errstr(NT_STATUS_DOS(ERRDOS, ERRnoaccess)));
1520                 goto fail;
1521         }
1522
1523         {
1524                 union smb_mkdir md;
1525                 md.t2mkdir.level = RAW_MKDIR_T2MKDIR;
1526                 md.t2mkdir.in.path = dname;
1527                 md.t2mkdir.in.num_eas = 0;
1528                 md.t2mkdir.in.eas = NULL;
1529
1530                 status = smb_raw_mkdir(cli_nt->tree, &md);
1531                 if (!NT_STATUS_EQUAL(status,
1532                                      NT_STATUS_OBJECT_NAME_COLLISION)) {
1533                         torture_comment(
1534                                 tctx, "(%s) incorrect status %s should be "
1535                                 "NT_STATUS_OBJECT_NAME_COLLISION\n",
1536                                 __location__, nt_errstr(status));
1537                         goto fail;
1538                 }
1539                 status = smb_raw_mkdir(cli_dos->tree, &md);
1540                 if (!NT_STATUS_EQUAL(status,
1541                                      NT_STATUS_DOS(ERRDOS, ERRrename))) {
1542                         torture_comment(tctx, "(%s) incorrect status %s "
1543                                         "should be ERRDOS:ERRrename\n",
1544                                         __location__, nt_errstr(status));
1545                         goto fail;
1546                 }
1547         }
1548
1549         io.ntcreatex.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
1550         status = smb_raw_open(cli_nt->tree, mem_ctx, &io);
1551         if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_COLLISION)) {
1552                 torture_comment(tctx, "(%s) incorrect status %s should be %s\n",
1553                        __location__, nt_errstr(status),
1554                        nt_errstr(NT_STATUS_OBJECT_NAME_COLLISION));
1555                 goto fail;
1556         }
1557
1558         status = smb_raw_open(cli_dos->tree, mem_ctx, &io);
1559         if (!NT_STATUS_EQUAL(status, NT_STATUS_DOS(ERRDOS, ERRfilexists))) {
1560                 torture_comment(tctx, "(%s) incorrect status %s should be %s\n",
1561                        __location__, nt_errstr(status),
1562                        nt_errstr(NT_STATUS_DOS(ERRDOS, ERRfilexists)));
1563                 goto fail;
1564         }
1565
1566         {
1567                 /* Test an invalid DOS deny mode */
1568                 const char *fname = "test.txt";
1569
1570                 fnum = smbcli_open(cli_nt->tree, fname, O_RDWR | O_CREAT, 5);
1571                 if (fnum != -1) {
1572                         torture_comment(tctx, "Open(%s) with invalid deny mode succeeded -- "
1573                                "expected failure\n", fname);
1574                         smbcli_close(cli_nt->tree, fnum);
1575                         goto fail;
1576                 }
1577                 if (!NT_STATUS_EQUAL(smbcli_nt_error(cli_nt->tree),
1578                                      NT_STATUS_DOS(ERRDOS,ERRbadaccess))) {
1579                         torture_comment(tctx, "Expected DOS error ERRDOS/ERRbadaccess, "
1580                                "got %s\n", smbcli_errstr(cli_nt->tree));
1581                         goto fail;
1582                 }
1583
1584                 fnum = smbcli_open(cli_dos->tree, fname, O_RDWR | O_CREAT, 5);
1585                 if (fnum != -1) {
1586                         torture_comment(tctx, "Open(%s) with invalid deny mode succeeded -- "
1587                                "expected failure\n", fname);
1588                         smbcli_close(cli_nt->tree, fnum);
1589                         goto fail;
1590                 }
1591                 if (!NT_STATUS_EQUAL(smbcli_nt_error(cli_nt->tree),
1592                                      NT_STATUS_DOS(ERRDOS,ERRbadaccess))) {
1593                         torture_comment(tctx, "Expected DOS error ERRDOS:ERRbadaccess, "
1594                                "got %s\n", smbcli_errstr(cli_nt->tree));
1595                         goto fail;
1596                 }
1597         }
1598
1599         {
1600                 /*
1601                  * Samba 3.0.23 has a bug that an existing file can be opened
1602                  * as a directory using ntcreate&x. Test this.
1603                  */
1604
1605                 const char *fname = "\\test_dir.txt";
1606
1607                 fnum = smbcli_open(cli_nt->tree, fname, O_RDWR|O_CREAT,
1608                                    DENY_NONE);
1609                 if (fnum == -1) {
1610                         d_printf("(%s) smbcli_open failed: %s\n", __location__,
1611                                  smbcli_errstr(cli_nt->tree));
1612                 }
1613                 smbcli_close(cli_nt->tree, fnum);
1614
1615                 io.generic.level = RAW_OPEN_NTCREATEX;
1616                 io.ntcreatex.in.root_fid = 0;
1617                 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1618                 io.ntcreatex.in.alloc_size = 0;
1619                 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_DIRECTORY;
1620                 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
1621                         NTCREATEX_SHARE_ACCESS_WRITE|
1622                         NTCREATEX_SHARE_ACCESS_DELETE;
1623                 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
1624                 io.ntcreatex.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
1625                 io.ntcreatex.in.impersonation =
1626                         NTCREATEX_IMPERSONATION_ANONYMOUS;
1627                 io.ntcreatex.in.security_flags = 0;
1628                 io.ntcreatex.in.fname = fname;
1629                 io.ntcreatex.in.flags = 0;
1630
1631                 status = smb_raw_open(cli_nt->tree, mem_ctx, &io);
1632                 if (!NT_STATUS_EQUAL(status, NT_STATUS_NOT_A_DIRECTORY)) {
1633                         torture_comment(tctx, "ntcreate as dir gave %s, "
1634                                         "expected NT_STATUS_NOT_A_DIRECTORY\n",
1635                                         nt_errstr(status));
1636                         result = False;
1637                 }
1638
1639                 if (NT_STATUS_IS_OK(status)) {
1640                         smbcli_close(cli_nt->tree, io.ntcreatex.out.file.fnum);
1641                 }
1642
1643                 status = smb_raw_open(cli_dos->tree, mem_ctx, &io);
1644                 if (!NT_STATUS_EQUAL(status, NT_STATUS_DOS(ERRDOS,
1645                                                            ERRbaddirectory))) {
1646                         torture_comment(tctx, "ntcreate as dir gave %s, "
1647                                         "expected NT_STATUS_NOT_A_DIRECTORY\n",
1648                                         nt_errstr(status));
1649                         result = False;
1650                 }
1651
1652                 if (NT_STATUS_IS_OK(status)) {
1653                         smbcli_close(cli_dos->tree,
1654                                      io.ntcreatex.out.file.fnum);
1655                 }
1656
1657                 smbcli_unlink(cli_nt->tree, fname);
1658         }
1659
1660         if (!torture_setting_bool(tctx, "samba3", False)) {
1661                 goto done;
1662         }
1663
1664         fnum = smbcli_open(cli_dos->tree, os2_fname, 
1665                            O_RDWR | O_CREAT | O_TRUNC,
1666                            DENY_NONE);
1667         if (fnum != -1) {
1668                 torture_comment(tctx, "Open(%s) succeeded -- expected failure\n",
1669                        os2_fname);
1670                 smbcli_close(cli_dos->tree, fnum);
1671                 goto fail;
1672         }
1673
1674         if (!NT_STATUS_EQUAL(smbcli_nt_error(cli_dos->tree),
1675                              NT_STATUS_DOS(ERRDOS, ERRcannotopen))) {
1676                 torture_comment(tctx, "Expected DOS error ERRDOS/ERRcannotopen, got %s\n",
1677                        smbcli_errstr(cli_dos->tree));
1678                 goto fail;
1679         }
1680
1681         fnum = smbcli_open(cli_nt->tree, os2_fname, 
1682                            O_RDWR | O_CREAT | O_TRUNC,
1683                            DENY_NONE);
1684         if (fnum != -1) {
1685                 torture_comment(tctx, "Open(%s) succeeded -- expected failure\n",
1686                        os2_fname);
1687                 smbcli_close(cli_nt->tree, fnum);
1688                 goto fail;
1689         }
1690
1691         if (!NT_STATUS_EQUAL(smbcli_nt_error(cli_nt->tree),
1692                              NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
1693                 torture_comment(tctx, "Expected error NT_STATUS_OBJECT_NAME_NOT_FOUND, "
1694                        "got %s\n", smbcli_errstr(cli_nt->tree));
1695                 goto fail;
1696         }
1697
1698  done:
1699         result = True;
1700
1701  fail:
1702         if (cli_dos != NULL) {
1703                 torture_close_connection(cli_dos);
1704         }
1705         if (cli_nt != NULL) {
1706                 torture_close_connection(cli_nt);
1707         }
1708         
1709         return result;
1710 }
1711
1712
1713 NTSTATUS torture_base_init(void)
1714 {
1715         struct torture_suite *suite = torture_suite_create(talloc_autofree_context(), "BASE");
1716
1717         torture_suite_add_2smb_test(suite, "FDPASS", run_fdpasstest);
1718         torture_suite_add_suite(suite, torture_base_locktest(suite));
1719         torture_suite_add_1smb_test(suite, "UNLINK", torture_unlinktest);
1720         torture_suite_add_1smb_test(suite, "ATTR",   run_attrtest);
1721         torture_suite_add_1smb_test(suite, "TRANS2", run_trans2test);
1722         torture_suite_add_simple_test(suite, "NEGNOWAIT", run_negprot_nowait);
1723         torture_suite_add_1smb_test(suite, "DIR1",  torture_dirtest1);
1724         torture_suite_add_1smb_test(suite, "DIR2",  torture_dirtest2);
1725         torture_suite_add_1smb_test(suite, "DENY1",  torture_denytest1);
1726         torture_suite_add_2smb_test(suite, "DENY2",  torture_denytest2);
1727         torture_suite_add_2smb_test(suite, "DENY3",  torture_denytest3);
1728         torture_suite_add_1smb_test(suite, "DENYDOS",  torture_denydos_sharing);
1729         torture_suite_add_smb_multi_test(suite, "NTDENY1", torture_ntdenytest1);
1730         torture_suite_add_2smb_test(suite, "NTDENY2",  torture_ntdenytest2);
1731         torture_suite_add_1smb_test(suite, "TCON",  run_tcon_test);
1732         torture_suite_add_1smb_test(suite, "TCONDEV",  run_tcon_devtype_test);
1733         torture_suite_add_1smb_test(suite, "VUID", run_vuidtest);
1734         torture_suite_add_2smb_test(suite, "RW1",  run_readwritetest);
1735         torture_suite_add_2smb_test(suite, "OPEN", run_opentest);
1736         torture_suite_add_smb_multi_test(suite, "DEFER_OPEN", run_deferopen);
1737         torture_suite_add_1smb_test(suite, "XCOPY", run_xcopy);
1738         torture_suite_add_1smb_test(suite, "IOMETER", run_iometer);
1739         torture_suite_add_1smb_test(suite, "RENAME", torture_test_rename);
1740         torture_suite_add_suite(suite, torture_test_delete());
1741         torture_suite_add_1smb_test(suite, "PROPERTIES", torture_test_properties);
1742         torture_suite_add_1smb_test(suite, "MANGLE", torture_mangle);
1743         torture_suite_add_1smb_test(suite, "OPENATTR", torture_openattrtest);
1744         torture_suite_add_suite(suite, torture_charset(suite));
1745         torture_suite_add_1smb_test(suite, "CHKPATH",  torture_chkpath_test);
1746         torture_suite_add_1smb_test(suite, "SECLEAK",  torture_sec_leak);
1747         torture_suite_add_simple_test(suite, "DISCONNECT",  torture_disconnect);
1748         torture_suite_add_suite(suite, torture_delay_write());
1749         torture_suite_add_simple_test(suite, "SAMBA3ERROR", torture_samba3_errorpaths);
1750         torture_suite_add_1smb_test(suite, "CASETABLE", torture_casetable);
1751         torture_suite_add_1smb_test(suite, "UTABLE", torture_utable);
1752         torture_suite_add_simple_test(suite, "SMB", torture_smb_scan);
1753         torture_suite_add_suite(suite, torture_trans2_aliases(suite));
1754         torture_suite_add_1smb_test(suite, "TRANS2-SCAN", torture_trans2_scan);
1755         torture_suite_add_1smb_test(suite, "NTTRANS", torture_nttrans_scan);
1756
1757         torture_suite_add_simple_test(suite, "BENCH-HOLDCON", torture_holdcon);
1758         torture_suite_add_simple_test(suite, "BENCH-READWRITE", run_benchrw);
1759         torture_suite_add_smb_multi_test(suite, "BENCH-TORTURE", run_torture);
1760         torture_suite_add_1smb_test(suite, "SCAN-PIPE_NUMBER", run_pipe_number);
1761         torture_suite_add_1smb_test(suite, "SCAN-IOCTL", torture_ioctl_test);
1762         torture_suite_add_smb_multi_test(suite, "SCAN-MAXFID", run_maxfidtest);
1763
1764         suite->description = talloc_strdup(suite, 
1765                                         "Basic SMB tests (imported from the original smbtorture)");
1766
1767         torture_register_suite(suite);
1768
1769         return NT_STATUS_OK;
1770 }