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