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