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