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