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