lib: modules: Change XXX_init interface from XXX_init(void) to XXX_init(TALLOC_CTX *)
[gd/samba-autobuild/.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         control_char_fname = talloc_strdup(tctx, "\\readonly.afile");
828         torture_assert_not_null(tctx, control_char_fname, "asprintf failed\n");
829
830         for (i = 1; i <= 0x1f; i++) {
831                 control_char_fname[10] = i;
832                 fnum1 = smbcli_nt_create_full(cli1->tree, control_char_fname, 0, SEC_FILE_WRITE_DATA, FILE_ATTRIBUTE_NORMAL,
833                                    NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
834                 
835                 if (!check_error(__location__, cli1, ERRDOS, ERRinvalidname, 
836                                 NT_STATUS_OBJECT_NAME_INVALID)) {
837                         torture_result(tctx, TORTURE_FAIL, "Error code should be NT_STATUS_OBJECT_NAME_INVALID, was %s for file with %d char\n",
838                                         smbcli_errstr(cli1->tree), i);
839                         failures++;
840                 }
841
842                 if (fnum1 != -1) {
843                         smbcli_close(cli1->tree, fnum1);
844                 }
845                 smbcli_setatr(cli1->tree, control_char_fname, 0, 0);
846                 smbcli_unlink(cli1->tree, control_char_fname);
847         }
848         TALLOC_FREE(control_char_fname);
849
850         if (!failures)
851                 torture_comment(tctx, "Create file with control char names passed.\n");
852
853         smbcli_setatr(cli1->tree, fname, 0, 0);
854         smbcli_unlink(cli1->tree, fname);
855         
856         fnum1 = smbcli_open(cli1->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
857         if (fnum1 == -1) {
858                 torture_result(tctx, TORTURE_FAIL, "open of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
859                 return false;
860         }
861
862         if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
863                 torture_result(tctx, TORTURE_FAIL, "close2 failed (%s)\n", smbcli_errstr(cli1->tree));
864                 return false;
865         }
866         
867         if (NT_STATUS_IS_ERR(smbcli_setatr(cli1->tree, fname, FILE_ATTRIBUTE_READONLY, 0))) {
868                 torture_result(tctx, TORTURE_FAIL,
869                         __location__ ": smbcli_setatr failed (%s)\n", smbcli_errstr(cli1->tree));
870                 CHECK_MAX_FAILURES(error_test1);
871                 return false;
872         }
873         
874         fnum1 = smbcli_open(cli1->tree, fname, O_RDONLY, DENY_WRITE);
875         if (fnum1 == -1) {
876                 torture_result(tctx, TORTURE_FAIL,
877                         __location__ ": open of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
878                 CHECK_MAX_FAILURES(error_test1);
879                 return false;
880         }
881         
882         /* This will fail - but the error should be ERRnoaccess, not ERRbadshare. */
883         fnum2 = smbcli_open(cli1->tree, fname, O_RDWR, DENY_ALL);
884         
885         if (check_error(__location__, cli1, ERRDOS, ERRnoaccess, 
886                         NT_STATUS_ACCESS_DENIED)) {
887                 torture_comment(tctx, "correct error code ERRDOS/ERRnoaccess returned\n");
888         }
889         
890         torture_comment(tctx, "finished open test 1\n");
891
892 error_test1:
893         smbcli_close(cli1->tree, fnum1);
894         
895         /* Now try not readonly and ensure ERRbadshare is returned. */
896         
897         smbcli_setatr(cli1->tree, fname, 0, 0);
898         
899         fnum1 = smbcli_open(cli1->tree, fname, O_RDONLY, DENY_WRITE);
900         if (fnum1 == -1) {
901                 torture_result(tctx, TORTURE_FAIL, "open of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
902                 return false;
903         }
904         
905         /* This will fail - but the error should be ERRshare. */
906         fnum2 = smbcli_open(cli1->tree, fname, O_RDWR, DENY_ALL);
907         
908         if (check_error(__location__, cli1, ERRDOS, ERRbadshare, 
909                         NT_STATUS_SHARING_VIOLATION)) {
910                 torture_comment(tctx, "correct error code ERRDOS/ERRbadshare returned\n");
911         }
912         
913         if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
914                 torture_result(tctx, TORTURE_FAIL, "close2 failed (%s)\n", smbcli_errstr(cli1->tree));
915                 return false;
916         }
917         
918         smbcli_unlink(cli1->tree, fname);
919         
920         torture_comment(tctx, "finished open test 2\n");
921         
922         /* Test truncate open disposition on file opened for read. */
923         
924         fnum1 = smbcli_open(cli1->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
925         if (fnum1 == -1) {
926                 torture_result(tctx, TORTURE_FAIL, "(3) open (1) of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
927                 return false;
928         }
929         
930         /* write 20 bytes. */
931         
932         memset(buf, '\0', 20);
933
934         if (smbcli_write(cli1->tree, fnum1, 0, buf, 0, 20) != 20) {
935                 torture_result(tctx, TORTURE_FAIL, "write failed (%s)\n", smbcli_errstr(cli1->tree));
936                 correct = false;
937         }
938
939         if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
940                 torture_result(tctx, TORTURE_FAIL, "(3) close1 failed (%s)\n", smbcli_errstr(cli1->tree));
941                 return false;
942         }
943         
944         /* Ensure size == 20. */
945         if (NT_STATUS_IS_ERR(smbcli_getatr(cli1->tree, fname, NULL, &fsize, NULL))) {
946                 torture_result(tctx, TORTURE_FAIL,
947                         __location__ ": (3) getatr failed (%s)\n", smbcli_errstr(cli1->tree));
948                 CHECK_MAX_FAILURES(error_test3);
949                 return false;
950         }
951         
952         if (fsize != 20) {
953                 torture_result(tctx, TORTURE_FAIL,
954                         __location__ ": (3) file size != 20\n");
955                 CHECK_MAX_FAILURES(error_test3);
956                 return false;
957         }
958
959         /* Now test if we can truncate a file opened for readonly. */
960         
961         fnum1 = smbcli_open(cli1->tree, fname, O_RDONLY|O_TRUNC, DENY_NONE);
962         if (fnum1 == -1) {
963                 torture_result(tctx, TORTURE_FAIL,
964                         __location__ ": (3) open (2) of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
965                 CHECK_MAX_FAILURES(error_test3);
966                 return false;
967         }
968         
969         if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
970                 torture_result(tctx, TORTURE_FAIL,
971                         __location__ ": close2 failed (%s)\n", smbcli_errstr(cli1->tree));
972                 return false;
973         }
974
975         /* Ensure size == 0. */
976         if (NT_STATUS_IS_ERR(smbcli_getatr(cli1->tree, fname, NULL, &fsize, NULL))) {
977                 torture_result(tctx, TORTURE_FAIL,
978                         __location__ ": (3) getatr failed (%s)\n", smbcli_errstr(cli1->tree));
979                 CHECK_MAX_FAILURES(error_test3);
980                 return false;
981         }
982
983         if (fsize != 0) {
984                 torture_result(tctx, TORTURE_FAIL,
985                         __location__ ": (3) file size != 0\n");
986                 CHECK_MAX_FAILURES(error_test3);
987                 return false;
988         }
989         torture_comment(tctx, "finished open test 3\n");
990 error_test3:    
991
992         fnum1 = fnum2 = -1;
993         smbcli_unlink(cli1->tree, fname);
994
995
996         torture_comment(tctx, "Testing ctemp\n");
997         fnum1 = smbcli_ctemp(cli1->tree, "\\", &tmp_path);
998         if (fnum1 == -1) {
999                 torture_result(tctx, TORTURE_FAIL,
1000                         __location__ ": ctemp failed (%s)\n", smbcli_errstr(cli1->tree));
1001                 CHECK_MAX_FAILURES(error_test4);
1002                 return false;
1003         }
1004         torture_comment(tctx, "ctemp gave path %s\n", tmp_path);
1005
1006 error_test4:
1007         if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1008                 torture_comment(tctx, "close of temp failed (%s)\n", smbcli_errstr(cli1->tree));
1009         }
1010         if (NT_STATUS_IS_ERR(smbcli_unlink(cli1->tree, tmp_path))) {
1011                 torture_comment(tctx, "unlink of temp failed (%s)\n", smbcli_errstr(cli1->tree));
1012         }
1013
1014         /* Test the non-io opens... */
1015
1016         torture_comment(tctx, "Test #1 testing 2 non-io opens (no delete)\n");
1017         fnum1 = fnum2 = -1;
1018         smbcli_setatr(cli2->tree, fname, 0, 0);
1019         smbcli_unlink(cli2->tree, fname);
1020
1021         fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1022                                    NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
1023
1024         if (fnum1 == -1) {
1025                 torture_result(tctx, TORTURE_FAIL,
1026                         __location__ ": Test 1 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1027                 CHECK_MAX_FAILURES(error_test10);
1028                 return false;
1029         }
1030
1031         fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1032                                    NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OPEN_IF, 0, 0);
1033         if (fnum2 == -1) {
1034                 torture_result(tctx, TORTURE_FAIL,
1035                         __location__ ": Test 1 open 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1036                 CHECK_MAX_FAILURES(error_test10);
1037                 return false;
1038         }
1039
1040         torture_comment(tctx, "non-io open test #1 passed.\n");
1041 error_test10:
1042
1043         if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1044                 torture_comment(tctx, "Test 1 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1045         }
1046         if (NT_STATUS_IS_ERR(smbcli_close(cli2->tree, fnum2))) {
1047                 torture_comment(tctx, "Test 1 close 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1048         }
1049
1050         torture_comment(tctx, "Test #2 testing 2 non-io opens (first with delete)\n");
1051         fnum1 = fnum2 = -1;
1052         smbcli_unlink(cli1->tree, fname);
1053
1054         fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SEC_STD_DELETE|SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1055                                    NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
1056
1057         if (fnum1 == -1) {
1058                 torture_result(tctx, TORTURE_FAIL,
1059                         __location__ ": Test 2 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1060                 CHECK_MAX_FAILURES(error_test20);
1061                 return false;
1062         }
1063
1064         fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1065                                    NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OPEN_IF, 0, 0);
1066
1067         if (fnum2 == -1) {
1068                 torture_result(tctx, TORTURE_FAIL,
1069                         __location__ ": Test 2 open 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1070                 CHECK_MAX_FAILURES(error_test20);
1071                 return false;
1072         }
1073
1074         torture_comment(tctx, "non-io open test #2 passed.\n");
1075 error_test20:
1076
1077         if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1078                 torture_comment(tctx, "Test 1 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1079         }
1080         if (NT_STATUS_IS_ERR(smbcli_close(cli2->tree, fnum2))) {
1081                 torture_comment(tctx, "Test 1 close 2 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1082         }
1083
1084         fnum1 = fnum2 = -1;
1085         smbcli_unlink(cli1->tree, fname);
1086
1087         torture_comment(tctx, "Test #3 testing 2 non-io opens (second with delete)\n");
1088
1089         fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1090                                    NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
1091
1092         if (fnum1 == -1) {
1093                 torture_result(tctx, TORTURE_FAIL,
1094                         __location__ ": Test 3 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1095                 CHECK_MAX_FAILURES(error_test30);
1096                 return false;
1097         }
1098
1099         fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, SEC_STD_DELETE|SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1100                                    NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OPEN_IF, 0, 0);
1101
1102         if (fnum2 == -1) {
1103                 torture_result(tctx, TORTURE_FAIL,
1104                         __location__ ": Test 3 open 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1105                 CHECK_MAX_FAILURES(error_test30);
1106                 return false;
1107         }
1108
1109         torture_comment(tctx, "non-io open test #3 passed.\n");
1110 error_test30:
1111
1112         if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1113                 torture_comment(tctx, "Test 3 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1114         }
1115         if (NT_STATUS_IS_ERR(smbcli_close(cli2->tree, fnum2))) {
1116                 torture_comment(tctx, "Test 3 close 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1117         }
1118
1119         torture_comment(tctx, "Test #4 testing 2 non-io opens (both with delete)\n");
1120         fnum1 = fnum2 = -1;
1121         smbcli_unlink(cli1->tree, fname);
1122
1123         fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SEC_STD_DELETE|SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1124                                    NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
1125
1126         if (fnum1 == -1) {
1127                 torture_result(tctx, TORTURE_FAIL,
1128                         __location__ ": Test 4 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1129                 CHECK_MAX_FAILURES(error_test40);
1130                 return false;
1131         }
1132
1133         fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, SEC_STD_DELETE|SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1134                                    NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OPEN_IF, 0, 0);
1135
1136         if (fnum2 != -1) {
1137                 torture_result(tctx, TORTURE_FAIL,
1138                         __location__ ": Test 4 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1139                 CHECK_MAX_FAILURES(error_test40);
1140                 return false;
1141         }
1142
1143         torture_comment(tctx, "Test 4 open 2 of %s gave %s (correct error should be %s)\n", fname, smbcli_errstr(cli2->tree), "sharing violation");
1144
1145         torture_comment(tctx, "non-io open test #4 passed.\n");
1146 error_test40:
1147
1148         if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1149                 torture_comment(tctx, "Test 4 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1150         }
1151         if (fnum2 != -1 && NT_STATUS_IS_ERR(smbcli_close(cli2->tree, fnum2))) {
1152                 torture_comment(tctx, "Test 4 close 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1153         }
1154
1155         torture_comment(tctx, "Test #5 testing 2 non-io opens (both with delete - both with file share delete)\n");
1156         fnum1 = fnum2 = -1;
1157         smbcli_unlink(cli1->tree, fname);
1158
1159         fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SEC_STD_DELETE|SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1160                                    NTCREATEX_SHARE_ACCESS_DELETE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
1161
1162         if (fnum1 == -1) {
1163                 torture_result(tctx, TORTURE_FAIL,
1164                         __location__ ": Test 5 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1165                 CHECK_MAX_FAILURES(error_test50);
1166                 return false;
1167         }
1168
1169         fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, SEC_STD_DELETE|SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1170                                    NTCREATEX_SHARE_ACCESS_DELETE, NTCREATEX_DISP_OPEN_IF, 0, 0);
1171
1172         if (fnum2 == -1) {
1173                 torture_result(tctx, TORTURE_FAIL,
1174                         __location__ ": Test 5 open 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1175                 CHECK_MAX_FAILURES(error_test50);
1176                 return false;
1177         }
1178
1179         torture_comment(tctx, "non-io open test #5 passed.\n");
1180 error_test50:
1181
1182         if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1183                 torture_comment(tctx, "Test 5 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1184         }
1185
1186         if (NT_STATUS_IS_ERR(smbcli_close(cli2->tree, fnum2))) {
1187                 torture_comment(tctx, "Test 5 close 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1188         }
1189
1190         torture_comment(tctx, "Test #6 testing 1 non-io open, one io open\n");
1191         fnum1 = fnum2 = -1;
1192         smbcli_unlink(cli1->tree, fname);
1193
1194         fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SEC_FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
1195                                    NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
1196
1197         if (fnum1 == -1) {
1198                 torture_result(tctx, TORTURE_FAIL,
1199                         __location__ ": Test 6 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1200                 CHECK_MAX_FAILURES(error_test60);
1201                 return false;
1202         }
1203
1204         fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1205                                    NTCREATEX_SHARE_ACCESS_READ, NTCREATEX_DISP_OPEN_IF, 0, 0);
1206
1207         if (fnum2 == -1) {
1208                 torture_result(tctx, TORTURE_FAIL,
1209                         __location__ ": Test 6 open 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1210                 CHECK_MAX_FAILURES(error_test60);
1211                 return false;
1212         }
1213
1214         torture_comment(tctx, "non-io open test #6 passed.\n");
1215 error_test60:
1216
1217         if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1218                 torture_comment(tctx, "Test 6 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1219         }
1220
1221         if (NT_STATUS_IS_ERR(smbcli_close(cli2->tree, fnum2))) {
1222                 torture_comment(tctx, "Test 6 close 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1223         }
1224
1225         torture_comment(tctx, "Test #7 testing 1 non-io open, one io open with delete\n");
1226         fnum1 = fnum2 = -1;
1227         smbcli_unlink(cli1->tree, fname);
1228
1229         fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SEC_FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
1230                                    NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
1231
1232         if (fnum1 == -1) {
1233                 torture_result(tctx, TORTURE_FAIL,
1234                         __location__ ": Test 7 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1235                 CHECK_MAX_FAILURES(error_test70);
1236                 return false;
1237         }
1238
1239         fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, SEC_STD_DELETE|SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1240                                    NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_DELETE, NTCREATEX_DISP_OPEN_IF, 0, 0);
1241
1242         if (fnum2 != -1) {
1243                 torture_result(tctx, TORTURE_FAIL,
1244                         __location__ ": Test 7 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1245                 CHECK_MAX_FAILURES(error_test70);
1246                 return false;
1247         }
1248
1249         torture_comment(tctx, "Test 7 open 2 of %s gave %s (correct error should be %s)\n", fname, smbcli_errstr(cli2->tree), "sharing violation");
1250
1251         torture_comment(tctx, "non-io open test #7 passed.\n");
1252 error_test70:
1253
1254         if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1255                 torture_comment(tctx, "Test 7 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1256         }
1257         if (fnum2 != -1 && NT_STATUS_IS_ERR(smbcli_close(cli2->tree, fnum2))) {
1258                 torture_comment(tctx, "Test 7 close 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1259         }
1260
1261         torture_comment(tctx, "Test #8 testing one normal open, followed by lock, followed by open with truncate\n");
1262         fnum1 = fnum2 = -1;
1263         smbcli_unlink(cli1->tree, fname);
1264
1265         fnum1 = smbcli_open(cli1->tree, fname, O_RDWR|O_CREAT, DENY_NONE);
1266         if (fnum1 == -1) {
1267                 torture_result(tctx, TORTURE_FAIL, "(8) open (1) of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1268                 return false;
1269         }
1270         
1271         /* write 20 bytes. */
1272         
1273         memset(buf, '\0', 20);
1274
1275         if (smbcli_write(cli1->tree, fnum1, 0, buf, 0, 20) != 20) {
1276                 torture_result(tctx, TORTURE_FAIL, "(8) write failed (%s)\n", smbcli_errstr(cli1->tree));
1277                 correct = false;
1278         }
1279
1280         /* Ensure size == 20. */
1281         if (NT_STATUS_IS_ERR(smbcli_getatr(cli1->tree, fname, NULL, &fsize, NULL))) {
1282                 torture_result(tctx, TORTURE_FAIL,
1283                         __location__ ": (8) getatr (1) failed (%s)\n", smbcli_errstr(cli1->tree));
1284                 CHECK_MAX_FAILURES(error_test80);
1285                 return false;
1286         }
1287         
1288         if (fsize != 20) {
1289                 torture_result(tctx, TORTURE_FAIL,
1290                         __location__ ": (8) file size %lu != 20\n", (unsigned long)fsize);
1291                 CHECK_MAX_FAILURES(error_test80);
1292                 return false;
1293         }
1294
1295         /* Get an exclusive lock on the open file. */
1296         if (NT_STATUS_IS_ERR(smbcli_lock(cli1->tree, fnum1, 0, 4, 0, WRITE_LOCK))) {
1297                 torture_result(tctx, TORTURE_FAIL,
1298                         __location__ ": (8) lock1 failed (%s)\n", smbcli_errstr(cli1->tree));
1299                 CHECK_MAX_FAILURES(error_test80);
1300                 return false;
1301         }
1302
1303         fnum2 = smbcli_open(cli1->tree, fname, O_RDWR|O_TRUNC, DENY_NONE);
1304         if (fnum1 == -1) {
1305                 torture_result(tctx, TORTURE_FAIL, "(8) open (2) of %s with truncate failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1306                 return false;
1307         }
1308
1309         /* Ensure size == 0. */
1310         if (NT_STATUS_IS_ERR(smbcli_getatr(cli1->tree, fname, NULL, &fsize, NULL))) {
1311                 torture_result(tctx, TORTURE_FAIL,
1312                         __location__ ": (8) getatr (2) failed (%s)\n", smbcli_errstr(cli1->tree));
1313                 CHECK_MAX_FAILURES(error_test80);
1314                 return false;
1315         }
1316         
1317         if (fsize != 0) {
1318                 torture_result(tctx, TORTURE_FAIL,
1319                         __location__ ": (8) file size %lu != 0\n", (unsigned long)fsize);
1320                 CHECK_MAX_FAILURES(error_test80);
1321                 return false;
1322         }
1323
1324         if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1325                 torture_result(tctx, TORTURE_FAIL, "(8) close1 failed (%s)\n", smbcli_errstr(cli1->tree));
1326                 return false;
1327         }
1328         
1329         if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum2))) {
1330                 torture_result(tctx, TORTURE_FAIL, "(8) close1 failed (%s)\n", smbcli_errstr(cli1->tree));
1331                 return false;
1332         }
1333         
1334 error_test80:
1335
1336         torture_comment(tctx, "open test #8 passed.\n");
1337
1338         smbcli_unlink(cli1->tree, fname);
1339
1340         return failures > 0 ? false : correct;
1341 }
1342
1343 /* FIRST_DESIRED_ACCESS   0xf019f */
1344 #define FIRST_DESIRED_ACCESS   SEC_FILE_READ_DATA|SEC_FILE_WRITE_DATA|SEC_FILE_APPEND_DATA|\
1345                                SEC_FILE_READ_EA|                           /* 0xf */ \
1346                                SEC_FILE_WRITE_EA|SEC_FILE_READ_ATTRIBUTE|     /* 0x90 */ \
1347                                SEC_FILE_WRITE_ATTRIBUTE|                  /* 0x100 */ \
1348                                SEC_STD_DELETE|SEC_STD_READ_CONTROL|\
1349                                SEC_STD_WRITE_DAC|SEC_STD_WRITE_OWNER     /* 0xf0000 */
1350 /* SECOND_DESIRED_ACCESS  0xe0080 */
1351 #define SECOND_DESIRED_ACCESS  SEC_FILE_READ_ATTRIBUTE|                   /* 0x80 */ \
1352                                SEC_STD_READ_CONTROL|SEC_STD_WRITE_DAC|\
1353                                SEC_STD_WRITE_OWNER                      /* 0xe0000 */
1354
1355 #if 0
1356 #define THIRD_DESIRED_ACCESS   FILE_READ_ATTRIBUTE|                   /* 0x80 */ \
1357                                READ_CONTROL|WRITE_DAC|\
1358                                SEC_FILE_READ_DATA|\
1359                                WRITE_OWNER                      /* */
1360 #endif
1361
1362
1363
1364 /**
1365   Test ntcreate calls made by xcopy
1366  */
1367 static bool run_xcopy(struct torture_context *tctx,
1368                                           struct smbcli_state *cli1)
1369 {
1370         const char *fname = "\\test.txt";
1371         int fnum1, fnum2;
1372
1373         fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0,
1374                                       FIRST_DESIRED_ACCESS, 
1375                                       FILE_ATTRIBUTE_ARCHIVE,
1376                                       NTCREATEX_SHARE_ACCESS_NONE, 
1377                                       NTCREATEX_DISP_OVERWRITE_IF, 
1378                                       0x4044, 0);
1379
1380         torture_assert(tctx, fnum1 != -1, talloc_asprintf(tctx, 
1381                                 "First open failed - %s", smbcli_errstr(cli1->tree)));
1382
1383         fnum2 = smbcli_nt_create_full(cli1->tree, fname, 0,
1384                                    SECOND_DESIRED_ACCESS, 0,
1385                                    NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE|NTCREATEX_SHARE_ACCESS_DELETE, NTCREATEX_DISP_OPEN, 
1386                                    0x200000, 0);
1387         torture_assert(tctx, fnum2 != -1, talloc_asprintf(tctx, 
1388                                 "second open failed - %s", smbcli_errstr(cli1->tree)));
1389         
1390         return true;
1391 }
1392
1393 static bool run_iometer(struct torture_context *tctx,
1394                                                 struct smbcli_state *cli)
1395 {
1396         const char *fname = "\\iobw.tst";
1397         int fnum;
1398         size_t filesize;
1399         NTSTATUS status;
1400         char buf[2048];
1401         int ops;
1402
1403         memset(buf, 0, sizeof(buf));
1404
1405         status = smbcli_getatr(cli->tree, fname, NULL, &filesize, NULL);
1406         torture_assert_ntstatus_ok(tctx, status, 
1407                 talloc_asprintf(tctx, "smbcli_getatr failed: %s", nt_errstr(status)));
1408
1409         torture_comment(tctx, "size: %d\n", (int)filesize);
1410
1411         filesize -= (sizeof(buf) - 1);
1412
1413         fnum = smbcli_nt_create_full(cli->tree, fname, 0x16,
1414                                      0x2019f, 0, 0x3, 3, 0x42, 0x3);
1415         torture_assert(tctx, fnum != -1, talloc_asprintf(tctx, "open failed: %s", 
1416                                    smbcli_errstr(cli->tree)));
1417
1418         ops = 0;
1419
1420         while (true) {
1421                 int i, num_reads, num_writes;
1422
1423                 num_reads = random() % 10;
1424                 num_writes = random() % 3;
1425
1426                 for (i=0; i<num_reads; i++) {
1427                         ssize_t res;
1428                         if (ops++ > torture_numops) {
1429                                 return true;
1430                         }
1431                         res = smbcli_read(cli->tree, fnum, buf,
1432                                           random() % filesize, sizeof(buf));
1433                         torture_assert(tctx, res == sizeof(buf), 
1434                                                    talloc_asprintf(tctx, "read failed: %s",
1435                                                                                    smbcli_errstr(cli->tree)));
1436                 }
1437                 for (i=0; i<num_writes; i++) {
1438                         ssize_t res;
1439                         if (ops++ > torture_numops) {
1440                                 return true;
1441                         }
1442                         res = smbcli_write(cli->tree, fnum, 0, buf,
1443                                           random() % filesize, sizeof(buf));
1444                         torture_assert(tctx, res == sizeof(buf),
1445                                                    talloc_asprintf(tctx, "read failed: %s",
1446                                        smbcli_errstr(cli->tree)));
1447                 }
1448         }
1449 }
1450
1451 /**
1452   tries variants of chkpath
1453  */
1454 static bool torture_chkpath_test(struct torture_context *tctx, 
1455                                                                  struct smbcli_state *cli)
1456 {
1457         int fnum;
1458         bool ret;
1459
1460         torture_comment(tctx, "Testing valid and invalid paths\n");
1461
1462         /* cleanup from an old run */
1463         smbcli_rmdir(cli->tree, "\\chkpath.dir\\dir2");
1464         smbcli_unlink(cli->tree, "\\chkpath.dir\\*");
1465         smbcli_rmdir(cli->tree, "\\chkpath.dir");
1466
1467         if (NT_STATUS_IS_ERR(smbcli_mkdir(cli->tree, "\\chkpath.dir"))) {
1468                 torture_result(tctx, TORTURE_FAIL, "mkdir1 failed : %s\n", smbcli_errstr(cli->tree));
1469                 return false;
1470         }
1471
1472         if (NT_STATUS_IS_ERR(smbcli_mkdir(cli->tree, "\\chkpath.dir\\dir2"))) {
1473                 torture_result(tctx, TORTURE_FAIL, "mkdir2 failed : %s\n", smbcli_errstr(cli->tree));
1474                 return false;
1475         }
1476
1477         fnum = smbcli_open(cli->tree, "\\chkpath.dir\\foo.txt", O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1478         if (fnum == -1) {
1479                 torture_result(tctx, TORTURE_FAIL, "open1 failed (%s)\n", smbcli_errstr(cli->tree));
1480                 return false;
1481         }
1482         smbcli_close(cli->tree, fnum);
1483
1484         if (NT_STATUS_IS_ERR(smbcli_chkpath(cli->tree, "\\chkpath.dir"))) {
1485                 torture_result(tctx, TORTURE_FAIL, "chkpath1 failed: %s\n", smbcli_errstr(cli->tree));
1486                 ret = false;
1487         }
1488
1489         if (NT_STATUS_IS_ERR(smbcli_chkpath(cli->tree, "\\chkpath.dir\\dir2"))) {
1490                 torture_result(tctx, TORTURE_FAIL, "chkpath2 failed: %s\n", smbcli_errstr(cli->tree));
1491                 ret = false;
1492         }
1493
1494         if (NT_STATUS_IS_ERR(smbcli_chkpath(cli->tree, "\\chkpath.dir\\foo.txt"))) {
1495                 ret = check_error(__location__, cli, ERRDOS, ERRbadpath, 
1496                                   NT_STATUS_NOT_A_DIRECTORY);
1497         } else {
1498                 torture_result(tctx, TORTURE_FAIL, "* chkpath on a file should fail\n");
1499                 ret = false;
1500         }
1501
1502         if (NT_STATUS_IS_ERR(smbcli_chkpath(cli->tree, "\\chkpath.dir\\bar.txt"))) {
1503                 ret = check_error(__location__, cli, ERRDOS, ERRbadpath, 
1504                                   NT_STATUS_OBJECT_NAME_NOT_FOUND);
1505         } else {
1506                 torture_result(tctx, TORTURE_FAIL, "* chkpath on a non existent file should fail\n");
1507                 ret = false;
1508         }
1509
1510         if (NT_STATUS_IS_ERR(smbcli_chkpath(cli->tree, "\\chkpath.dir\\dirxx\\bar.txt"))) {
1511                 ret = check_error(__location__, cli, ERRDOS, ERRbadpath, 
1512                                   NT_STATUS_OBJECT_PATH_NOT_FOUND);
1513         } else {
1514                 torture_result(tctx, TORTURE_FAIL, "* chkpath on a non existent component should fail\n");
1515                 ret = false;
1516         }
1517
1518         smbcli_rmdir(cli->tree, "\\chkpath.dir\\dir2");
1519         smbcli_unlink(cli->tree, "\\chkpath.dir\\*");
1520         smbcli_rmdir(cli->tree, "\\chkpath.dir");
1521
1522         return ret;
1523 }
1524
1525 /*
1526  * This is a test to excercise some weird Samba3 error paths.
1527  */
1528
1529 static bool torture_samba3_errorpaths(struct torture_context *tctx)
1530 {
1531         bool nt_status_support;
1532         bool client_ntlmv2_auth;
1533         struct smbcli_state *cli_nt = NULL, *cli_dos = NULL;
1534         bool result = false;
1535         int fnum;
1536         const char *os2_fname = ".+,;=[].";
1537         const char *dname = "samba3_errordir";
1538         union smb_open io;
1539         NTSTATUS status;
1540
1541         nt_status_support = lpcfg_nt_status_support(tctx->lp_ctx);
1542         client_ntlmv2_auth = lpcfg_client_ntlmv2_auth(tctx->lp_ctx);
1543
1544         if (!lpcfg_set_cmdline(tctx->lp_ctx, "nt status support", "yes")) {
1545                 torture_result(tctx, TORTURE_FAIL, "Could not set 'nt status support = yes'\n");
1546                 goto fail;
1547         }
1548         if (!lpcfg_set_cmdline(tctx->lp_ctx, "client ntlmv2 auth", "yes")) {
1549                 torture_result(tctx, TORTURE_FAIL, "Could not set 'client ntlmv2 auth = yes'\n");
1550                 goto fail;
1551         }
1552
1553         if (!torture_open_connection(&cli_nt, tctx, 0)) {
1554                 goto fail;
1555         }
1556
1557         if (!lpcfg_set_cmdline(tctx->lp_ctx, "nt status support", "no")) {
1558                 torture_result(tctx, TORTURE_FAIL, "Could not set 'nt status support = no'\n");
1559                 goto fail;
1560         }
1561         if (!lpcfg_set_cmdline(tctx->lp_ctx, "client ntlmv2 auth", "no")) {
1562                 torture_result(tctx, TORTURE_FAIL, "Could not set 'client ntlmv2 auth = no'\n");
1563                 goto fail;
1564         }
1565
1566         if (!torture_open_connection(&cli_dos, tctx, 1)) {
1567                 goto fail;
1568         }
1569
1570         if (!lpcfg_set_cmdline(tctx->lp_ctx, "nt status support",
1571                             nt_status_support ? "yes":"no")) {
1572                 torture_result(tctx, TORTURE_FAIL, "Could not reset 'nt status support'");
1573                 goto fail;
1574         }
1575         if (!lpcfg_set_cmdline(tctx->lp_ctx, "client ntlmv2 auth",
1576                                client_ntlmv2_auth ? "yes":"no")) {
1577                 torture_result(tctx, TORTURE_FAIL, "Could not reset 'client ntlmv2 auth'");
1578                 goto fail;
1579         }
1580
1581         smbcli_unlink(cli_nt->tree, os2_fname);
1582         smbcli_rmdir(cli_nt->tree, dname);
1583
1584         if (!NT_STATUS_IS_OK(smbcli_mkdir(cli_nt->tree, dname))) {
1585                 torture_result(tctx, TORTURE_FAIL, "smbcli_mkdir(%s) failed: %s\n", dname,
1586                        smbcli_errstr(cli_nt->tree));
1587                 goto fail;
1588         }
1589
1590         io.generic.level = RAW_OPEN_NTCREATEX;
1591         io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED;
1592         io.ntcreatex.in.root_fid.fnum = 0;
1593         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1594         io.ntcreatex.in.alloc_size = 1024*1024;
1595         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_DIRECTORY;
1596         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
1597         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
1598         io.ntcreatex.in.create_options = 0;
1599         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
1600         io.ntcreatex.in.security_flags = 0;
1601         io.ntcreatex.in.fname = dname;
1602
1603         status = smb_raw_open(cli_nt->tree, tctx, &io);
1604         if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_COLLISION)) {
1605                 torture_result(tctx, TORTURE_FAIL, "(%s) incorrect status %s should be %s\n",
1606                        __location__, nt_errstr(status),
1607                        nt_errstr(NT_STATUS_OBJECT_NAME_COLLISION));
1608                 goto fail;
1609         }
1610         status = smb_raw_open(cli_dos->tree, tctx, &io);
1611         if (!NT_STATUS_EQUAL(status, NT_STATUS_DOS(ERRDOS, ERRfilexists))) {
1612                 torture_result(tctx, TORTURE_FAIL, "(%s) incorrect status %s should be %s\n",
1613                        __location__, nt_errstr(status),
1614                        nt_errstr(NT_STATUS_DOS(ERRDOS, ERRfilexists)));
1615                 goto fail;
1616         }
1617
1618         status = smbcli_mkdir(cli_nt->tree, dname);
1619         if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_COLLISION)) {
1620                 torture_result(tctx, TORTURE_FAIL, "(%s) incorrect status %s should be %s\n",
1621                        __location__, nt_errstr(status),
1622                        nt_errstr(NT_STATUS_OBJECT_NAME_COLLISION));
1623                 goto fail;
1624         }
1625         status = smbcli_mkdir(cli_dos->tree, dname);
1626         if (!NT_STATUS_EQUAL(status, NT_STATUS_DOS(ERRDOS, ERRnoaccess))) {
1627                 torture_result(tctx, TORTURE_FAIL, "(%s) incorrect status %s should be %s\n",
1628                        __location__, nt_errstr(status),
1629                        nt_errstr(NT_STATUS_DOS(ERRDOS, ERRnoaccess)));
1630                 goto fail;
1631         }
1632
1633         {
1634                 union smb_mkdir md;
1635                 md.t2mkdir.level = RAW_MKDIR_T2MKDIR;
1636                 md.t2mkdir.in.path = dname;
1637                 md.t2mkdir.in.num_eas = 0;
1638                 md.t2mkdir.in.eas = NULL;
1639
1640                 status = smb_raw_mkdir(cli_nt->tree, &md);
1641                 if (!NT_STATUS_EQUAL(status,
1642                                      NT_STATUS_OBJECT_NAME_COLLISION)) {
1643                         torture_comment(
1644                                 tctx, "(%s) incorrect status %s should be "
1645                                 "NT_STATUS_OBJECT_NAME_COLLISION\n",
1646                                 __location__, nt_errstr(status));
1647                         goto fail;
1648                 }
1649                 status = smb_raw_mkdir(cli_dos->tree, &md);
1650                 if (!NT_STATUS_EQUAL(status,
1651                                      NT_STATUS_DOS(ERRDOS, ERRrename))) {
1652                         torture_result(tctx, TORTURE_FAIL, "(%s) incorrect status %s "
1653                                         "should be ERRDOS:ERRrename\n",
1654                                         __location__, nt_errstr(status));
1655                         goto fail;
1656                 }
1657         }
1658
1659         io.ntcreatex.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
1660         status = smb_raw_open(cli_nt->tree, tctx, &io);
1661         if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_COLLISION)) {
1662                 torture_result(tctx, TORTURE_FAIL, "(%s) incorrect status %s should be %s\n",
1663                        __location__, nt_errstr(status),
1664                        nt_errstr(NT_STATUS_OBJECT_NAME_COLLISION));
1665                 goto fail;
1666         }
1667
1668         status = smb_raw_open(cli_dos->tree, tctx, &io);
1669         if (!NT_STATUS_EQUAL(status, NT_STATUS_DOS(ERRDOS, ERRfilexists))) {
1670                 torture_result(tctx, TORTURE_FAIL, "(%s) incorrect status %s should be %s\n",
1671                        __location__, nt_errstr(status),
1672                        nt_errstr(NT_STATUS_DOS(ERRDOS, ERRfilexists)));
1673                 goto fail;
1674         }
1675
1676         {
1677                 /* Test an invalid DOS deny mode */
1678                 const char *fname = "test.txt";
1679
1680                 fnum = smbcli_open(cli_nt->tree, fname, O_RDWR | O_CREAT, 5);
1681                 if (fnum != -1) {
1682                         torture_result(tctx, TORTURE_FAIL, "Open(%s) with invalid deny mode succeeded -- "
1683                                "expected failure\n", fname);
1684                         smbcli_close(cli_nt->tree, fnum);
1685                         goto fail;
1686                 }
1687                 if (!NT_STATUS_EQUAL(smbcli_nt_error(cli_nt->tree),
1688                                      NT_STATUS_DOS(ERRDOS,ERRbadaccess))) {
1689                         torture_result(tctx, TORTURE_FAIL, "Expected DOS error ERRDOS/ERRbadaccess, "
1690                                "got %s\n", smbcli_errstr(cli_nt->tree));
1691                         goto fail;
1692                 }
1693
1694                 fnum = smbcli_open(cli_dos->tree, fname, O_RDWR | O_CREAT, 5);
1695                 if (fnum != -1) {
1696                         torture_result(tctx, TORTURE_FAIL, "Open(%s) with invalid deny mode succeeded -- "
1697                                "expected failure\n", fname);
1698                         smbcli_close(cli_nt->tree, fnum);
1699                         goto fail;
1700                 }
1701                 if (!NT_STATUS_EQUAL(smbcli_nt_error(cli_nt->tree),
1702                                      NT_STATUS_DOS(ERRDOS,ERRbadaccess))) {
1703                         torture_result(tctx, TORTURE_FAIL, "Expected DOS error ERRDOS:ERRbadaccess, "
1704                                "got %s\n", smbcli_errstr(cli_nt->tree));
1705                         goto fail;
1706                 }
1707         }
1708
1709         {
1710                 /*
1711                  * Samba 3.0.23 has a bug that an existing file can be opened
1712                  * as a directory using ntcreate&x. Test this.
1713                  */
1714
1715                 const char *fname = "\\test_dir.txt";
1716
1717                 fnum = smbcli_open(cli_nt->tree, fname, O_RDWR|O_CREAT,
1718                                    DENY_NONE);
1719                 if (fnum == -1) {
1720                         d_printf("(%s) smbcli_open failed: %s\n", __location__,
1721                                  smbcli_errstr(cli_nt->tree));
1722                 }
1723                 smbcli_close(cli_nt->tree, fnum);
1724
1725                 io.generic.level = RAW_OPEN_NTCREATEX;
1726                 io.ntcreatex.in.root_fid.fnum = 0;
1727                 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
1728                 io.ntcreatex.in.alloc_size = 0;
1729                 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_DIRECTORY;
1730                 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|
1731                         NTCREATEX_SHARE_ACCESS_WRITE|
1732                         NTCREATEX_SHARE_ACCESS_DELETE;
1733                 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
1734                 io.ntcreatex.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
1735                 io.ntcreatex.in.impersonation =
1736                         NTCREATEX_IMPERSONATION_ANONYMOUS;
1737                 io.ntcreatex.in.security_flags = 0;
1738                 io.ntcreatex.in.fname = fname;
1739                 io.ntcreatex.in.flags = 0;
1740
1741                 status = smb_raw_open(cli_nt->tree, tctx, &io);
1742                 if (!NT_STATUS_EQUAL(status, NT_STATUS_NOT_A_DIRECTORY)) {
1743                         torture_result(tctx, TORTURE_FAIL, "ntcreate as dir gave %s, "
1744                                         "expected NT_STATUS_NOT_A_DIRECTORY\n",
1745                                         nt_errstr(status));
1746                         result = false;
1747                 }
1748
1749                 if (NT_STATUS_IS_OK(status)) {
1750                         smbcli_close(cli_nt->tree, io.ntcreatex.out.file.fnum);
1751                 }
1752
1753                 status = smb_raw_open(cli_dos->tree, tctx, &io);
1754                 if (!NT_STATUS_EQUAL(status, NT_STATUS_DOS(ERRDOS,
1755                                                            ERRbaddirectory))) {
1756                         torture_result(tctx, TORTURE_FAIL, "ntcreate as dir gave %s, "
1757                                         "expected NT_STATUS_NOT_A_DIRECTORY\n",
1758                                         nt_errstr(status));
1759                         result = false;
1760                 }
1761
1762                 if (NT_STATUS_IS_OK(status)) {
1763                         smbcli_close(cli_dos->tree,
1764                                      io.ntcreatex.out.file.fnum);
1765                 }
1766
1767                 smbcli_unlink(cli_nt->tree, fname);
1768         }
1769
1770         if (!torture_setting_bool(tctx, "samba3", false)) {
1771                 goto done;
1772         }
1773
1774         fnum = smbcli_open(cli_dos->tree, os2_fname, 
1775                            O_RDWR | O_CREAT | O_TRUNC,
1776                            DENY_NONE);
1777         if (fnum != -1) {
1778                 torture_result(tctx, TORTURE_FAIL, "Open(%s) succeeded -- expected failure\n",
1779                        os2_fname);
1780                 smbcli_close(cli_dos->tree, fnum);
1781                 goto fail;
1782         }
1783
1784         if (!NT_STATUS_EQUAL(smbcli_nt_error(cli_dos->tree),
1785                              NT_STATUS_DOS(ERRDOS, ERRcannotopen))) {
1786                 torture_result(tctx, TORTURE_FAIL, "Expected DOS error ERRDOS/ERRcannotopen, got %s\n",
1787                        smbcli_errstr(cli_dos->tree));
1788                 goto fail;
1789         }
1790
1791         fnum = smbcli_open(cli_nt->tree, os2_fname, 
1792                            O_RDWR | O_CREAT | O_TRUNC,
1793                            DENY_NONE);
1794         if (fnum != -1) {
1795                 torture_result(tctx, TORTURE_FAIL, "Open(%s) succeeded -- expected failure\n",
1796                        os2_fname);
1797                 smbcli_close(cli_nt->tree, fnum);
1798                 goto fail;
1799         }
1800
1801         if (!NT_STATUS_EQUAL(smbcli_nt_error(cli_nt->tree),
1802                              NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
1803                 torture_result(tctx, TORTURE_FAIL, "Expected error NT_STATUS_OBJECT_NAME_NOT_FOUND, "
1804                        "got %s\n", smbcli_errstr(cli_nt->tree));
1805                 goto fail;
1806         }
1807
1808  done:
1809         result = true;
1810
1811  fail:
1812         if (cli_dos != NULL) {
1813                 torture_close_connection(cli_dos);
1814         }
1815         if (cli_nt != NULL) {
1816                 torture_close_connection(cli_nt);
1817         }
1818         
1819         return result;
1820 }
1821
1822 /**
1823   This checks file/dir birthtime
1824 */
1825 static void list_fn(struct clilist_file_info *finfo, const char *name,
1826                         void *state){
1827
1828         /* Just to change dir access time*/
1829         sleep(5);
1830
1831 }
1832
1833 static bool run_birthtimetest(struct torture_context *tctx,
1834                                                    struct smbcli_state *cli)
1835 {
1836         int fnum;
1837         size_t size;
1838         time_t c_time, a_time, m_time, w_time, c_time1;
1839         const char *fname = "\\birthtime.tst";
1840         const char *dname = "\\birthtime";
1841         const char *fname2 = "\\birthtime\\birthtime.tst";
1842         bool correct = true;
1843         uint8_t buf[16];
1844
1845
1846         smbcli_unlink(cli->tree, fname);
1847
1848         torture_comment(tctx, "Testing Birthtime for File\n");
1849
1850         /* Save File birthtime/creationtime */
1851         fnum = smbcli_open(cli->tree, fname, O_RDWR | O_CREAT | O_TRUNC,
1852                                 DENY_NONE);
1853         if (NT_STATUS_IS_ERR(smbcli_qfileinfo(cli->tree, fnum, NULL, &size,
1854                                 &c_time, &a_time, &m_time, NULL, NULL))) {
1855                 torture_result(tctx, TORTURE_FAIL, "ERROR: qfileinfo failed (%s)\n",
1856                                 smbcli_errstr(cli->tree));
1857                 correct = false;
1858         }
1859         smbcli_close(cli->tree, fnum);
1860
1861         sleep(10);
1862
1863         /* Change in File attribute changes file change time*/
1864         smbcli_setatr(cli->tree, fname, FILE_ATTRIBUTE_SYSTEM, 0);
1865
1866         fnum = smbcli_open(cli->tree, fname, O_RDWR | O_CREAT , DENY_NONE);
1867         /* Writing updates modification time*/
1868         smbcli_smbwrite(cli->tree, fnum,  &fname, 0, sizeof(fname));
1869         /*Reading updates access time */
1870         smbcli_read(cli->tree, fnum, buf, 0, 13);
1871         smbcli_close(cli->tree, fnum);
1872
1873         if (NT_STATUS_IS_ERR(smbcli_qpathinfo2(cli->tree, fname, &c_time1,
1874                         &a_time, &m_time, &w_time, &size, NULL, NULL))) {
1875                 torture_result(tctx, TORTURE_FAIL, "ERROR: qpathinfo2 failed (%s)\n",
1876                         smbcli_errstr(cli->tree));
1877                 correct = false;
1878         } else {
1879                 fprintf(stdout, "c_time = %li, c_time1 = %li\n",
1880                         (long) c_time, (long) c_time1);
1881                 if (c_time1 != c_time) {
1882                         torture_result(tctx, TORTURE_FAIL, "This system updated file \
1883                                         birth times! Not expected!\n");
1884                         correct = false;
1885                 }
1886         }
1887         smbcli_unlink(cli->tree, fname);
1888
1889         torture_comment(tctx, "Testing Birthtime for Directory\n");
1890
1891         /* check if the server does not update the directory birth time
1892           when creating a new file */
1893         if (NT_STATUS_IS_ERR(smbcli_mkdir(cli->tree, dname))) {
1894                 torture_result(tctx, TORTURE_FAIL, "ERROR: mkdir failed (%s)\n",
1895                                 smbcli_errstr(cli->tree));
1896                 correct = false;
1897         }
1898         sleep(3);
1899         if (NT_STATUS_IS_ERR(smbcli_qpathinfo2(cli->tree, "\\birthtime\\",
1900                         &c_time,&a_time,&m_time,&w_time, &size, NULL, NULL))){
1901                 torture_result(tctx, TORTURE_FAIL, "ERROR: qpathinfo2 failed (%s)\n",
1902                                 smbcli_errstr(cli->tree));
1903                 correct = false;
1904         }
1905
1906         /* Creating a new file changes dir modification time and change time*/
1907         smbcli_unlink(cli->tree, fname2);
1908         fnum = smbcli_open(cli->tree, fname2, O_RDWR | O_CREAT | O_TRUNC,
1909                         DENY_NONE);
1910         smbcli_smbwrite(cli->tree, fnum,  &fnum, 0, sizeof(fnum));
1911         smbcli_read(cli->tree, fnum, buf, 0, 13);
1912         smbcli_close(cli->tree, fnum);
1913
1914         /* dir listing changes dir access time*/
1915         smbcli_list(cli->tree, "\\birthtime\\*", 0, list_fn, cli );
1916
1917         if (NT_STATUS_IS_ERR(smbcli_qpathinfo2(cli->tree, "\\birthtime\\",
1918                         &c_time1, &a_time, &m_time,&w_time,&size,NULL,NULL))){
1919                 torture_result(tctx, TORTURE_FAIL, "ERROR: qpathinfo2 failed (%s)\n",
1920                                 smbcli_errstr(cli->tree));
1921                 correct = false;
1922         } else {
1923                 fprintf(stdout, "c_time = %li, c_time1 = %li\n",
1924                         (long) c_time, (long) c_time1);
1925                 if (c_time1 != c_time) {
1926                         torture_result(tctx, TORTURE_FAIL, "This system  updated directory \
1927                                         birth times! Not Expected!\n");
1928                         correct = false;
1929                 }
1930         }
1931         smbcli_unlink(cli->tree, fname2);
1932         smbcli_rmdir(cli->tree, dname);
1933
1934         return correct;
1935 }
1936
1937
1938 NTSTATUS torture_base_init(TALLOC_CTX *ctx)
1939 {
1940         struct torture_suite *suite = torture_suite_create(talloc_autofree_context(), "base");
1941
1942         torture_suite_add_2smb_test(suite, "fdpass", run_fdpasstest);
1943         torture_suite_add_suite(suite, torture_base_locktest(suite));
1944         torture_suite_add_1smb_test(suite, "unlink", torture_unlinktest);
1945         torture_suite_add_1smb_test(suite, "attr",   run_attrtest);
1946         torture_suite_add_1smb_test(suite, "trans2", run_trans2test);
1947         torture_suite_add_1smb_test(suite, "birthtime", run_birthtimetest);
1948         torture_suite_add_simple_test(suite, "negnowait", run_negprot_nowait);
1949         torture_suite_add_1smb_test(suite, "dir1",  torture_dirtest1);
1950         torture_suite_add_1smb_test(suite, "dir2",  torture_dirtest2);
1951         torture_suite_add_1smb_test(suite, "deny1",  torture_denytest1);
1952         torture_suite_add_2smb_test(suite, "deny2",  torture_denytest2);
1953         torture_suite_add_2smb_test(suite, "deny3",  torture_denytest3);
1954         torture_suite_add_1smb_test(suite, "denydos",  torture_denydos_sharing);
1955         torture_suite_add_smb_multi_test(suite, "ntdeny1", torture_ntdenytest1);
1956         torture_suite_add_2smb_test(suite, "ntdeny2",  torture_ntdenytest2);
1957         torture_suite_add_1smb_test(suite, "tcon",  run_tcon_test);
1958         torture_suite_add_1smb_test(suite, "tcondev",  run_tcon_devtype_test);
1959         torture_suite_add_1smb_test(suite, "vuid", run_vuidtest);
1960         torture_suite_add_2smb_test(suite, "rw1",  run_readwritetest);
1961         torture_suite_add_2smb_test(suite, "open", run_opentest);
1962         torture_suite_add_smb_multi_test(suite, "defer_open", run_deferopen);
1963         torture_suite_add_1smb_test(suite, "xcopy", run_xcopy);
1964         torture_suite_add_1smb_test(suite, "iometer", run_iometer);
1965         torture_suite_add_1smb_test(suite, "rename", torture_test_rename);
1966         torture_suite_add_suite(suite, torture_test_delete());
1967         torture_suite_add_1smb_test(suite, "properties", torture_test_properties);
1968         torture_suite_add_1smb_test(suite, "mangle", torture_mangle);
1969         torture_suite_add_1smb_test(suite, "openattr", torture_openattrtest);
1970         torture_suite_add_1smb_test(suite, "winattr", torture_winattrtest);
1971         torture_suite_add_suite(suite, torture_charset(suite));
1972         torture_suite_add_1smb_test(suite, "chkpath",  torture_chkpath_test);
1973         torture_suite_add_1smb_test(suite, "secleak",  torture_sec_leak);
1974         torture_suite_add_simple_test(suite, "disconnect",  torture_disconnect);
1975         torture_suite_add_suite(suite, torture_delay_write());
1976         torture_suite_add_simple_test(suite, "samba3error", torture_samba3_errorpaths);
1977         torture_suite_add_1smb_test(suite, "casetable", torture_casetable);
1978         torture_suite_add_1smb_test(suite, "utable", torture_utable);
1979         torture_suite_add_simple_test(suite, "smb", torture_smb_scan);
1980         torture_suite_add_suite(suite, torture_trans2_aliases(suite));
1981         torture_suite_add_1smb_test(suite, "trans2-scan", torture_trans2_scan);
1982         torture_suite_add_1smb_test(suite, "nttrans", torture_nttrans_scan);
1983         torture_suite_add_1smb_test(suite, "createx_access", torture_createx_access);
1984         torture_suite_add_2smb_test(suite, "createx_sharemodes_file", torture_createx_sharemodes_file);
1985         torture_suite_add_2smb_test(suite, "createx_sharemodes_dir", torture_createx_sharemodes_dir);
1986         torture_suite_add_1smb_test(suite, "maximum_allowed", torture_maximum_allowed);
1987
1988         torture_suite_add_simple_test(suite, "bench-holdcon", torture_holdcon);
1989         torture_suite_add_1smb_test(suite, "bench-holdopen", torture_holdopen);
1990         torture_suite_add_simple_test(suite, "bench-readwrite", run_benchrw);
1991         torture_suite_add_smb_multi_test(suite, "bench-torture", run_torture);
1992         torture_suite_add_1smb_test(suite, "scan-pipe_number", run_pipe_number);
1993         torture_suite_add_1smb_test(suite, "scan-ioctl", torture_ioctl_test);
1994         torture_suite_add_1smb_test(suite, "scan-maxfid", torture_maxfid_test);
1995
1996         suite->description = talloc_strdup(suite, 
1997                                         "Basic SMB tests (imported from the original smbtorture)");
1998
1999         torture_register_suite(suite);
2000
2001         return NT_STATUS_OK;
2002 }