root/source3/torture/torture.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. start_timer
  2. end_timer
  3. shm_setup
  4. force_cli_encryption
  5. open_nbt_connection
  6. terminate_path_at_separator
  7. smbcli_parse_unc
  8. torture_open_connection_share
  9. torture_open_connection
  10. torture_cli_session_setup2
  11. torture_close_connection
  12. check_error
  13. wait_lock
  14. rw_torture
  15. run_torture
  16. rw_torture3
  17. rw_torture2
  18. run_readwritetest
  19. run_readwritemulti
  20. run_readwritelarge
  21. run_netbench
  22. run_nbench
  23. run_locktest1
  24. run_tcon_test
  25. run_tcon2_test
  26. tcon_devtest
  27. run_tcon_devtype_test
  28. run_locktest2
  29. run_locktest3
  30. run_locktest4
  31. run_locktest5
  32. run_locktest6
  33. run_locktest7
  34. run_fdpasstest
  35. run_fdsesstest
  36. run_unlinktest
  37. run_maxfidtest
  38. rand_buf
  39. run_negprot_nowait
  40. run_randomipc
  41. browse_callback
  42. run_browsetest
  43. run_attrtest
  44. run_trans2test
  45. new_trans
  46. run_w2ktest
  47. run_oplock1
  48. run_oplock2
  49. oplock3_handler
  50. run_oplock3
  51. run_deletetest
  52. run_properties
  53. run_xcopy
  54. run_rename
  55. run_pipe_number
  56. run_opentest
  57. run_simple_posix_open_test
  58. run_openattrtest
  59. list_fn
  60. run_dirtest
  61. del_fn
  62. torture_ioctl_test
  63. torture_chkpath_test
  64. run_eatest
  65. run_dirtest1
  66. run_error_map_extract
  67. run_sesssetup_bench
  68. subst_test
  69. chain1_open_completion
  70. chain1_read_completion
  71. chain1_write_completion
  72. chain1_close_completion
  73. run_chain1
  74. null_source
  75. run_windows_write
  76. run_cli_echo
  77. run_uid_regression_test
  78. shortname_del_fn
  79. shortname_list_fn
  80. run_shortname_test
  81. run_local_substitute
  82. run_local_gencache
  83. rbt_testval
  84. run_local_rbtree
  85. test_stream_name
  86. run_local_stream_name
  87. data_blob_equal
  88. run_local_memcache
  89. wbclient_done
  90. run_local_wbclient
  91. create_procs
  92. run_test
  93. usage
  94. main

   1 /* 
   2    Unix SMB/CIFS implementation.
   3    SMB torture tester
   4    Copyright (C) Andrew Tridgell 1997-1998
   5    
   6    This program is free software; you can redistribute it and/or modify
   7    it under the terms of the GNU General Public License as published by
   8    the Free Software Foundation; either version 3 of the License, or
   9    (at your option) any later version.
  10    
  11    This program is distributed in the hope that it will be useful,
  12    but WITHOUT ANY WARRANTY; without even the implied warranty of
  13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14    GNU General Public License for more details.
  15    
  16    You should have received a copy of the GNU General Public License
  17    along with this program.  If not, see <http://www.gnu.org/licenses/>.
  18 */
  19 
  20 #include "includes.h"
  21 #include "wbc_async.h"
  22 
  23 extern char *optarg;
  24 extern int optind;
  25 
  26 static fstring host, workgroup, share, password, username, myname;
  27 static int max_protocol = PROTOCOL_NT1;
  28 static const char *sockops="TCP_NODELAY";
  29 static int nprocs=1;
  30 static int port_to_use=0;
  31 int torture_numops=100;
  32 int torture_blocksize=1024*1024;
  33 static int procnum; /* records process count number when forking */
  34 static struct cli_state *current_cli;
  35 static fstring randomfname;
  36 static bool use_oplocks;
  37 static bool use_level_II_oplocks;
  38 static const char *client_txt = "client_oplocks.txt";
  39 static bool use_kerberos;
  40 static fstring multishare_conn_fname;
  41 static bool use_multishare_conn = False;
  42 static bool do_encrypt;
  43 
  44 bool torture_showall = False;
  45 
  46 static double create_procs(bool (*fn)(int), bool *result);
  47 
  48 
  49 static struct timeval tp1,tp2;
  50 
  51 
  52 void start_timer(void)
     /* [<][>][^][v][top][bottom][index][help] */
  53 {
  54         GetTimeOfDay(&tp1);
  55 }
  56 
  57 double end_timer(void)
     /* [<][>][^][v][top][bottom][index][help] */
  58 {
  59         GetTimeOfDay(&tp2);
  60         return((tp2.tv_sec - tp1.tv_sec) + 
  61                (tp2.tv_usec - tp1.tv_usec)*1.0e-6);
  62 }
  63 
  64 
  65 /* return a pointer to a anonymous shared memory segment of size "size"
  66    which will persist across fork() but will disappear when all processes
  67    exit 
  68 
  69    The memory is not zeroed 
  70 
  71    This function uses system5 shared memory. It takes advantage of a property
  72    that the memory is not destroyed if it is attached when the id is removed
  73    */
  74 void *shm_setup(int size)
     /* [<][>][^][v][top][bottom][index][help] */
  75 {
  76         int shmid;
  77         void *ret;
  78 
  79         shmid = shmget(IPC_PRIVATE, size, S_IRUSR | S_IWUSR);
  80         if (shmid == -1) {
  81                 printf("can't get shared memory\n");
  82                 exit(1);
  83         }
  84         ret = (void *)shmat(shmid, 0, 0);
  85         if (!ret || ret == (void *)-1) {
  86                 printf("can't attach to shared memory\n");
  87                 return NULL;
  88         }
  89         /* the following releases the ipc, but note that this process
  90            and all its children will still have access to the memory, its
  91            just that the shmid is no longer valid for other shm calls. This
  92            means we don't leave behind lots of shm segments after we exit 
  93 
  94            See Stevens "advanced programming in unix env" for details
  95            */
  96         shmctl(shmid, IPC_RMID, 0);
  97         
  98         return ret;
  99 }
 100 
 101 /********************************************************************
 102  Ensure a connection is encrypted.
 103 ********************************************************************/
 104 
 105 static bool force_cli_encryption(struct cli_state *c,
     /* [<][>][^][v][top][bottom][index][help] */
 106                         const char *sharename)
 107 {
 108         uint16 major, minor;
 109         uint32 caplow, caphigh;
 110         NTSTATUS status;
 111 
 112         if (!SERVER_HAS_UNIX_CIFS(c)) {
 113                 d_printf("Encryption required and "
 114                         "server that doesn't support "
 115                         "UNIX extensions - failing connect\n");
 116                         return false;
 117         }
 118 
 119         if (!cli_unix_extensions_version(c, &major, &minor, &caplow, &caphigh)) {
 120                 d_printf("Encryption required and "
 121                         "can't get UNIX CIFS extensions "
 122                         "version from server.\n");
 123                 return false;
 124         }
 125 
 126         if (!(caplow & CIFS_UNIX_TRANSPORT_ENCRYPTION_CAP)) {
 127                 d_printf("Encryption required and "
 128                         "share %s doesn't support "
 129                         "encryption.\n", sharename);
 130                 return false;
 131         }
 132 
 133         if (c->use_kerberos) {
 134                 status = cli_gss_smb_encryption_start(c);
 135         } else {
 136                 status = cli_raw_ntlm_smb_encryption_start(c,
 137                                                 username,
 138                                                 password,
 139                                                 workgroup);
 140         }
 141 
 142         if (!NT_STATUS_IS_OK(status)) {
 143                 d_printf("Encryption required and "
 144                         "setup failed with error %s.\n",
 145                         nt_errstr(status));
 146                 return false;
 147         }
 148 
 149         return true;
 150 }
 151 
 152 
 153 static struct cli_state *open_nbt_connection(void)
     /* [<][>][^][v][top][bottom][index][help] */
 154 {
 155         struct nmb_name called, calling;
 156         struct sockaddr_storage ss;
 157         struct cli_state *c;
 158         NTSTATUS status;
 159 
 160         make_nmb_name(&calling, myname, 0x0);
 161         make_nmb_name(&called , host, 0x20);
 162 
 163         zero_sockaddr(&ss);
 164 
 165         if (!(c = cli_initialise())) {
 166                 printf("Failed initialize cli_struct to connect with %s\n", host);
 167                 return NULL;
 168         }
 169 
 170         c->port = port_to_use;
 171 
 172         status = cli_connect(c, host, &ss);
 173         if (!NT_STATUS_IS_OK(status)) {
 174                 printf("Failed to connect with %s. Error %s\n", host, nt_errstr(status) );
 175                 return NULL;
 176         }
 177 
 178         c->use_kerberos = use_kerberos;
 179 
 180         c->timeout = 120000; /* set a really long timeout (2 minutes) */
 181         if (use_oplocks) c->use_oplocks = True;
 182         if (use_level_II_oplocks) c->use_level_II_oplocks = True;
 183 
 184         if (!cli_session_request(c, &calling, &called)) {
 185                 /*
 186                  * Well, that failed, try *SMBSERVER ...
 187                  * However, we must reconnect as well ...
 188                  */
 189                 status = cli_connect(c, host, &ss);
 190                 if (!NT_STATUS_IS_OK(status)) {
 191                         printf("Failed to connect with %s. Error %s\n", host, nt_errstr(status) );
 192                         return NULL;
 193                 }
 194 
 195                 make_nmb_name(&called, "*SMBSERVER", 0x20);
 196                 if (!cli_session_request(c, &calling, &called)) {
 197                         printf("%s rejected the session\n",host);
 198                         printf("We tried with a called name of %s & %s\n",
 199                                 host, "*SMBSERVER");
 200                         cli_shutdown(c);
 201                         return NULL;
 202                 }
 203         }
 204 
 205         return c;
 206 }
 207 
 208 /* Insert a NULL at the first separator of the given path and return a pointer
 209  * to the remainder of the string.
 210  */
 211 static char *
 212 terminate_path_at_separator(char * path)
     /* [<][>][^][v][top][bottom][index][help] */
 213 {
 214         char * p;
 215 
 216         if (!path) {
 217                 return NULL;
 218         }
 219 
 220         if ((p = strchr_m(path, '/'))) {
 221                 *p = '\0';
 222                 return p + 1;
 223         }
 224 
 225         if ((p = strchr_m(path, '\\'))) {
 226                 *p = '\0';
 227                 return p + 1;
 228         }
 229         
 230         /* No separator. */
 231         return NULL;
 232 }
 233 
 234 /*
 235   parse a //server/share type UNC name
 236 */
 237 bool smbcli_parse_unc(const char *unc_name, TALLOC_CTX *mem_ctx,
     /* [<][>][^][v][top][bottom][index][help] */
 238                       char **hostname, char **sharename)
 239 {
 240         char *p;
 241 
 242         *hostname = *sharename = NULL;
 243 
 244         if (strncmp(unc_name, "\\\\", 2) &&
 245             strncmp(unc_name, "//", 2)) {
 246                 return False;
 247         }
 248 
 249         *hostname = talloc_strdup(mem_ctx, &unc_name[2]);
 250         p = terminate_path_at_separator(*hostname);
 251 
 252         if (p && *p) {
 253                 *sharename = talloc_strdup(mem_ctx, p);
 254                 terminate_path_at_separator(*sharename);
 255         }
 256 
 257         if (*hostname && *sharename) {
 258                 return True;
 259         }
 260 
 261         TALLOC_FREE(*hostname);
 262         TALLOC_FREE(*sharename);
 263         return False;
 264 }
 265 
 266 static bool torture_open_connection_share(struct cli_state **c,
     /* [<][>][^][v][top][bottom][index][help] */
 267                                    const char *hostname, 
 268                                    const char *sharename)
 269 {
 270         bool retry;
 271         int flags = 0;
 272         NTSTATUS status;
 273 
 274         if (use_kerberos)
 275                 flags |= CLI_FULL_CONNECTION_USE_KERBEROS;
 276 
 277         status = cli_full_connection(c, myname,
 278                                      hostname, NULL, port_to_use, 
 279                                      sharename, "?????", 
 280                                      username, workgroup, 
 281                                      password, flags, Undefined, &retry);
 282         if (!NT_STATUS_IS_OK(status)) {
 283                 printf("failed to open share connection: //%s/%s port:%d - %s\n",
 284                         hostname, sharename, port_to_use, nt_errstr(status));
 285                 return False;
 286         }
 287 
 288         if (use_oplocks) (*c)->use_oplocks = True;
 289         if (use_level_II_oplocks) (*c)->use_level_II_oplocks = True;
 290         (*c)->timeout = 120000; /* set a really long timeout (2 minutes) */
 291 
 292         if (do_encrypt) {
 293                 return force_cli_encryption(*c,
 294                                         sharename);
 295         }
 296         return True;
 297 }
 298 
 299 bool torture_open_connection(struct cli_state **c, int conn_index)
     /* [<][>][^][v][top][bottom][index][help] */
 300 {
 301         char **unc_list = NULL;
 302         int num_unc_names = 0;
 303         bool result;
 304 
 305         if (use_multishare_conn==True) {
 306                 char *h, *s;
 307                 unc_list = file_lines_load(multishare_conn_fname, &num_unc_names, 0, NULL);
 308                 if (!unc_list || num_unc_names <= 0) {
 309                         printf("Failed to load unc names list from '%s'\n", multishare_conn_fname);
 310                         exit(1);
 311                 }
 312 
 313                 if (!smbcli_parse_unc(unc_list[conn_index % num_unc_names],
 314                                       NULL, &h, &s)) {
 315                         printf("Failed to parse UNC name %s\n",
 316                                unc_list[conn_index % num_unc_names]);
 317                         TALLOC_FREE(unc_list);
 318                         exit(1);
 319                 }
 320 
 321                 result = torture_open_connection_share(c, h, s);
 322 
 323                 /* h, s were copied earlier */
 324                 TALLOC_FREE(unc_list);
 325                 return result;
 326         }
 327 
 328         return torture_open_connection_share(c, host, share);
 329 }
 330 
 331 bool torture_cli_session_setup2(struct cli_state *cli, uint16 *new_vuid)
     /* [<][>][^][v][top][bottom][index][help] */
 332 {
 333         uint16 old_vuid = cli->vuid;
 334         fstring old_user_name;
 335         size_t passlen = strlen(password);
 336         NTSTATUS status;
 337         bool ret;
 338 
 339         fstrcpy(old_user_name, cli->user_name);
 340         cli->vuid = 0;
 341         ret = NT_STATUS_IS_OK(cli_session_setup(cli, username,
 342                                                 password, passlen,
 343                                                 password, passlen,
 344                                                 workgroup));
 345         *new_vuid = cli->vuid;
 346         cli->vuid = old_vuid;
 347         status = cli_set_username(cli, old_user_name);
 348         if (!NT_STATUS_IS_OK(status)) {
 349                 return false;
 350         }
 351         return ret;
 352 }
 353 
 354 
 355 bool torture_close_connection(struct cli_state *c)
     /* [<][>][^][v][top][bottom][index][help] */
 356 {
 357         bool ret = True;
 358         if (!cli_tdis(c)) {
 359                 printf("tdis failed (%s)\n", cli_errstr(c));
 360                 ret = False;
 361         }
 362 
 363         cli_shutdown(c);
 364 
 365         return ret;
 366 }
 367 
 368 
 369 /* check if the server produced the expected error code */
 370 static bool check_error(int line, struct cli_state *c, 
     /* [<][>][^][v][top][bottom][index][help] */
 371                         uint8 eclass, uint32 ecode, NTSTATUS nterr)
 372 {
 373         if (cli_is_dos_error(c)) {
 374                 uint8 cclass;
 375                 uint32 num;
 376 
 377                 /* Check DOS error */
 378 
 379                 cli_dos_error(c, &cclass, &num);
 380 
 381                 if (eclass != cclass || ecode != num) {
 382                         printf("unexpected error code class=%d code=%d\n", 
 383                                (int)cclass, (int)num);
 384                         printf(" expected %d/%d %s (line=%d)\n", 
 385                                (int)eclass, (int)ecode, nt_errstr(nterr), line);
 386                         return False;
 387                 }
 388 
 389         } else {
 390                 NTSTATUS status;
 391 
 392                 /* Check NT error */
 393 
 394                 status = cli_nt_error(c);
 395 
 396                 if (NT_STATUS_V(nterr) != NT_STATUS_V(status)) {
 397                         printf("unexpected error code %s\n", nt_errstr(status));
 398                         printf(" expected %s (line=%d)\n", nt_errstr(nterr), line);
 399                         return False;
 400                 }
 401         }
 402 
 403         return True;
 404 }
 405 
 406 
 407 static bool wait_lock(struct cli_state *c, int fnum, uint32 offset, uint32 len)
     /* [<][>][^][v][top][bottom][index][help] */
 408 {
 409         while (!cli_lock(c, fnum, offset, len, -1, WRITE_LOCK)) {
 410                 if (!check_error(__LINE__, c, ERRDOS, ERRlock, NT_STATUS_LOCK_NOT_GRANTED)) return False;
 411         }
 412         return True;
 413 }
 414 
 415 
 416 static bool rw_torture(struct cli_state *c)
     /* [<][>][^][v][top][bottom][index][help] */
 417 {
 418         const char *lockfname = "\\torture.lck";
 419         fstring fname;
 420         int fnum;
 421         int fnum2;
 422         pid_t pid2, pid = getpid();
 423         int i, j;
 424         char buf[1024];
 425         bool correct = True;
 426 
 427         memset(buf, '\0', sizeof(buf));
 428 
 429         fnum2 = cli_open(c, lockfname, O_RDWR | O_CREAT | O_EXCL, 
 430                          DENY_NONE);
 431         if (fnum2 == -1)
 432                 fnum2 = cli_open(c, lockfname, O_RDWR, DENY_NONE);
 433         if (fnum2 == -1) {
 434                 printf("open of %s failed (%s)\n", lockfname, cli_errstr(c));
 435                 return False;
 436         }
 437 
 438 
 439         for (i=0;i<torture_numops;i++) {
 440                 unsigned n = (unsigned)sys_random()%10;
 441                 if (i % 10 == 0) {
 442                         printf("%d\r", i); fflush(stdout);
 443                 }
 444                 slprintf(fname, sizeof(fstring) - 1, "\\torture.%u", n);
 445 
 446                 if (!wait_lock(c, fnum2, n*sizeof(int), sizeof(int))) {
 447                         return False;
 448                 }
 449 
 450                 fnum = cli_open(c, fname, O_RDWR | O_CREAT | O_TRUNC, DENY_ALL);
 451                 if (fnum == -1) {
 452                         printf("open failed (%s)\n", cli_errstr(c));
 453                         correct = False;
 454                         break;
 455                 }
 456 
 457                 if (cli_write(c, fnum, 0, (char *)&pid, 0, sizeof(pid)) != sizeof(pid)) {
 458                         printf("write failed (%s)\n", cli_errstr(c));
 459                         correct = False;
 460                 }
 461 
 462                 for (j=0;j<50;j++) {
 463                         if (cli_write(c, fnum, 0, (char *)buf, 
 464                                       sizeof(pid)+(j*sizeof(buf)), 
 465                                       sizeof(buf)) != sizeof(buf)) {
 466                                 printf("write failed (%s)\n", cli_errstr(c));
 467                                 correct = False;
 468                         }
 469                 }
 470 
 471                 pid2 = 0;
 472 
 473                 if (cli_read(c, fnum, (char *)&pid2, 0, sizeof(pid)) != sizeof(pid)) {
 474                         printf("read failed (%s)\n", cli_errstr(c));
 475                         correct = False;
 476                 }
 477 
 478                 if (pid2 != pid) {
 479                         printf("data corruption!\n");
 480                         correct = False;
 481                 }
 482 
 483                 if (!cli_close(c, fnum)) {
 484                         printf("close failed (%s)\n", cli_errstr(c));
 485                         correct = False;
 486                 }
 487 
 488                 if (!cli_unlink(c, fname)) {
 489                         printf("unlink failed (%s)\n", cli_errstr(c));
 490                         correct = False;
 491                 }
 492 
 493                 if (!cli_unlock(c, fnum2, n*sizeof(int), sizeof(int))) {
 494                         printf("unlock failed (%s)\n", cli_errstr(c));
 495                         correct = False;
 496                 }
 497         }
 498 
 499         cli_close(c, fnum2);
 500         cli_unlink(c, lockfname);
 501 
 502         printf("%d\n", i);
 503 
 504         return correct;
 505 }
 506 
 507 static bool run_torture(int dummy)
     /* [<][>][^][v][top][bottom][index][help] */
 508 {
 509         struct cli_state *cli;
 510         bool ret;
 511 
 512         cli = current_cli;
 513 
 514         cli_sockopt(cli, sockops);
 515 
 516         ret = rw_torture(cli);
 517         
 518         if (!torture_close_connection(cli)) {
 519                 ret = False;
 520         }
 521 
 522         return ret;
 523 }
 524 
 525 static bool rw_torture3(struct cli_state *c, char *lockfname)
     /* [<][>][^][v][top][bottom][index][help] */
 526 {
 527         int fnum = -1;
 528         unsigned int i = 0;
 529         char buf[131072];
 530         char buf_rd[131072];
 531         unsigned count;
 532         unsigned countprev = 0;
 533         ssize_t sent = 0;
 534         bool correct = True;
 535 
 536         srandom(1);
 537         for (i = 0; i < sizeof(buf); i += sizeof(uint32))
 538         {
 539                 SIVAL(buf, i, sys_random());
 540         }
 541 
 542         if (procnum == 0)
 543         {
 544                 fnum = cli_open(c, lockfname, O_RDWR | O_CREAT | O_EXCL, 
 545                                  DENY_NONE);
 546                 if (fnum == -1) {
 547                         printf("first open read/write of %s failed (%s)\n",
 548                                         lockfname, cli_errstr(c));
 549                         return False;
 550                 }
 551         }
 552         else
 553         {
 554                 for (i = 0; i < 500 && fnum == -1; i++)
 555                 {
 556                         fnum = cli_open(c, lockfname, O_RDONLY, 
 557                                          DENY_NONE);
 558                         smb_msleep(10);
 559                 }
 560                 if (fnum == -1) {
 561                         printf("second open read-only of %s failed (%s)\n",
 562                                         lockfname, cli_errstr(c));
 563                         return False;
 564                 }
 565         }
 566 
 567         i = 0;
 568         for (count = 0; count < sizeof(buf); count += sent)
 569         {
 570                 if (count >= countprev) {
 571                         printf("%d %8d\r", i, count);
 572                         fflush(stdout);
 573                         i++;
 574                         countprev += (sizeof(buf) / 20);
 575                 }
 576 
 577                 if (procnum == 0)
 578                 {
 579                         sent = ((unsigned)sys_random()%(20))+ 1;
 580                         if (sent > sizeof(buf) - count)
 581                         {
 582                                 sent = sizeof(buf) - count;
 583                         }
 584 
 585                         if (cli_write(c, fnum, 0, buf+count, count, (size_t)sent) != sent) {
 586                                 printf("write failed (%s)\n", cli_errstr(c));
 587                                 correct = False;
 588                         }
 589                 }
 590                 else
 591                 {
 592                         sent = cli_read(c, fnum, buf_rd+count, count,
 593                                                   sizeof(buf)-count);
 594                         if (sent < 0)
 595                         {
 596                                 printf("read failed offset:%d size:%ld (%s)\n",
 597                                        count, (unsigned long)sizeof(buf)-count,
 598                                        cli_errstr(c));
 599                                 correct = False;
 600                                 sent = 0;
 601                         }
 602                         if (sent > 0)
 603                         {
 604                                 if (memcmp(buf_rd+count, buf+count, sent) != 0)
 605                                 {
 606                                         printf("read/write compare failed\n");
 607                                         printf("offset: %d req %ld recvd %ld\n", count, (unsigned long)sizeof(buf)-count, (unsigned long)sent);
 608                                         correct = False;
 609                                         break;
 610                                 }
 611                         }
 612                 }
 613 
 614         }
 615 
 616         if (!cli_close(c, fnum)) {
 617                 printf("close failed (%s)\n", cli_errstr(c));
 618                 correct = False;
 619         }
 620 
 621         return correct;
 622 }
 623 
 624 static bool rw_torture2(struct cli_state *c1, struct cli_state *c2)
     /* [<][>][^][v][top][bottom][index][help] */
 625 {
 626         const char *lockfname = "\\torture2.lck";
 627         int fnum1;
 628         int fnum2;
 629         int i;
 630         char buf[131072];
 631         char buf_rd[131072];
 632         bool correct = True;
 633         ssize_t bytes_read;
 634 
 635         if (!cli_unlink(c1, lockfname)) {
 636                 printf("unlink failed (%s) (normal, this file should not exist)\n", cli_errstr(c1));
 637         }
 638 
 639         fnum1 = cli_open(c1, lockfname, O_RDWR | O_CREAT | O_EXCL, 
 640                          DENY_NONE);
 641         if (fnum1 == -1) {
 642                 printf("first open read/write of %s failed (%s)\n",
 643                                 lockfname, cli_errstr(c1));
 644                 return False;
 645         }
 646         fnum2 = cli_open(c2, lockfname, O_RDONLY, 
 647                          DENY_NONE);
 648         if (fnum2 == -1) {
 649                 printf("second open read-only of %s failed (%s)\n",
 650                                 lockfname, cli_errstr(c2));
 651                 cli_close(c1, fnum1);
 652                 return False;
 653         }
 654 
 655         for (i=0;i<torture_numops;i++)
 656         {
 657                 size_t buf_size = ((unsigned)sys_random()%(sizeof(buf)-1))+ 1;
 658                 if (i % 10 == 0) {
 659                         printf("%d\r", i); fflush(stdout);
 660                 }
 661 
 662                 generate_random_buffer((unsigned char *)buf, buf_size);
 663 
 664                 if (cli_write(c1, fnum1, 0, buf, 0, buf_size) != buf_size) {
 665                         printf("write failed (%s)\n", cli_errstr(c1));
 666                         correct = False;
 667                         break;
 668                 }
 669 
 670                 if ((bytes_read = cli_read(c2, fnum2, buf_rd, 0, buf_size)) != buf_size) {
 671                         printf("read failed (%s)\n", cli_errstr(c2));
 672                         printf("read %d, expected %ld\n", (int)bytes_read, 
 673                                (unsigned long)buf_size); 
 674                         correct = False;
 675                         break;
 676                 }
 677 
 678                 if (memcmp(buf_rd, buf, buf_size) != 0)
 679                 {
 680                         printf("read/write compare failed\n");
 681                         correct = False;
 682                         break;
 683                 }
 684         }
 685 
 686         if (!cli_close(c2, fnum2)) {
 687                 printf("close failed (%s)\n", cli_errstr(c2));
 688                 correct = False;
 689         }
 690         if (!cli_close(c1, fnum1)) {
 691                 printf("close failed (%s)\n", cli_errstr(c1));
 692                 correct = False;
 693         }
 694 
 695         if (!cli_unlink(c1, lockfname)) {
 696                 printf("unlink failed (%s)\n", cli_errstr(c1));
 697                 correct = False;
 698         }
 699 
 700         return correct;
 701 }
 702 
 703 static bool run_readwritetest(int dummy)
     /* [<][>][^][v][top][bottom][index][help] */
 704 {
 705         static struct cli_state *cli1, *cli2;
 706         bool test1, test2 = False;
 707 
 708         if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
 709                 return False;
 710         }
 711         cli_sockopt(cli1, sockops);
 712         cli_sockopt(cli2, sockops);
 713 
 714         printf("starting readwritetest\n");
 715 
 716         test1 = rw_torture2(cli1, cli2);
 717         printf("Passed readwritetest v1: %s\n", BOOLSTR(test1));
 718 
 719         if (test1) {
 720                 test2 = rw_torture2(cli1, cli1);
 721                 printf("Passed readwritetest v2: %s\n", BOOLSTR(test2));
 722         }
 723 
 724         if (!torture_close_connection(cli1)) {
 725                 test1 = False;
 726         }
 727 
 728         if (!torture_close_connection(cli2)) {
 729                 test2 = False;
 730         }
 731 
 732         return (test1 && test2);
 733 }
 734 
 735 static bool run_readwritemulti(int dummy)
     /* [<][>][^][v][top][bottom][index][help] */
 736 {
 737         struct cli_state *cli;
 738         bool test;
 739 
 740         cli = current_cli;
 741 
 742         cli_sockopt(cli, sockops);
 743 
 744         printf("run_readwritemulti: fname %s\n", randomfname);
 745         test = rw_torture3(cli, randomfname);
 746 
 747         if (!torture_close_connection(cli)) {
 748                 test = False;
 749         }
 750         
 751         return test;
 752 }
 753 
 754 static bool run_readwritelarge(int dummy)
     /* [<][>][^][v][top][bottom][index][help] */
 755 {
 756         static struct cli_state *cli1;
 757         int fnum1;
 758         const char *lockfname = "\\large.dat";
 759         SMB_OFF_T fsize;
 760         char buf[126*1024];
 761         bool correct = True;
 762  
 763         if (!torture_open_connection(&cli1, 0)) {
 764                 return False;
 765         }
 766         cli_sockopt(cli1, sockops);
 767         memset(buf,'\0',sizeof(buf));
 768         
 769         cli1->max_xmit = 128*1024;
 770         
 771         printf("starting readwritelarge\n");
 772  
 773         cli_unlink(cli1, lockfname);
 774 
 775         fnum1 = cli_open(cli1, lockfname, O_RDWR | O_CREAT | O_EXCL, DENY_NONE);
 776         if (fnum1 == -1) {
 777                 printf("open read/write of %s failed (%s)\n", lockfname, cli_errstr(cli1));
 778                 return False;
 779         }
 780    
 781         cli_write(cli1, fnum1, 0, buf, 0, sizeof(buf));
 782 
 783         if (!cli_qfileinfo(cli1, fnum1, NULL, &fsize, NULL, NULL, NULL, NULL, NULL)) {
 784                 printf("qfileinfo failed (%s)\n", cli_errstr(cli1));
 785                 correct = False;
 786         }
 787 
 788         if (fsize == sizeof(buf))
 789                 printf("readwritelarge test 1 succeeded (size = %lx)\n", 
 790                        (unsigned long)fsize);
 791         else {
 792                 printf("readwritelarge test 1 failed (size = %lx)\n", 
 793                        (unsigned long)fsize);
 794                 correct = False;
 795         }
 796 
 797         if (!cli_close(cli1, fnum1)) {
 798                 printf("close failed (%s)\n", cli_errstr(cli1));
 799                 correct = False;
 800         }
 801 
 802         if (!cli_unlink(cli1, lockfname)) {
 803                 printf("unlink failed (%s)\n", cli_errstr(cli1));
 804                 correct = False;
 805         }
 806 
 807         fnum1 = cli_open(cli1, lockfname, O_RDWR | O_CREAT | O_EXCL, DENY_NONE);
 808         if (fnum1 == -1) {
 809                 printf("open read/write of %s failed (%s)\n", lockfname, cli_errstr(cli1));
 810                 return False;
 811         }
 812         
 813         cli1->max_xmit = 4*1024;
 814         
 815         cli_smbwrite(cli1, fnum1, buf, 0, sizeof(buf));
 816         
 817         if (!cli_qfileinfo(cli1, fnum1, NULL, &fsize, NULL, NULL, NULL, NULL, NULL)) {
 818                 printf("qfileinfo failed (%s)\n", cli_errstr(cli1));
 819                 correct = False;
 820         }
 821 
 822         if (fsize == sizeof(buf))
 823                 printf("readwritelarge test 2 succeeded (size = %lx)\n", 
 824                        (unsigned long)fsize);
 825         else {
 826                 printf("readwritelarge test 2 failed (size = %lx)\n", 
 827                        (unsigned long)fsize);
 828                 correct = False;
 829         }
 830 
 831 #if 0
 832         /* ToDo - set allocation. JRA */
 833         if(!cli_set_allocation_size(cli1, fnum1, 0)) {
 834                 printf("set allocation size to zero failed (%s)\n", cli_errstr(&cli1));
 835                 return False;
 836         }
 837         if (!cli_qfileinfo(cli1, fnum1, NULL, &fsize, NULL, NULL, NULL, NULL, NULL)) {
 838                 printf("qfileinfo failed (%s)\n", cli_errstr(cli1));
 839                 correct = False;
 840         }
 841         if (fsize != 0)
 842                 printf("readwritelarge test 3 (truncate test) succeeded (size = %x)\n", fsize);
 843 #endif
 844 
 845         if (!cli_close(cli1, fnum1)) {
 846                 printf("close failed (%s)\n", cli_errstr(cli1));
 847                 correct = False;
 848         }
 849         
 850         if (!torture_close_connection(cli1)) {
 851                 correct = False;
 852         }
 853         return correct;
 854 }
 855 
 856 int line_count = 0;
 857 int nbio_id;
 858 
 859 #define ival(s) strtol(s, NULL, 0)
 860 
 861 /* run a test that simulates an approximate netbench client load */
 862 static bool run_netbench(int client)
     /* [<][>][^][v][top][bottom][index][help] */
 863 {
 864         struct cli_state *cli;
 865         int i;
 866         char line[1024];
 867         char cname[20];
 868         FILE *f;
 869         const char *params[20];
 870         bool correct = True;
 871 
 872         cli = current_cli;
 873 
 874         nbio_id = client;
 875 
 876         cli_sockopt(cli, sockops);
 877 
 878         nb_setup(cli);
 879 
 880         slprintf(cname,sizeof(cname)-1, "client%d", client);
 881 
 882         f = fopen(client_txt, "r");
 883 
 884         if (!f) {
 885                 perror(client_txt);
 886                 return False;
 887         }
 888 
 889         while (fgets(line, sizeof(line)-1, f)) {
 890                 char *saveptr;
 891                 line_count++;
 892 
 893                 line[strlen(line)-1] = 0;
 894 
 895                 /* printf("[%d] %s\n", line_count, line); */
 896 
 897                 all_string_sub(line,"client1", cname, sizeof(line));
 898 
 899                 /* parse the command parameters */
 900                 params[0] = strtok_r(line, " ", &saveptr);
 901                 i = 0;
 902                 while (params[i]) params[++i] = strtok_r(NULL, " ", &saveptr);
 903 
 904                 params[i] = "";
 905 
 906                 if (i < 2) continue;
 907 
 908                 if (!strncmp(params[0],"SMB", 3)) {
 909                         printf("ERROR: You are using a dbench 1 load file\n");
 910                         exit(1);
 911                 }
 912 
 913                 if (!strcmp(params[0],"NTCreateX")) {
 914                         nb_createx(params[1], ival(params[2]), ival(params[3]), 
 915                                    ival(params[4]));
 916                 } else if (!strcmp(params[0],"Close")) {
 917                         nb_close(ival(params[1]));
 918                 } else if (!strcmp(params[0],"Rename")) {
 919                         nb_rename(params[1], params[2]);
 920                 } else if (!strcmp(params[0],"Unlink")) {
 921                         nb_unlink(params[1]);
 922                 } else if (!strcmp(params[0],"Deltree")) {
 923                         nb_deltree(params[1]);
 924                 } else if (!strcmp(params[0],"Rmdir")) {
 925                         nb_rmdir(params[1]);
 926                 } else if (!strcmp(params[0],"QUERY_PATH_INFORMATION")) {
 927                         nb_qpathinfo(params[1]);
 928                 } else if (!strcmp(params[0],"QUERY_FILE_INFORMATION")) {
 929                         nb_qfileinfo(ival(params[1]));
 930                 } else if (!strcmp(params[0],"QUERY_FS_INFORMATION")) {
 931                         nb_qfsinfo(ival(params[1]));
 932                 } else if (!strcmp(params[0],"FIND_FIRST")) {
 933                         nb_findfirst(params[1]);
 934                 } else if (!strcmp(params[0],"WriteX")) {
 935                         nb_writex(ival(params[1]), 
 936                                   ival(params[2]), ival(params[3]), ival(params[4]));
 937                 } else if (!strcmp(params[0],"ReadX")) {
 938                         nb_readx(ival(params[1]), 
 939                                   ival(params[2]), ival(params[3]), ival(params[4]));
 940                 } else if (!strcmp(params[0],"Flush")) {
 941                         nb_flush(ival(params[1]));
 942                 } else {
 943                         printf("Unknown operation %s\n", params[0]);
 944                         exit(1);
 945                 }
 946         }
 947         fclose(f);
 948 
 949         nb_cleanup();
 950 
 951         if (!torture_close_connection(cli)) {
 952                 correct = False;
 953         }
 954         
 955         return correct;
 956 }
 957 
 958 
 959 /* run a test that simulates an approximate netbench client load */
 960 static bool run_nbench(int dummy)
     /* [<][>][^][v][top][bottom][index][help] */
 961 {
 962         double t;
 963         bool correct = True;
 964 
 965         nbio_shmem(nprocs);
 966 
 967         nbio_id = -1;
 968 
 969         signal(SIGALRM, nb_alarm);
 970         alarm(1);
 971         t = create_procs(run_netbench, &correct);
 972         alarm(0);
 973 
 974         printf("\nThroughput %g MB/sec\n", 
 975                1.0e-6 * nbio_total() / t);
 976         return correct;
 977 }
 978 
 979 
 980 /*
 981   This test checks for two things:
 982 
 983   1) correct support for retaining locks over a close (ie. the server
 984      must not use posix semantics)
 985   2) support for lock timeouts
 986  */
 987 static bool run_locktest1(int dummy)
     /* [<][>][^][v][top][bottom][index][help] */
 988 {
 989         struct cli_state *cli1, *cli2;
 990         const char *fname = "\\lockt1.lck";
 991         int fnum1, fnum2, fnum3;
 992         time_t t1, t2;
 993         unsigned lock_timeout;
 994 
 995         if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
 996                 return False;
 997         }
 998         cli_sockopt(cli1, sockops);
 999         cli_sockopt(cli2, sockops);
1000 
1001         printf("starting locktest1\n");
1002 
1003         cli_unlink(cli1, fname);
1004 
1005         fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1006         if (fnum1 == -1) {
1007                 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
1008                 return False;
1009         }
1010         fnum2 = cli_open(cli1, fname, O_RDWR, DENY_NONE);
1011         if (fnum2 == -1) {
1012                 printf("open2 of %s failed (%s)\n", fname, cli_errstr(cli1));
1013                 return False;
1014         }
1015         fnum3 = cli_open(cli2, fname, O_RDWR, DENY_NONE);
1016         if (fnum3 == -1) {
1017                 printf("open3 of %s failed (%s)\n", fname, cli_errstr(cli2));
1018                 return False;
1019         }
1020 
1021         if (!cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK)) {
1022                 printf("lock1 failed (%s)\n", cli_errstr(cli1));
1023                 return False;
1024         }
1025 
1026 
1027         if (cli_lock(cli2, fnum3, 0, 4, 0, WRITE_LOCK)) {
1028                 printf("lock2 succeeded! This is a locking bug\n");
1029                 return False;
1030         } else {
1031                 if (!check_error(__LINE__, cli2, ERRDOS, ERRlock, 
1032                                  NT_STATUS_LOCK_NOT_GRANTED)) return False;
1033         }
1034 
1035 
1036         lock_timeout = (1 + (random() % 20));
1037         printf("Testing lock timeout with timeout=%u\n", lock_timeout);
1038         t1 = time(NULL);
1039         if (cli_lock(cli2, fnum3, 0, 4, lock_timeout * 1000, WRITE_LOCK)) {
1040                 printf("lock3 succeeded! This is a locking bug\n");
1041                 return False;
1042         } else {
1043                 if (!check_error(__LINE__, cli2, ERRDOS, ERRlock, 
1044                                  NT_STATUS_FILE_LOCK_CONFLICT)) return False;
1045         }
1046         t2 = time(NULL);
1047 
1048         if (ABS(t2 - t1) < lock_timeout-1) {
1049                 printf("error: This server appears not to support timed lock requests\n");
1050         }
1051 
1052         printf("server slept for %u seconds for a %u second timeout\n",
1053                (unsigned int)(t2-t1), lock_timeout);
1054 
1055         if (!cli_close(cli1, fnum2)) {
1056                 printf("close1 failed (%s)\n", cli_errstr(cli1));
1057                 return False;
1058         }
1059 
1060         if (cli_lock(cli2, fnum3, 0, 4, 0, WRITE_LOCK)) {
1061                 printf("lock4 succeeded! This is a locking bug\n");
1062                 return False;
1063         } else {
1064                 if (!check_error(__LINE__, cli2, ERRDOS, ERRlock, 
1065                                  NT_STATUS_FILE_LOCK_CONFLICT)) return False;
1066         }
1067 
1068         if (!cli_close(cli1, fnum1)) {
1069                 printf("close2 failed (%s)\n", cli_errstr(cli1));
1070                 return False;
1071         }
1072 
1073         if (!cli_close(cli2, fnum3)) {
1074                 printf("close3 failed (%s)\n", cli_errstr(cli2));
1075                 return False;
1076         }
1077 
1078         if (!cli_unlink(cli1, fname)) {
1079                 printf("unlink failed (%s)\n", cli_errstr(cli1));
1080                 return False;
1081         }
1082 
1083 
1084         if (!torture_close_connection(cli1)) {
1085                 return False;
1086         }
1087 
1088         if (!torture_close_connection(cli2)) {
1089                 return False;
1090         }
1091 
1092         printf("Passed locktest1\n");
1093         return True;
1094 }
1095 
1096 /*
1097   this checks to see if a secondary tconx can use open files from an
1098   earlier tconx
1099  */
1100 static bool run_tcon_test(int dummy)
     /* [<][>][^][v][top][bottom][index][help] */
1101 {
1102         static struct cli_state *cli;
1103         const char *fname = "\\tcontest.tmp";
1104         int fnum1;
1105         uint16 cnum1, cnum2, cnum3;
1106         uint16 vuid1, vuid2;
1107         char buf[4];
1108         bool ret = True;
1109         NTSTATUS status;
1110 
1111         memset(buf, '\0', sizeof(buf));
1112 
1113         if (!torture_open_connection(&cli, 0)) {
1114                 return False;
1115         }
1116         cli_sockopt(cli, sockops);
1117 
1118         printf("starting tcontest\n");
1119 
1120         cli_unlink(cli, fname);
1121 
1122         fnum1 = cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1123         if (fnum1 == -1) {
1124                 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
1125                 return False;
1126         }
1127 
1128         cnum1 = cli->cnum;
1129         vuid1 = cli->vuid;
1130 
1131         if (cli_write(cli, fnum1, 0, buf, 130, 4) != 4) {
1132                 printf("initial write failed (%s)", cli_errstr(cli));
1133                 return False;
1134         }
1135 
1136         status = cli_tcon_andx(cli, share, "?????",
1137                                password, strlen(password)+1);
1138         if (!NT_STATUS_IS_OK(status)) {
1139                 printf("%s refused 2nd tree connect (%s)\n", host,
1140                        nt_errstr(status));
1141                 cli_shutdown(cli);
1142                 return False;
1143         }
1144 
1145         cnum2 = cli->cnum;
1146         cnum3 = MAX(cnum1, cnum2) + 1; /* any invalid number */
1147         vuid2 = cli->vuid + 1;
1148 
1149         /* try a write with the wrong tid */
1150         cli->cnum = cnum2;
1151 
1152         if (cli_write(cli, fnum1, 0, buf, 130, 4) == 4) {
1153                 printf("* server allows write with wrong TID\n");
1154                 ret = False;
1155         } else {
1156                 printf("server fails write with wrong TID : %s\n", cli_errstr(cli));
1157         }
1158 
1159 
1160         /* try a write with an invalid tid */
1161         cli->cnum = cnum3;
1162 
1163         if (cli_write(cli, fnum1, 0, buf, 130, 4) == 4) {
1164                 printf("* server allows write with invalid TID\n");
1165                 ret = False;
1166         } else {
1167                 printf("server fails write with invalid TID : %s\n", cli_errstr(cli));
1168         }
1169 
1170         /* try a write with an invalid vuid */
1171         cli->vuid = vuid2;
1172         cli->cnum = cnum1;
1173 
1174         if (cli_write(cli, fnum1, 0, buf, 130, 4) == 4) {
1175                 printf("* server allows write with invalid VUID\n");
1176                 ret = False;
1177         } else {
1178                 printf("server fails write with invalid VUID : %s\n", cli_errstr(cli));
1179         }
1180 
1181         cli->cnum = cnum1;
1182         cli->vuid = vuid1;
1183 
1184         if (!cli_close(cli, fnum1)) {
1185                 printf("close failed (%s)\n", cli_errstr(cli));
1186                 return False;
1187         }
1188 
1189         cli->cnum = cnum2;
1190 
1191         if (!cli_tdis(cli)) {
1192                 printf("secondary tdis failed (%s)\n", cli_errstr(cli));
1193                 return False;
1194         }
1195 
1196         cli->cnum = cnum1;
1197 
1198         if (!torture_close_connection(cli)) {
1199                 return False;
1200         }
1201 
1202         return ret;
1203 }
1204 
1205 
1206 /*
1207  checks for old style tcon support
1208  */
1209 static bool run_tcon2_test(int dummy)
     /* [<][>][^][v][top][bottom][index][help] */
1210 {
1211         static struct cli_state *cli;
1212         uint16 cnum, max_xmit;
1213         char *service;
1214         NTSTATUS status;
1215 
1216         if (!torture_open_connection(&cli, 0)) {
1217                 return False;
1218         }
1219         cli_sockopt(cli, sockops);
1220 
1221         printf("starting tcon2 test\n");
1222 
1223         if (asprintf(&service, "\\\\%s\\%s", host, share) == -1) {
1224                 return false;
1225         }
1226 
1227         status = cli_raw_tcon(cli, service, password, "?????", &max_xmit, &cnum);
1228 
1229         if (!NT_STATUS_IS_OK(status)) {
1230                 printf("tcon2 failed : %s\n", cli_errstr(cli));
1231         } else {
1232                 printf("tcon OK : max_xmit=%d cnum=%d tid=%d\n", 
1233                        (int)max_xmit, (int)cnum, SVAL(cli->inbuf, smb_tid));
1234         }
1235 
1236         if (!torture_close_connection(cli)) {
1237                 return False;
1238         }
1239 
1240         printf("Passed tcon2 test\n");
1241         return True;
1242 }
1243 
1244 static bool tcon_devtest(struct cli_state *cli,
     /* [<][>][^][v][top][bottom][index][help] */
1245                          const char *myshare, const char *devtype,
1246                          const char *return_devtype,
1247                          NTSTATUS expected_error)
1248 {
1249         NTSTATUS status;
1250         bool ret;
1251 
1252         status = cli_tcon_andx(cli, myshare, devtype,
1253                                password, strlen(password)+1);
1254 
1255         if (NT_STATUS_IS_OK(expected_error)) {
1256                 if (NT_STATUS_IS_OK(status)) {
1257                         if (strcmp(cli->dev, return_devtype) == 0) {
1258                                 ret = True;
1259                         } else { 
1260                                 printf("tconX to share %s with type %s "
1261                                        "succeeded but returned the wrong "
1262                                        "device type (got [%s] but should have got [%s])\n",
1263                                        myshare, devtype, cli->dev, return_devtype);
1264                                 ret = False;
1265                         }
1266                 } else {
1267                         printf("tconX to share %s with type %s "
1268                                "should have succeeded but failed\n",
1269                                myshare, devtype);
1270                         ret = False;
1271                 }
1272                 cli_tdis(cli);
1273         } else {
1274                 if (NT_STATUS_IS_OK(status)) {
1275                         printf("tconx to share %s with type %s "
1276                                "should have failed but succeeded\n",
1277                                myshare, devtype);
1278                         ret = False;
1279                 } else {
1280                         if (NT_STATUS_EQUAL(cli_nt_error(cli),
1281                                             expected_error)) {
1282                                 ret = True;
1283                         } else {
1284                                 printf("Returned unexpected error\n");
1285                                 ret = False;
1286                         }
1287                 }
1288         }
1289         return ret;
1290 }
1291 
1292 /*
1293  checks for correct tconX support
1294  */
1295 static bool run_tcon_devtype_test(int dummy)
     /* [<][>][^][v][top][bottom][index][help] */
1296 {
1297         static struct cli_state *cli1 = NULL;
1298         bool retry;
1299         int flags = 0;
1300         NTSTATUS status;
1301         bool ret = True;
1302 
1303         status = cli_full_connection(&cli1, myname,
1304                                      host, NULL, port_to_use,
1305                                      NULL, NULL,
1306                                      username, workgroup,
1307                                      password, flags, Undefined, &retry);
1308 
1309         if (!NT_STATUS_IS_OK(status)) {
1310                 printf("could not open connection\n");
1311                 return False;
1312         }
1313 
1314         if (!tcon_devtest(cli1, "IPC$", "A:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1315                 ret = False;
1316 
1317         if (!tcon_devtest(cli1, "IPC$", "?????", "IPC", NT_STATUS_OK))
1318                 ret = False;
1319 
1320         if (!tcon_devtest(cli1, "IPC$", "LPT:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1321                 ret = False;
1322 
1323         if (!tcon_devtest(cli1, "IPC$", "IPC", "IPC", NT_STATUS_OK))
1324                 ret = False;
1325                         
1326         if (!tcon_devtest(cli1, "IPC$", "FOOBA", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1327                 ret = False;
1328 
1329         if (!tcon_devtest(cli1, share, "A:", "A:", NT_STATUS_OK))
1330                 ret = False;
1331 
1332         if (!tcon_devtest(cli1, share, "?????", "A:", NT_STATUS_OK))
1333                 ret = False;
1334 
1335         if (!tcon_devtest(cli1, share, "LPT:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1336                 ret = False;
1337 
1338         if (!tcon_devtest(cli1, share, "IPC", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1339                 ret = False;
1340                         
1341         if (!tcon_devtest(cli1, share, "FOOBA", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1342                 ret = False;
1343 
1344         cli_shutdown(cli1);
1345 
1346         if (ret)
1347                 printf("Passed tcondevtest\n");
1348 
1349         return ret;
1350 }
1351 
1352 
1353 /*
1354   This test checks that 
1355 
1356   1) the server supports multiple locking contexts on the one SMB
1357   connection, distinguished by PID.  
1358 
1359   2) the server correctly fails overlapping locks made by the same PID (this
1360      goes against POSIX behaviour, which is why it is tricky to implement)
1361 
1362   3) the server denies unlock requests by an incorrect client PID
1363 */
1364 static bool run_locktest2(int dummy)
     /* [<][>][^][v][top][bottom][index][help] */
1365 {
1366         static struct cli_state *cli;
1367         const char *fname = "\\lockt2.lck";
1368         int fnum1, fnum2, fnum3;
1369         bool correct = True;
1370 
1371         if (!torture_open_connection(&cli, 0)) {
1372                 return False;
1373         }
1374 
1375         cli_sockopt(cli, sockops);
1376 
1377         printf("starting locktest2\n");
1378 
1379         cli_unlink(cli, fname);
1380 
1381         cli_setpid(cli, 1);
1382 
1383         fnum1 = cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1384         if (fnum1 == -1) {
1385                 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
1386                 return False;
1387         }
1388 
1389         fnum2 = cli_open(cli, fname, O_RDWR, DENY_NONE);
1390         if (fnum2 == -1) {
1391                 printf("open2 of %s failed (%s)\n", fname, cli_errstr(cli));
1392                 return False;
1393         }
1394 
1395         cli_setpid(cli, 2);
1396 
1397         fnum3 = cli_open(cli, fname, O_RDWR, DENY_NONE);
1398         if (fnum3 == -1) {
1399                 printf("open3 of %s failed (%s)\n", fname, cli_errstr(cli));
1400                 return False;
1401         }
1402 
1403         cli_setpid(cli, 1);
1404 
1405         if (!cli_lock(cli, fnum1, 0, 4, 0, WRITE_LOCK)) {
1406                 printf("lock1 failed (%s)\n", cli_errstr(cli));
1407                 return False;
1408         }
1409 
1410         if (cli_lock(cli, fnum1, 0, 4, 0, WRITE_LOCK)) {
1411                 printf("WRITE lock1 succeeded! This is a locking bug\n");
1412                 correct = False;
1413         } else {
1414                 if (!check_error(__LINE__, cli, ERRDOS, ERRlock, 
1415                                  NT_STATUS_LOCK_NOT_GRANTED)) return False;
1416         }
1417 
1418         if (cli_lock(cli, fnum2, 0, 4, 0, WRITE_LOCK)) {
1419                 printf("WRITE lock2 succeeded! This is a locking bug\n");
1420                 correct = False;
1421         } else {
1422                 if (!check_error(__LINE__, cli, ERRDOS, ERRlock, 
1423                                  NT_STATUS_LOCK_NOT_GRANTED)) return False;
1424         }
1425 
1426         if (cli_lock(cli, fnum2, 0, 4, 0, READ_LOCK)) {
1427                 printf("READ lock2 succeeded! This is a locking bug\n");
1428                 correct = False;
1429         } else {
1430                 if (!check_error(__LINE__, cli, ERRDOS, ERRlock, 
1431                                  NT_STATUS_FILE_LOCK_CONFLICT)) return False;
1432         }
1433 
1434         if (!cli_lock(cli, fnum1, 100, 4, 0, WRITE_LOCK)) {
1435                 printf("lock at 100 failed (%s)\n", cli_errstr(cli));
1436         }
1437         cli_setpid(cli, 2);
1438         if (cli_unlock(cli, fnum1, 100, 4)) {
1439                 printf("unlock at 100 succeeded! This is a locking bug\n");
1440                 correct = False;
1441         }
1442 
1443         if (cli_unlock(cli, fnum1, 0, 4)) {
1444                 printf("unlock1 succeeded! This is a locking bug\n");
1445                 correct = False;
1446         } else {
1447                 if (!check_error(__LINE__, cli, 
1448                                  ERRDOS, ERRlock, 
1449                                  NT_STATUS_RANGE_NOT_LOCKED)) return False;
1450         }
1451 
1452         if (cli_unlock(cli, fnum1, 0, 8)) {
1453                 printf("unlock2 succeeded! This is a locking bug\n");
1454                 correct = False;
1455         } else {
1456                 if (!check_error(__LINE__, cli, 
1457                                  ERRDOS, ERRlock, 
1458                                  NT_STATUS_RANGE_NOT_LOCKED)) return False;
1459         }
1460 
1461         if (cli_lock(cli, fnum3, 0, 4, 0, WRITE_LOCK)) {
1462                 printf("lock3 succeeded! This is a locking bug\n");
1463                 correct = False;
1464         } else {
1465                 if (!check_error(__LINE__, cli, ERRDOS, ERRlock, NT_STATUS_LOCK_NOT_GRANTED)) return False;
1466         }
1467 
1468         cli_setpid(cli, 1);
1469 
1470         if (!cli_close(cli, fnum1)) {
1471                 printf("close1 failed (%s)\n", cli_errstr(cli));
1472                 return False;
1473         }
1474 
1475         if (!cli_close(cli, fnum2)) {
1476                 printf("close2 failed (%s)\n", cli_errstr(cli));
1477                 return False;
1478         }
1479 
1480         if (!cli_close(cli, fnum3)) {
1481                 printf("close3 failed (%s)\n", cli_errstr(cli));
1482                 return False;
1483         }
1484 
1485         if (!torture_close_connection(cli)) {
1486                 correct = False;
1487         }
1488 
1489         printf("locktest2 finished\n");
1490 
1491         return correct;
1492 }
1493 
1494 
1495 /*
1496   This test checks that 
1497 
1498   1) the server supports the full offset range in lock requests
1499 */
1500 static bool run_locktest3(int dummy)
     /* [<][>][^][v][top][bottom][index][help] */
1501 {
1502         static struct cli_state *cli1, *cli2;
1503         const char *fname = "\\lockt3.lck";
1504         int fnum1, fnum2, i;
1505         uint32 offset;
1506         bool correct = True;
1507 
1508 #define NEXT_OFFSET offset += (~(uint32)0) / torture_numops
1509 
1510         if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1511                 return False;
1512         }
1513         cli_sockopt(cli1, sockops);
1514         cli_sockopt(cli2, sockops);
1515 
1516         printf("starting locktest3\n");
1517 
1518         cli_unlink(cli1, fname);
1519 
1520         fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1521         if (fnum1 == -1) {
1522                 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
1523                 return False;
1524         }
1525         fnum2 = cli_open(cli2, fname, O_RDWR, DENY_NONE);
1526         if (fnum2 == -1) {
1527                 printf("open2 of %s failed (%s)\n", fname, cli_errstr(cli2));
1528                 return False;
1529         }
1530 
1531         for (offset=i=0;i<torture_numops;i++) {
1532                 NEXT_OFFSET;
1533                 if (!cli_lock(cli1, fnum1, offset-1, 1, 0, WRITE_LOCK)) {
1534                         printf("lock1 %d failed (%s)\n", 
1535                                i,
1536                                cli_errstr(cli1));
1537                         return False;
1538                 }
1539 
1540                 if (!cli_lock(cli2, fnum2, offset-2, 1, 0, WRITE_LOCK)) {
1541                         printf("lock2 %d failed (%s)\n", 
1542                                i,
1543                                cli_errstr(cli1));
1544                         return False;
1545                 }
1546         }
1547 
1548         for (offset=i=0;i<torture_numops;i++) {
1549                 NEXT_OFFSET;
1550 
1551                 if (cli_lock(cli1, fnum1, offset-2, 1, 0, WRITE_LOCK)) {
1552                         printf("error: lock1 %d succeeded!\n", i);
1553                         return False;
1554                 }
1555 
1556                 if (cli_lock(cli2, fnum2, offset-1, 1, 0, WRITE_LOCK)) {
1557                         printf("error: lock2 %d succeeded!\n", i);
1558                         return False;
1559                 }
1560 
1561                 if (cli_lock(cli1, fnum1, offset-1, 1, 0, WRITE_LOCK)) {
1562                         printf("error: lock3 %d succeeded!\n", i);
1563                         return False;
1564                 }
1565 
1566                 if (cli_lock(cli2, fnum2, offset-2, 1, 0, WRITE_LOCK)) {
1567                         printf("error: lock4 %d succeeded!\n", i);
1568                         return False;
1569                 }
1570         }
1571 
1572         for (offset=i=0;i<torture_numops;i++) {
1573                 NEXT_OFFSET;
1574 
1575                 if (!cli_unlock(cli1, fnum1, offset-1, 1)) {
1576                         printf("unlock1 %d failed (%s)\n", 
1577                                i,
1578                                cli_errstr(cli1));
1579                         return False;
1580                 }
1581 
1582                 if (!cli_unlock(cli2, fnum2, offset-2, 1)) {
1583                         printf("unlock2 %d failed (%s)\n", 
1584                                i,
1585                                cli_errstr(cli1));
1586                         return False;
1587                 }
1588         }
1589 
1590         if (!cli_close(cli1, fnum1)) {
1591                 printf("close1 failed (%s)\n", cli_errstr(cli1));
1592                 return False;
1593         }
1594 
1595         if (!cli_close(cli2, fnum2)) {
1596                 printf("close2 failed (%s)\n", cli_errstr(cli2));
1597                 return False;
1598         }
1599 
1600         if (!cli_unlink(cli1, fname)) {
1601                 printf("unlink failed (%s)\n", cli_errstr(cli1));
1602                 return False;
1603         }
1604 
1605         if (!torture_close_connection(cli1)) {
1606                 correct = False;
1607         }
1608         
1609         if (!torture_close_connection(cli2)) {
1610                 correct = False;
1611         }
1612 
1613         printf("finished locktest3\n");
1614 
1615         return correct;
1616 }
1617 
1618 #define EXPECTED(ret, v) if ((ret) != (v)) { \
1619         printf("** "); correct = False; \
1620         }
1621 
1622 /*
1623   looks at overlapping locks
1624 */
1625 static bool run_locktest4(int dummy)
     /* [<][>][^][v][top][bottom][index][help] */
1626 {
1627         static struct cli_state *cli1, *cli2;
1628         const char *fname = "\\lockt4.lck";
1629         int fnum1, fnum2, f;
1630         bool ret;
1631         char buf[1000];
1632         bool correct = True;
1633 
1634         if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1635                 return False;
1636         }
1637 
1638         cli_sockopt(cli1, sockops);
1639         cli_sockopt(cli2, sockops);
1640 
1641         printf("starting locktest4\n");
1642 
1643         cli_unlink(cli1, fname);
1644 
1645         fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1646         fnum2 = cli_open(cli2, fname, O_RDWR, DENY_NONE);
1647 
1648         memset(buf, 0, sizeof(buf));
1649 
1650         if (cli_write(cli1, fnum1, 0, buf, 0, sizeof(buf)) != sizeof(buf)) {
1651                 printf("Failed to create file\n");
1652                 correct = False;
1653                 goto fail;
1654         }
1655 
1656         ret = cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK) &&
1657               cli_lock(cli1, fnum1, 2, 4, 0, WRITE_LOCK);
1658         EXPECTED(ret, False);
1659         printf("the same process %s set overlapping write locks\n", ret?"can":"cannot");
1660             
1661         ret = cli_lock(cli1, fnum1, 10, 4, 0, READ_LOCK) &&
1662               cli_lock(cli1, fnum1, 12, 4, 0, READ_LOCK);
1663         EXPECTED(ret, True);
1664         printf("the same process %s set overlapping read locks\n", ret?"can":"cannot");
1665 
1666         ret = cli_lock(cli1, fnum1, 20, 4, 0, WRITE_LOCK) &&
1667               cli_lock(cli2, fnum2, 22, 4, 0, WRITE_LOCK);
1668         EXPECTED(ret, False);
1669         printf("a different connection %s set overlapping write locks\n", ret?"can":"cannot");
1670             
1671         ret = cli_lock(cli1, fnum1, 30, 4, 0, READ_LOCK) &&
1672               cli_lock(cli2, fnum2, 32, 4, 0, READ_LOCK);
1673         EXPECTED(ret, True);
1674         printf("a different connection %s set overlapping read locks\n", ret?"can":"cannot");
1675         
1676         ret = (cli_setpid(cli1, 1), cli_lock(cli1, fnum1, 40, 4, 0, WRITE_LOCK)) &&
1677               (cli_setpid(cli1, 2), cli_lock(cli1, fnum1, 42, 4, 0, WRITE_LOCK));
1678         EXPECTED(ret, False);
1679         printf("a different pid %s set overlapping write locks\n", ret?"can":"cannot");
1680             
1681         ret = (cli_setpid(cli1, 1), cli_lock(cli1, fnum1, 50, 4, 0, READ_LOCK)) &&
1682               (cli_setpid(cli1, 2), cli_lock(cli1, fnum1, 52, 4, 0, READ_LOCK));
1683         EXPECTED(ret, True);
1684         printf("a different pid %s set overlapping read locks\n", ret?"can":"cannot");
1685 
1686         ret = cli_lock(cli1, fnum1, 60, 4, 0, READ_LOCK) &&
1687               cli_lock(cli1, fnum1, 60, 4, 0, READ_LOCK);
1688         EXPECTED(ret, True);
1689         printf("the same process %s set the same read lock twice\n", ret?"can":"cannot");
1690 
1691         ret = cli_lock(cli1, fnum1, 70, 4, 0, WRITE_LOCK) &&
1692               cli_lock(cli1, fnum1, 70, 4, 0, WRITE_LOCK);
1693         EXPECTED(ret, False);
1694         printf("the same process %s set the same write lock twice\n", ret?"can":"cannot");
1695 
1696         ret = cli_lock(cli1, fnum1, 80, 4, 0, READ_LOCK) &&
1697               cli_lock(cli1, fnum1, 80, 4, 0, WRITE_LOCK);
1698         EXPECTED(ret, False);
1699         printf("the same process %s overlay a read lock with a write lock\n", ret?"can":"cannot");
1700 
1701         ret = cli_lock(cli1, fnum1, 90, 4, 0, WRITE_LOCK) &&
1702               cli_lock(cli1, fnum1, 90, 4, 0, READ_LOCK);
1703         EXPECTED(ret, True);
1704         printf("the same process %s overlay a write lock with a read lock\n", ret?"can":"cannot");
1705 
1706         ret = (cli_setpid(cli1, 1), cli_lock(cli1, fnum1, 100, 4, 0, WRITE_LOCK)) &&
1707               (cli_setpid(cli1, 2), cli_lock(cli1, fnum1, 100, 4, 0, READ_LOCK));
1708         EXPECTED(ret, False);
1709         printf("a different pid %s overlay a write lock with a read lock\n", ret?"can":"cannot");
1710 
1711         ret = cli_lock(cli1, fnum1, 110, 4, 0, READ_LOCK) &&
1712               cli_lock(cli1, fnum1, 112, 4, 0, READ_LOCK) &&
1713               cli_unlock(cli1, fnum1, 110, 6);
1714         EXPECTED(ret, False);
1715         printf("the same process %s coalesce read locks\n", ret?"can":"cannot");
1716 
1717 
1718         ret = cli_lock(cli1, fnum1, 120, 4, 0, WRITE_LOCK) &&
1719               (cli_read(cli2, fnum2, buf, 120, 4) == 4);
1720         EXPECTED(ret, False);
1721         printf("this server %s strict write locking\n", ret?"doesn't do":"does");
1722 
1723         ret = cli_lock(cli1, fnum1, 130, 4, 0, READ_LOCK) &&
1724               (cli_write(cli2, fnum2, 0, buf, 130, 4) == 4);
1725         EXPECTED(ret, False);
1726         printf("this server %s strict read locking\n", ret?"doesn't do":"does");
1727 
1728 
1729         ret = cli_lock(cli1, fnum1, 140, 4, 0, READ_LOCK) &&
1730               cli_lock(cli1, fnum1, 140, 4, 0, READ_LOCK) &&
1731               cli_unlock(cli1, fnum1, 140, 4) &&
1732               cli_unlock(cli1, fnum1, 140, 4);
1733         EXPECTED(ret, True);
1734         printf("this server %s do recursive read locking\n", ret?"does":"doesn't");
1735 
1736 
1737         ret = cli_lock(cli1, fnum1, 150, 4, 0, WRITE_LOCK) &&
1738               cli_lock(cli1, fnum1, 150, 4, 0, READ_LOCK) &&
1739               cli_unlock(cli1, fnum1, 150, 4) &&
1740               (cli_read(cli2, fnum2, buf, 150, 4) == 4) &&
1741               !(cli_write(cli2, fnum2, 0, buf, 150, 4) == 4) &&
1742               cli_unlock(cli1, fnum1, 150, 4);
1743         EXPECTED(ret, True);
1744         printf("this server %s do recursive lock overlays\n", ret?"does":"doesn't");
1745 
1746         ret = cli_lock(cli1, fnum1, 160, 4, 0, READ_LOCK) &&
1747               cli_unlock(cli1, fnum1, 160, 4) &&
1748               (cli_write(cli2, fnum2, 0, buf, 160, 4) == 4) &&          
1749               (cli_read(cli2, fnum2, buf, 160, 4) == 4);                
1750         EXPECTED(ret, True);
1751         printf("the same process %s remove a read lock using write locking\n", ret?"can":"cannot");
1752 
1753         ret = cli_lock(cli1, fnum1, 170, 4, 0, WRITE_LOCK) &&
1754               cli_unlock(cli1, fnum1, 170, 4) &&
1755               (cli_write(cli2, fnum2, 0, buf, 170, 4) == 4) &&          
1756               (cli_read(cli2, fnum2, buf, 170, 4) == 4);                
1757         EXPECTED(ret, True);
1758         printf("the same process %s remove a write lock using read locking\n", ret?"can":"cannot");
1759 
1760         ret = cli_lock(cli1, fnum1, 190, 4, 0, WRITE_LOCK) &&
1761               cli_lock(cli1, fnum1, 190, 4, 0, READ_LOCK) &&
1762               cli_unlock(cli1, fnum1, 190, 4) &&
1763               !(cli_write(cli2, fnum2, 0, buf, 190, 4) == 4) &&         
1764               (cli_read(cli2, fnum2, buf, 190, 4) == 4);                
1765         EXPECTED(ret, True);
1766         printf("the same process %s remove the first lock first\n", ret?"does":"doesn't");
1767 
1768         cli_close(cli1, fnum1);
1769         cli_close(cli2, fnum2);
1770         fnum1 = cli_open(cli1, fname, O_RDWR, DENY_NONE);
1771         f = cli_open(cli1, fname, O_RDWR, DENY_NONE);
1772         ret = cli_lock(cli1, fnum1, 0, 8, 0, READ_LOCK) &&
1773               cli_lock(cli1, f, 0, 1, 0, READ_LOCK) &&
1774               cli_close(cli1, fnum1) &&
1775               ((fnum1 = cli_open(cli1, fname, O_RDWR, DENY_NONE)) != -1) &&
1776               cli_lock(cli1, fnum1, 7, 1, 0, WRITE_LOCK);
1777         cli_close(cli1, f);
1778         cli_close(cli1, fnum1);
1779         EXPECTED(ret, True);
1780         printf("the server %s have the NT byte range lock bug\n", !ret?"does":"doesn't");
1781 
1782  fail:
1783         cli_close(cli1, fnum1);
1784         cli_close(cli2, fnum2);
1785         cli_unlink(cli1, fname);
1786         torture_close_connection(cli1);
1787         torture_close_connection(cli2);
1788 
1789         printf("finished locktest4\n");
1790         return correct;
1791 }
1792 
1793 /*
1794   looks at lock upgrade/downgrade.
1795 */
1796 static bool run_locktest5(int dummy)
     /* [<][>][^][v][top][bottom][index][help] */
1797 {
1798         static struct cli_state *cli1, *cli2;
1799         const char *fname = "\\lockt5.lck";
1800         int fnum1, fnum2, fnum3;
1801         bool ret;
1802         char buf[1000];
1803         bool correct = True;
1804 
1805         if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1806                 return False;
1807         }
1808 
1809         cli_sockopt(cli1, sockops);
1810         cli_sockopt(cli2, sockops);
1811 
1812         printf("starting locktest5\n");
1813 
1814         cli_unlink(cli1, fname);
1815 
1816         fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1817         fnum2 = cli_open(cli2, fname, O_RDWR, DENY_NONE);
1818         fnum3 = cli_open(cli1, fname, O_RDWR, DENY_NONE);
1819 
1820         memset(buf, 0, sizeof(buf));
1821 
1822         if (cli_write(cli1, fnum1, 0, buf, 0, sizeof(buf)) != sizeof(buf)) {
1823                 printf("Failed to create file\n");
1824                 correct = False;
1825                 goto fail;
1826         }
1827 
1828         /* Check for NT bug... */
1829         ret = cli_lock(cli1, fnum1, 0, 8, 0, READ_LOCK) &&
1830                   cli_lock(cli1, fnum3, 0, 1, 0, READ_LOCK);
1831         cli_close(cli1, fnum1);
1832         fnum1 = cli_open(cli1, fname, O_RDWR, DENY_NONE);
1833         ret = cli_lock(cli1, fnum1, 7, 1, 0, WRITE_LOCK);
1834         EXPECTED(ret, True);
1835         printf("this server %s the NT locking bug\n", ret ? "doesn't have" : "has");
1836         cli_close(cli1, fnum1);
1837         fnum1 = cli_open(cli1, fname, O_RDWR, DENY_NONE);
1838         cli_unlock(cli1, fnum3, 0, 1);
1839 
1840         ret = cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK) &&
1841               cli_lock(cli1, fnum1, 1, 1, 0, READ_LOCK);
1842         EXPECTED(ret, True);
1843         printf("the same process %s overlay a write with a read lock\n", ret?"can":"cannot");
1844 
1845         ret = cli_lock(cli2, fnum2, 0, 4, 0, READ_LOCK);
1846         EXPECTED(ret, False);
1847 
1848         printf("a different processs %s get a read lock on the first process lock stack\n", ret?"can":"cannot");
1849 
1850         /* Unlock the process 2 lock. */
1851         cli_unlock(cli2, fnum2, 0, 4);
1852 
1853         ret = cli_lock(cli1, fnum3, 0, 4, 0, READ_LOCK);
1854         EXPECTED(ret, False);
1855 
1856         printf("the same processs on a different fnum %s get a read lock\n", ret?"can":"cannot");
1857 
1858         /* Unlock the process 1 fnum3 lock. */
1859         cli_unlock(cli1, fnum3, 0, 4);
1860 
1861         /* Stack 2 more locks here. */
1862         ret = cli_lock(cli1, fnum1, 0, 4, 0, READ_LOCK) &&
1863                   cli_lock(cli1, fnum1, 0, 4, 0, READ_LOCK);
1864 
1865         EXPECTED(ret, True);
1866         printf("the same process %s stack read locks\n", ret?"can":"cannot");
1867 
1868         /* Unlock the first process lock, then check this was the WRITE lock that was
1869                 removed. */
1870 
1871         ret = cli_unlock(cli1, fnum1, 0, 4) &&
1872                         cli_lock(cli2, fnum2, 0, 4, 0, READ_LOCK);
1873 
1874         EXPECTED(ret, True);
1875         printf("the first unlock removes the %s lock\n", ret?"WRITE":"READ");
1876 
1877         /* Unlock the process 2 lock. */
1878         cli_unlock(cli2, fnum2, 0, 4);
1879 
1880         /* We should have 3 stacked locks here. Ensure we need to do 3 unlocks. */
1881 
1882         ret = cli_unlock(cli1, fnum1, 1, 1) &&
1883                   cli_unlock(cli1, fnum1, 0, 4) &&
1884                   cli_unlock(cli1, fnum1, 0, 4);
1885 
1886         EXPECTED(ret, True);
1887         printf("the same process %s unlock the stack of 4 locks\n", ret?"can":"cannot"); 
1888 
1889         /* Ensure the next unlock fails. */
1890         ret = cli_unlock(cli1, fnum1, 0, 4);
1891         EXPECTED(ret, False);
1892         printf("the same process %s count the lock stack\n", !ret?"can":"cannot"); 
1893 
1894         /* Ensure connection 2 can get a write lock. */
1895         ret = cli_lock(cli2, fnum2, 0, 4, 0, WRITE_LOCK);
1896         EXPECTED(ret, True);
1897 
1898         printf("a different processs %s get a write lock on the unlocked stack\n", ret?"can":"cannot");
1899 
1900 
1901  fail:
1902         cli_close(cli1, fnum1);
1903         cli_close(cli2, fnum2);
1904         cli_unlink(cli1, fname);
1905         if (!torture_close_connection(cli1)) {
1906                 correct = False;
1907         }
1908         if (!torture_close_connection(cli2)) {
1909                 correct = False;
1910         }
1911 
1912         printf("finished locktest5\n");
1913        
1914         return correct;
1915 }
1916 
1917 /*
1918   tries the unusual lockingX locktype bits
1919 */
1920 static bool run_locktest6(int dummy)
     /* [<][>][^][v][top][bottom][index][help] */
1921 {
1922         static struct cli_state *cli;
1923         const char *fname[1] = { "\\lock6.txt" };
1924         int i;
1925         int fnum;
1926         NTSTATUS status;
1927 
1928         if (!torture_open_connection(&cli, 0)) {
1929                 return False;
1930         }
1931 
1932         cli_sockopt(cli, sockops);
1933 
1934         printf("starting locktest6\n");
1935 
1936         for (i=0;i<1;i++) {
1937                 printf("Testing %s\n", fname[i]);
1938 
1939                 cli_unlink(cli, fname[i]);
1940 
1941                 fnum = cli_open(cli, fname[i], O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1942                 status = cli_locktype(cli, fnum, 0, 8, 0, LOCKING_ANDX_CHANGE_LOCKTYPE);
1943                 cli_close(cli, fnum);
1944                 printf("CHANGE_LOCKTYPE gave %s\n", nt_errstr(status));
1945 
1946                 fnum = cli_open(cli, fname[i], O_RDWR, DENY_NONE);
1947                 status = cli_locktype(cli, fnum, 0, 8, 0, LOCKING_ANDX_CANCEL_LOCK);
1948                 cli_close(cli, fnum);
1949                 printf("CANCEL_LOCK gave %s\n", nt_errstr(status));
1950 
1951                 cli_unlink(cli, fname[i]);
1952         }
1953 
1954         torture_close_connection(cli);
1955 
1956         printf("finished locktest6\n");
1957         return True;
1958 }
1959 
1960 static bool run_locktest7(int dummy)
     /* [<][>][^][v][top][bottom][index][help] */
1961 {
1962         struct cli_state *cli1;
1963         const char *fname = "\\lockt7.lck";
1964         int fnum1;
1965         char buf[200];
1966         bool correct = False;
1967 
1968         if (!torture_open_connection(&cli1, 0)) {
1969                 return False;
1970         }
1971 
1972         cli_sockopt(cli1, sockops);
1973 
1974         printf("starting locktest7\n");
1975 
1976         cli_unlink(cli1, fname);
1977 
1978         fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1979 
1980         memset(buf, 0, sizeof(buf));
1981 
1982         if (cli_write(cli1, fnum1, 0, buf, 0, sizeof(buf)) != sizeof(buf)) {
1983                 printf("Failed to create file\n");
1984                 goto fail;
1985         }
1986 
1987         cli_setpid(cli1, 1);
1988 
1989         if (!cli_lock(cli1, fnum1, 130, 4, 0, READ_LOCK)) {
1990                 printf("Unable to apply read lock on range 130:4, error was %s\n", cli_errstr(cli1));
1991                 goto fail;
1992         } else {
1993                 printf("pid1 successfully locked range 130:4 for READ\n");
1994         }
1995 
1996         if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
1997                 printf("pid1 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
1998                 goto fail;
1999         } else {
2000                 printf("pid1 successfully read the range 130:4\n");
2001         }
2002 
2003         if (cli_write(cli1, fnum1, 0, buf, 130, 4) != 4) {
2004                 printf("pid1 unable to write to the range 130:4, error was %s\n", cli_errstr(cli1));
2005                 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
2006                         printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2007                         goto fail;
2008                 }
2009         } else {
2010                 printf("pid1 successfully wrote to the range 130:4 (should be denied)\n");
2011                 goto fail;
2012         }
2013 
2014         cli_setpid(cli1, 2);
2015 
2016         if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
2017                 printf("pid2 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
2018         } else {
2019                 printf("pid2 successfully read the range 130:4\n");
2020         }
2021 
2022         if (cli_write(cli1, fnum1, 0, buf, 130, 4) != 4) {
2023                 printf("pid2 unable to write to the range 130:4, error was %s\n", cli_errstr(cli1));
2024                 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
2025                         printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2026                         goto fail;
2027                 }
2028         } else {
2029                 printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
2030                 goto fail;
2031         }
2032 
2033         cli_setpid(cli1, 1);
2034         cli_unlock(cli1, fnum1, 130, 4);
2035 
2036         if (!cli_lock(cli1, fnum1, 130, 4, 0, WRITE_LOCK)) {
2037                 printf("Unable to apply write lock on range 130:4, error was %s\n", cli_errstr(cli1));
2038                 goto fail;
2039         } else {
2040                 printf("pid1 successfully locked range 130:4 for WRITE\n");
2041         }
2042 
2043         if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
2044                 printf("pid1 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
2045                 goto fail;
2046         } else {
2047                 printf("pid1 successfully read the range 130:4\n");
2048         }
2049 
2050         if (cli_write(cli1, fnum1, 0, buf, 130, 4) != 4) {
2051                 printf("pid1 unable to write to the range 130:4, error was %s\n", cli_errstr(cli1));
2052                 goto fail;
2053         } else {
2054                 printf("pid1 successfully wrote to the range 130:4\n");
2055         }
2056 
2057         cli_setpid(cli1, 2);
2058 
2059         if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
2060                 printf("pid2 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
2061                 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
2062                         printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2063                         goto fail;
2064                 }
2065         } else {
2066                 printf("pid2 successfully read the range 130:4 (should be denied)\n");
2067                 goto fail;
2068         }
2069 
2070         if (cli_write(cli1, fnum1, 0, buf, 130, 4) != 4) {
2071                 printf("pid2 unable to write to the range 130:4, error was %s\n", cli_errstr(cli1));
2072                 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
2073                         printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2074                         goto fail;
2075                 }
2076         } else {
2077                 printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
2078                 goto fail;
2079         }
2080 
2081         cli_unlock(cli1, fnum1, 130, 0);
2082         correct = True;
2083 
2084 fail:
2085         cli_close(cli1, fnum1);
2086         cli_unlink(cli1, fname);
2087         torture_close_connection(cli1);
2088 
2089         printf("finished locktest7\n");
2090         return correct;
2091 }
2092 
2093 /*
2094 test whether fnums and tids open on one VC are available on another (a major
2095 security hole)
2096 */
2097 static bool run_fdpasstest(int dummy)
     /* [<][>][^][v][top][bottom][index][help] */
2098 {
2099         struct cli_state *cli1, *cli2;
2100         const char *fname = "\\fdpass.tst";
2101         int fnum1;
2102         char buf[1024];
2103 
2104         if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
2105                 return False;
2106         }
2107         cli_sockopt(cli1, sockops);
2108         cli_sockopt(cli2, sockops);
2109 
2110         printf("starting fdpasstest\n");
2111 
2112         cli_unlink(cli1, fname);
2113 
2114         fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
2115         if (fnum1 == -1) {
2116                 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
2117                 return False;
2118         }
2119 
2120         if (cli_write(cli1, fnum1, 0, "hello world\n", 0, 13) != 13) {
2121                 printf("write failed (%s)\n", cli_errstr(cli1));
2122                 return False;
2123         }
2124 
2125         cli2->vuid = cli1->vuid;
2126         cli2->cnum = cli1->cnum;
2127         cli2->pid = cli1->pid;
2128 
2129         if (cli_read(cli2, fnum1, buf, 0, 13) == 13) {
2130                 printf("read succeeded! nasty security hole [%s]\n",
2131                        buf);
2132                 return False;
2133         }
2134 
2135         cli_close(cli1, fnum1);
2136         cli_unlink(cli1, fname);
2137 
2138         torture_close_connection(cli1);
2139         torture_close_connection(cli2);
2140 
2141         printf("finished fdpasstest\n");
2142         return True;
2143 }
2144 
2145 static bool run_fdsesstest(int dummy)
     /* [<][>][^][v][top][bottom][index][help] */
2146 {
2147         struct cli_state *cli;
2148         uint16 new_vuid;
2149         uint16 saved_vuid;
2150         uint16 new_cnum;
2151         uint16 saved_cnum;
2152         const char *fname = "\\fdsess.tst";
2153         const char *fname1 = "\\fdsess1.tst";
2154         int fnum1;
2155         int fnum2;
2156         char buf[1024];
2157         bool ret = True;
2158 
2159         if (!torture_open_connection(&cli, 0))
2160                 return False;
2161         cli_sockopt(cli, sockops);
2162 
2163         if (!torture_cli_session_setup2(cli, &new_vuid))
2164                 return False;
2165 
2166         saved_cnum = cli->cnum;
2167         if (!NT_STATUS_IS_OK(cli_tcon_andx(cli, share, "?????", "", 1)))
2168                 return False;
2169         new_cnum = cli->cnum;
2170         cli->cnum = saved_cnum;
2171 
2172         printf("starting fdsesstest\n");
2173 
2174         cli_unlink(cli, fname);
2175         cli_unlink(cli, fname1);
2176 
2177         fnum1 = cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
2178         if (fnum1 == -1) {
2179                 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
2180                 return False;
2181         }
2182 
2183         if (cli_write(cli, fnum1, 0, "hello world\n", 0, 13) != 13) {
2184                 printf("write failed (%s)\n", cli_errstr(cli));
2185                 return False;
2186         }
2187 
2188         saved_vuid = cli->vuid;
2189         cli->vuid = new_vuid;
2190 
2191         if (cli_read(cli, fnum1, buf, 0, 13) == 13) {
2192                 printf("read succeeded with different vuid! nasty security hole [%s]\n",
2193                        buf);
2194                 ret = False;
2195         }
2196         /* Try to open a file with different vuid, samba cnum. */
2197         fnum2 = cli_open(cli, fname1, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
2198         if (fnum2 != -1) {
2199                 printf("create with different vuid, same cnum succeeded.\n");
2200                 cli_close(cli, fnum2);
2201                 cli_unlink(cli, fname1);
2202         } else {
2203                 printf("create with different vuid, same cnum failed.\n");
2204                 printf("This will cause problems with service clients.\n");
2205                 ret = False;
2206         }
2207 
2208         cli->vuid = saved_vuid;
2209 
2210         /* Try with same vuid, different cnum. */
2211         cli->cnum = new_cnum;
2212 
2213         if (cli_read(cli, fnum1, buf, 0, 13) == 13) {
2214                 printf("read succeeded with different cnum![%s]\n",
2215                        buf);
2216                 ret = False;
2217         }
2218 
2219         cli->cnum = saved_cnum;
2220         cli_close(cli, fnum1);
2221         cli_unlink(cli, fname);
2222 
2223         torture_close_connection(cli);
2224 
2225         printf("finished fdsesstest\n");
2226         return ret;
2227 }
2228 
2229 /*
2230   This test checks that 
2231 
2232   1) the server does not allow an unlink on a file that is open
2233 */
2234 static bool run_unlinktest(int dummy)
     /* [<][>][^][v][top][bottom][index][help] */
2235 {
2236         struct cli_state *cli;
2237         const char *fname = "\\unlink.tst";
2238         int fnum;
2239         bool correct = True;
2240 
2241         if (!torture_open_connection(&cli, 0)) {
2242                 return False;
2243         }
2244 
2245         cli_sockopt(cli, sockops);
2246 
2247         printf("starting unlink test\n");
2248 
2249         cli_unlink(cli, fname);
2250 
2251         cli_setpid(cli, 1);
2252 
2253         fnum = cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
2254         if (fnum == -1) {
2255                 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
2256                 return False;
2257         }
2258 
2259         if (cli_unlink(cli, fname)) {
2260                 printf("error: server allowed unlink on an open file\n");
2261                 correct = False;
2262         } else {
2263                 correct = check_error(__LINE__, cli, ERRDOS, ERRbadshare, 
2264                                       NT_STATUS_SHARING_VIOLATION);
2265         }
2266 
2267         cli_close(cli, fnum);
2268         cli_unlink(cli, fname);
2269 
2270         if (!torture_close_connection(cli)) {
2271                 correct = False;
2272         }
2273 
2274         printf("unlink test finished\n");
2275         
2276         return correct;
2277 }
2278 
2279 
2280 /*
2281 test how many open files this server supports on the one socket
2282 */
2283 static bool run_maxfidtest(int dummy)
     /* [<][>][^][v][top][bottom][index][help] */
2284 {
2285         struct cli_state *cli;
2286         const char *ftemplate = "\\maxfid.%d.%d";
2287         fstring fname;
2288         int fnums[0x11000], i;
2289         int retries=4;
2290         bool correct = True;
2291 
2292         cli = current_cli;
2293 
2294         if (retries <= 0) {
2295                 printf("failed to connect\n");
2296                 return False;
2297         }
2298 
2299         cli_sockopt(cli, sockops);
2300 
2301         for (i=0; i<0x11000; i++) {
2302                 slprintf(fname,sizeof(fname)-1,ftemplate, i,(int)getpid());
2303                 if ((fnums[i] = cli_open(cli, fname, 
2304                                         O_RDWR|O_CREAT|O_TRUNC, DENY_NONE)) ==
2305                     -1) {
2306                         printf("open of %s failed (%s)\n", 
2307                                fname, cli_errstr(cli));
2308                         printf("maximum fnum is %d\n", i);
2309                         break;
2310                 }
2311                 printf("%6d\r", i);
2312         }
2313         printf("%6d\n", i);
2314         i--;
2315 
2316         printf("cleaning up\n");
2317         for (;i>=0;i--) {
2318                 slprintf(fname,sizeof(fname)-1,ftemplate, i,(int)getpid());
2319                 cli_close(cli, fnums[i]);
2320                 if (!cli_unlink(cli, fname)) {
2321                         printf("unlink of %s failed (%s)\n", 
2322                                fname, cli_errstr(cli));
2323                         correct = False;
2324                 }
2325                 printf("%6d\r", i);
2326         }
2327         printf("%6d\n", 0);
2328 
2329         printf("maxfid test finished\n");
2330         if (!torture_close_connection(cli)) {
2331                 correct = False;
2332         }
2333         return correct;
2334 }
2335 
2336 /* generate a random buffer */
2337 static void rand_buf(char *buf, int len)
     /* [<][>][^][v][top][bottom][index][help] */
2338 {
2339         while (len--) {
2340                 *buf = (char)sys_random();
2341                 buf++;
2342         }
2343 }
2344 
2345 /* send smb negprot commands, not reading the response */
2346 static bool run_negprot_nowait(int dummy)
     /* [<][>][^][v][top][bottom][index][help] */
2347 {
2348         int i;
2349         static struct cli_state *cli;
2350         bool correct = True;
2351 
2352         printf("starting negprot nowait test\n");
2353 
2354         if (!(cli = open_nbt_connection())) {
2355                 return False;
2356         }
2357 
2358         for (i=0;i<50000;i++) {
2359                 cli_negprot_sendsync(cli);
2360         }
2361 
2362         if (!torture_close_connection(cli)) {
2363                 correct = False;
2364         }
2365 
2366         printf("finished negprot nowait test\n");
2367 
2368         return correct;
2369 }
2370 
2371 
2372 /* send random IPC commands */
2373 static bool run_randomipc(int dummy)
     /* [<][>][^][v][top][bottom][index][help] */
2374 {
2375         char *rparam = NULL;
2376         char *rdata = NULL;
2377         unsigned int rdrcnt,rprcnt;
2378         char param[1024];
2379         int api, param_len, i;
2380         struct cli_state *cli;
2381         bool correct = True;
2382         int count = 50000;
2383 
2384         printf("starting random ipc test\n");
2385 
2386         if (!torture_open_connection(&cli, 0)) {
2387                 return False;
2388         }
2389 
2390         for (i=0;i<count;i++) {
2391                 api = sys_random() % 500;
2392                 param_len = (sys_random() % 64);
2393 
2394                 rand_buf(param, param_len);
2395   
2396                 SSVAL(param,0,api); 
2397 
2398                 cli_api(cli, 
2399                         param, param_len, 8,  
2400                         NULL, 0, BUFFER_SIZE, 
2401                         &rparam, &rprcnt,     
2402                         &rdata, &rdrcnt);
2403                 if (i % 100 == 0) {
2404                         printf("%d/%d\r", i,count);
2405                 }
2406         }
2407         printf("%d/%d\n", i, count);
2408 
2409         if (!torture_close_connection(cli)) {
2410                 correct = False;
2411         }
2412 
2413         printf("finished random ipc test\n");
2414 
2415         return correct;
2416 }
2417 
2418 
2419 
2420 static void browse_callback(const char *sname, uint32 stype, 
     /* [<][>][^][v][top][bottom][index][help] */
2421                             const char *comment, void *state)
2422 {
2423         printf("\t%20.20s %08x %s\n", sname, stype, comment);
2424 }
2425 
2426 
2427 
2428 /*
2429   This test checks the browse list code
2430 
2431 */
2432 static bool run_browsetest(int dummy)
     /* [<][>][^][v][top][bottom][index][help] */
2433 {
2434         static struct cli_state *cli;
2435         bool correct = True;
2436 
2437         printf("starting browse test\n");
2438 
2439         if (!torture_open_connection(&cli, 0)) {
2440                 return False;
2441         }
2442 
2443         printf("domain list:\n");
2444         cli_NetServerEnum(cli, cli->server_domain, 
2445                           SV_TYPE_DOMAIN_ENUM,
2446                           browse_callback, NULL);
2447 
2448         printf("machine list:\n");
2449         cli_NetServerEnum(cli, cli->server_domain, 
2450                           SV_TYPE_ALL,
2451                           browse_callback, NULL);
2452 
2453         if (!torture_close_connection(cli)) {
2454                 correct = False;
2455         }
2456 
2457         printf("browse test finished\n");
2458 
2459         return correct;
2460 
2461 }
2462 
2463 
2464 /*
2465   This checks how the getatr calls works
2466 */
2467 static bool run_attrtest(int dummy)
     /* [<][>][^][v][top][bottom][index][help] */
2468 {
2469         struct cli_state *cli;
2470         int fnum;
2471         time_t t, t2;
2472         const char *fname = "\\attrib123456789.tst";
2473         bool correct = True;
2474 
2475         printf("starting attrib test\n");
2476 
2477         if (!torture_open_connection(&cli, 0)) {
2478                 return False;
2479         }
2480 
2481         cli_unlink(cli, fname);
2482         fnum = cli_open(cli, fname, 
2483                         O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
2484         cli_close(cli, fnum);
2485         if (!cli_getatr(cli, fname, NULL, NULL, &t)) {
2486                 printf("getatr failed (%s)\n", cli_errstr(cli));
2487                 correct = False;
2488         }
2489 
2490         if (abs(t - time(NULL)) > 60*60*24*10) {
2491                 printf("ERROR: SMBgetatr bug. time is %s",
2492                        ctime(&t));
2493                 t = time(NULL);
2494                 correct = True;
2495         }
2496 
2497         t2 = t-60*60*24; /* 1 day ago */
2498 
2499         if (!cli_setatr(cli, fname, 0, t2)) {
2500                 printf("setatr failed (%s)\n", cli_errstr(cli));
2501                 correct = True;
2502         }
2503 
2504         if (!cli_getatr(cli, fname, NULL, NULL, &t)) {
2505                 printf("getatr failed (%s)\n", cli_errstr(cli));
2506                 correct = True;
2507         }
2508 
2509         if (t != t2) {
2510                 printf("ERROR: getatr/setatr bug. times are\n%s",
2511                        ctime(&t));
2512                 printf("%s", ctime(&t2));
2513                 correct = True;
2514         }
2515 
2516         cli_unlink(cli, fname);
2517 
2518         if (!torture_close_connection(cli)) {
2519                 correct = False;
2520         }
2521 
2522         printf("attrib test finished\n");
2523 
2524         return correct;
2525 }
2526 
2527 
2528 /*
2529   This checks a couple of trans2 calls
2530 */
2531 static bool run_trans2test(int dummy)
     /* [<][>][^][v][top][bottom][index][help] */
2532 {
2533         struct cli_state *cli;
2534         int fnum;
2535         SMB_OFF_T size;
2536         time_t c_time, a_time, m_time;
2537         struct timespec c_time_ts, a_time_ts, m_time_ts, w_time_ts, m_time2_ts;
2538         const char *fname = "\\trans2.tst";
2539         const char *dname = "\\trans2";
2540         const char *fname2 = "\\trans2\\trans2.tst";
2541         char pname[1024];
2542         bool correct = True;
2543 
2544         printf("starting trans2 test\n");
2545 
2546         if (!torture_open_connection(&cli, 0)) {
2547                 return False;
2548         }
2549 
2550         cli_unlink(cli, fname);
2551         fnum = cli_open(cli, fname, 
2552                         O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
2553         if (!cli_qfileinfo(cli, fnum, NULL, &size, &c_time_ts, &a_time_ts, &w_time_ts,
2554                            &m_time_ts, NULL)) {
2555                 printf("ERROR: qfileinfo failed (%s)\n", cli_errstr(cli));
2556                 correct = False;
2557         }
2558 
2559         if (!cli_qfilename(cli, fnum, pname, sizeof(pname))) {
2560                 printf("ERROR: qfilename failed (%s)\n", cli_errstr(cli));
2561                 correct = False;
2562         }
2563 
2564         if (strcmp(pname, fname)) {
2565                 printf("qfilename gave different name? [%s] [%s]\n",
2566                        fname, pname);
2567                 correct = False;
2568         }
2569 
2570         cli_close(cli, fnum);
2571 
2572         sleep(2);
2573 
2574         cli_unlink(cli, fname);
2575         fnum = cli_open(cli, fname, 
2576                         O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
2577         if (fnum == -1) {
2578                 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
2579                 return False;
2580         }
2581         cli_close(cli, fnum);
2582 
2583         if (!cli_qpathinfo(cli, fname, &c_time, &a_time, &m_time, &size, NULL)) {
2584                 printf("ERROR: qpathinfo failed (%s)\n", cli_errstr(cli));
2585                 correct = False;
2586         } else {
2587                 if (c_time != m_time) {
2588                         printf("create time=%s", ctime(&c_time));
2589                         printf("modify time=%s", ctime(&m_time));
2590                         printf("This system appears to have sticky create times\n");
2591                 }
2592                 if (a_time % (60*60) == 0) {
2593                         printf("access time=%s", ctime(&a_time));
2594                         printf("This system appears to set a midnight access time\n");
2595                         correct = False;
2596                 }
2597 
2598                 if (abs(m_time - time(NULL)) > 60*60*24*7) {
2599                         printf("ERROR: totally incorrect times - maybe word reversed? mtime=%s", ctime(&m_time));
2600                         correct = False;
2601                 }
2602         }
2603 
2604 
2605         cli_unlink(cli, fname);
2606         fnum = cli_open(cli, fname, 
2607                         O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
2608         cli_close(cli, fnum);
2609         if (!cli_qpathinfo2(cli, fname, &c_time_ts, &a_time_ts, &w_time_ts, 
2610                             &m_time_ts, &size, NULL, NULL)) {
2611                 printf("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(cli));
2612                 correct = False;
2613         } else {
2614                 if (w_time_ts.tv_sec < 60*60*24*2) {
2615                         printf("write time=%s", ctime(&w_time_ts.tv_sec));
2616                         printf("This system appears to set a initial 0 write time\n");
2617                         correct = False;
2618                 }
2619         }
2620 
2621         cli_unlink(cli, fname);
2622 
2623 
2624         /* check if the server updates the directory modification time
2625            when creating a new file */
2626         if (!cli_mkdir(cli, dname)) {
2627                 printf("ERROR: mkdir failed (%s)\n", cli_errstr(cli));
2628                 correct = False;
2629         }
2630         sleep(3);
2631         if (!cli_qpathinfo2(cli, "\\trans2\\", &c_time_ts, &a_time_ts, &w_time_ts, 
2632                             &m_time_ts, &size, NULL, NULL)) {
2633                 printf("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(cli));
2634                 correct = False;
2635         }
2636 
2637         fnum = cli_open(cli, fname2, 
2638                         O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
2639         cli_write(cli, fnum,  0, (char *)&fnum, 0, sizeof(fnum));
2640         cli_close(cli, fnum);
2641         if (!cli_qpathinfo2(cli, "\\trans2\\", &c_time_ts, &a_time_ts, &w_time_ts, 
2642                             &m_time2_ts, &size, NULL, NULL)) {
2643                 printf("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(cli));
2644                 correct = False;
2645         } else {
2646                 if (memcmp(&m_time_ts, &m_time2_ts, sizeof(struct timespec))
2647                     == 0) {
2648                         printf("This system does not update directory modification times\n");
2649                         correct = False;
2650                 }
2651         }
2652         cli_unlink(cli, fname2);
2653         cli_rmdir(cli, dname);
2654 
2655         if (!torture_close_connection(cli)) {
2656                 correct = False;
2657         }
2658 
2659         printf("trans2 test finished\n");
2660 
2661         return correct;
2662 }
2663 
2664 /*
2665   This checks new W2K calls.
2666 */
2667 
2668 static bool new_trans(struct cli_state *pcli, int fnum, int level)
     /* [<][>][^][v][top][bottom][index][help] */
2669 {
2670         char *buf = NULL;
2671         uint32 len;
2672         bool correct = True;
2673 
2674         if (!cli_qfileinfo_test(pcli, fnum, level, &buf, &len)) {
2675                 printf("ERROR: qfileinfo (%d) failed (%s)\n", level, cli_errstr(pcli));
2676                 correct = False;
2677         } else {
2678                 printf("qfileinfo: level %d, len = %u\n", level, len);
2679                 dump_data(0, (uint8 *)buf, len);
2680                 printf("\n");
2681         }
2682         SAFE_FREE(buf);
2683         return correct;
2684 }
2685 
2686 static bool run_w2ktest(int dummy)
     /* [<][>][^][v][top][bottom][index][help] */
2687 {
2688         struct cli_state *cli;
2689         int fnum;
2690         const char *fname = "\\w2ktest\\w2k.tst";
2691         int level;
2692         bool correct = True;
2693 
2694         printf("starting w2k test\n");
2695 
2696         if (!torture_open_connection(&cli, 0)) {
2697                 return False;
2698         }
2699 
2700         fnum = cli_open(cli, fname, 
2701                         O_RDWR | O_CREAT , DENY_NONE);
2702 
2703         for (level = 1004; level < 1040; level++) {
2704                 new_trans(cli, fnum, level);
2705         }
2706 
2707         cli_close(cli, fnum);
2708 
2709         if (!torture_close_connection(cli)) {
2710                 correct = False;
2711         }
2712 
2713         printf("w2k test finished\n");
2714         
2715         return correct;
2716 }
2717 
2718 
2719 /*
2720   this is a harness for some oplock tests
2721  */
2722 static bool run_oplock1(int dummy)
     /* [<][>][^][v][top][bottom][index][help] */
2723 {
2724         struct cli_state *cli1;
2725         const char *fname = "\\lockt1.lck";
2726         int fnum1;
2727         bool correct = True;
2728 
2729         printf("starting oplock test 1\n");
2730 
2731         if (!torture_open_connection(&cli1, 0)) {
2732                 return False;
2733         }
2734 
2735         cli_unlink(cli1, fname);
2736 
2737         cli_sockopt(cli1, sockops);
2738 
2739         cli1->use_oplocks = True;
2740 
2741         fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
2742         if (fnum1 == -1) {
2743                 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
2744                 return False;
2745         }
2746 
2747         cli1->use_oplocks = False;
2748 
2749         cli_unlink(cli1, fname);
2750         cli_unlink(cli1, fname);
2751 
2752         if (!cli_close(cli1, fnum1)) {
2753                 printf("close2 failed (%s)\n", cli_errstr(cli1));
2754                 return False;
2755         }
2756 
2757         if (!cli_unlink(cli1, fname)) {
2758                 printf("unlink failed (%s)\n", cli_errstr(cli1));
2759                 return False;
2760         }
2761 
2762         if (!torture_close_connection(cli1)) {
2763                 correct = False;
2764         }
2765 
2766         printf("finished oplock test 1\n");
2767 
2768         return correct;
2769 }
2770 
2771 static bool run_oplock2(int dummy)
     /* [<][>][^][v][top][bottom][index][help] */
2772 {
2773         struct cli_state *cli1, *cli2;
2774         const char *fname = "\\lockt2.lck";
2775         int fnum1, fnum2;
2776         int saved_use_oplocks = use_oplocks;
2777         char buf[4];
2778         bool correct = True;
2779         volatile bool *shared_correct;
2780 
2781         shared_correct = (volatile bool *)shm_setup(sizeof(bool));
2782         *shared_correct = True;
2783 
2784         use_level_II_oplocks = True;
2785         use_oplocks = True;
2786 
2787         printf("starting oplock test 2\n");
2788 
2789         if (!torture_open_connection(&cli1, 0)) {
2790                 use_level_II_oplocks = False;
2791                 use_oplocks = saved_use_oplocks;
2792                 return False;
2793         }
2794 
2795         cli1->use_oplocks = True;
2796         cli1->use_level_II_oplocks = True;
2797 
2798         if (!torture_open_connection(&cli2, 1)) {
2799                 use_level_II_oplocks = False;
2800                 use_oplocks = saved_use_oplocks;
2801                 return False;
2802         }
2803 
2804         cli2->use_oplocks = True;
2805         cli2->use_level_II_oplocks = True;
2806 
2807         cli_unlink(cli1, fname);
2808 
2809         cli_sockopt(cli1, sockops);
2810         cli_sockopt(cli2, sockops);
2811 
2812         fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
2813         if (fnum1 == -1) {
2814                 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
2815                 return False;
2816         }
2817 
2818         /* Don't need the globals any more. */
2819         use_level_II_oplocks = False;
2820         use_oplocks = saved_use_oplocks;
2821 
2822         if (fork() == 0) {
2823                 /* Child code */
2824                 fnum2 = cli_open(cli2, fname, O_RDWR, DENY_NONE);
2825                 if (fnum2 == -1) {
2826                         printf("second open of %s failed (%s)\n", fname, cli_errstr(cli1));
2827                         *shared_correct = False;
2828                         exit(0);
2829                 }
2830 
2831                 sleep(2);
2832 
2833                 if (!cli_close(cli2, fnum2)) {
2834                         printf("close2 failed (%s)\n", cli_errstr(cli1));
2835                         *shared_correct = False;
2836                 }
2837 
2838                 exit(0);
2839         }
2840 
2841         sleep(2);
2842 
2843         /* Ensure cli1 processes the break. Empty file should always return 0
2844          * bytes.  */
2845 
2846         if (cli_read(cli1, fnum1, buf, 0, 4) != 0) {
2847                 printf("read on fnum1 failed (%s)\n", cli_errstr(cli1));
2848                 correct = False;
2849         }
2850 
2851         /* Should now be at level II. */
2852         /* Test if sending a write locks causes a break to none. */
2853 
2854         if (!cli_lock(cli1, fnum1, 0, 4, 0, READ_LOCK)) {
2855                 printf("lock failed (%s)\n", cli_errstr(cli1));
2856                 correct = False;
2857         }
2858 
2859         cli_unlock(cli1, fnum1, 0, 4);
2860 
2861         sleep(2);
2862 
2863         if (!cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK)) {
2864                 printf("lock failed (%s)\n", cli_errstr(cli1));
2865                 correct = False;
2866         }
2867 
2868         cli_unlock(cli1, fnum1, 0, 4);
2869 
2870         sleep(2);
2871 
2872         cli_read(cli1, fnum1, buf, 0, 4);
2873 
2874 #if 0
2875         if (cli_write(cli1, fnum1, 0, buf, 0, 4) != 4) {
2876                 printf("write on fnum1 failed (%s)\n", cli_errstr(cli1));
2877                 correct = False;
2878         }
2879 #endif
2880 
2881         if (!cli_close(cli1, fnum1)) {
2882                 printf("close1 failed (%s)\n", cli_errstr(cli1));
2883                 correct = False;
2884         }
2885 
2886         sleep(4);
2887 
2888         if (!cli_unlink(cli1, fname)) {
2889                 printf("unlink failed (%s)\n", cli_errstr(cli1));
2890                 correct = False;
2891         }
2892 
2893         if (!torture_close_connection(cli1)) {
2894                 correct = False;
2895         }
2896 
2897         if (!*shared_correct) {
2898                 correct = False;
2899         }
2900 
2901         printf("finished oplock test 2\n");
2902 
2903         return correct;
2904 }
2905 
2906 /* handler for oplock 3 tests */
2907 static bool oplock3_handler(struct cli_state *cli, int fnum, unsigned char level)
     /* [<][>][^][v][top][bottom][index][help] */
2908 {
2909         printf("got oplock break fnum=%d level=%d\n",
2910                fnum, level);
2911         return cli_oplock_ack(cli, fnum, level);
2912 }
2913 
2914 static bool run_oplock3(int dummy)
     /* [<][>][^][v][top][bottom][index][help] */
2915 {
2916         struct cli_state *cli;
2917         const char *fname = "\\oplockt3.dat";
2918         int fnum;
2919         char buf[4] = "abcd";
2920         bool correct = True;
2921         volatile bool *shared_correct;
2922 
2923         shared_correct = (volatile bool *)shm_setup(sizeof(bool));
2924         *shared_correct = True;
2925 
2926         printf("starting oplock test 3\n");
2927 
2928         if (fork() == 0) {
2929                 /* Child code */
2930                 use_oplocks = True;
2931                 use_level_II_oplocks = True;
2932                 if (!torture_open_connection(&cli, 0)) {
2933                         *shared_correct = False;
2934                         exit(0);
2935                 } 
2936                 sleep(2);
2937                 /* try to trigger a oplock break in parent */
2938                 fnum = cli_open(cli, fname, O_RDWR, DENY_NONE);
2939                 cli_write(cli, fnum, 0, buf, 0, 4);
2940                 exit(0);
2941         }
2942 
2943         /* parent code */
2944         use_oplocks = True;
2945         use_level_II_oplocks = True;
2946         if (!torture_open_connection(&cli, 1)) { /* other is forked */
2947                 return False;
2948         }
2949         cli_oplock_handler(cli, oplock3_handler);
2950         fnum = cli_open(cli, fname, O_RDWR|O_CREAT, DENY_NONE);
2951         cli_write(cli, fnum, 0, buf, 0, 4);
2952         cli_close(cli, fnum);
2953         fnum = cli_open(cli, fname, O_RDWR, DENY_NONE);
2954         cli->timeout = 20000;
2955         cli_receive_smb(cli);
2956         printf("finished oplock test 3\n");
2957 
2958         return (correct && *shared_correct);
2959 
2960 /* What are we looking for here?  What's sucess and what's FAILURE? */
2961 }
2962 
2963 
2964 
2965 /*
2966   Test delete on close semantics.
2967  */
2968 static bool run_deletetest(int dummy)
     /* [<][>][^][v][top][bottom][index][help] */
2969 {
2970         struct cli_state *cli1 = NULL;
2971         struct cli_state *cli2 = NULL;
2972         const char *fname = "\\delete.file";
2973         int fnum1 = -1;
2974         int fnum2 = -1;
2975         bool correct = True;
2976         
2977         printf("starting delete test\n");
2978         
2979         if (!torture_open_connection(&cli1, 0)) {
2980                 return False;
2981         }
2982         
2983         cli_sockopt(cli1, sockops);
2984 
2985         /* Test 1 - this should delete the file on close. */
2986         
2987         cli_setatr(cli1, fname, 0, 0);
2988         cli_unlink(cli1, fname);
2989         
2990         fnum1 = cli_nt_create_full(cli1, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS, FILE_ATTRIBUTE_NORMAL,
2991                                    0, FILE_OVERWRITE_IF, 
2992                                    FILE_DELETE_ON_CLOSE, 0);
2993         
2994         if (fnum1 == -1) {
2995                 printf("[1] open of %s failed (%s)\n", fname, cli_errstr(cli1));
2996                 correct = False;
2997                 goto fail;
2998         }
2999 
3000 #if 0 /* JRATEST */
3001         {
3002                 uint32 *accinfo = NULL;
3003                 uint32 len;
3004                 cli_qfileinfo_test(cli1, fnum1, SMB_FILE_ACCESS_INFORMATION, (char **)&accinfo, &len);
3005                 if (accinfo)
3006                         printf("access mode = 0x%lx\n", *accinfo);
3007                 SAFE_FREE(accinfo);
3008         }
3009 #endif
3010 
3011         if (!cli_close(cli1, fnum1)) {
3012                 printf("[1] close failed (%s)\n", cli_errstr(cli1));
3013                 correct = False;
3014                 goto fail;
3015         }
3016 
3017         fnum1 = cli_open(cli1, fname, O_RDWR, DENY_NONE);
3018         if (fnum1 != -1) {
3019                 printf("[1] open of %s succeeded (should fail)\n", fname);
3020                 correct = False;
3021                 goto fail;
3022         }
3023         
3024         printf("first delete on close test succeeded.\n");
3025         
3026         /* Test 2 - this should delete the file on close. */
3027         
3028         cli_setatr(cli1, fname, 0, 0);
3029         cli_unlink(cli1, fname);
3030         
3031         fnum1 = cli_nt_create_full(cli1, fname, 0, GENERIC_ALL_ACCESS,
3032                                    FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE, 
3033                                    FILE_OVERWRITE_IF, 0, 0);
3034         
3035         if (fnum1 == -1) {
3036                 printf("[2] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3037                 correct = False;
3038                 goto fail;
3039         }
3040         
3041         if (!cli_nt_delete_on_close(cli1, fnum1, True)) {
3042                 printf("[2] setting delete_on_close failed (%s)\n", cli_errstr(cli1));
3043                 correct = False;
3044                 goto fail;
3045         }
3046         
3047         if (!cli_close(cli1, fnum1)) {
3048                 printf("[2] close failed (%s)\n", cli_errstr(cli1));
3049                 correct = False;
3050                 goto fail;
3051         }
3052         
3053         fnum1 = cli_open(cli1, fname, O_RDONLY, DENY_NONE);
3054         if (fnum1 != -1) {
3055                 printf("[2] open of %s succeeded should have been deleted on close !\n", fname);
3056                 if (!cli_close(cli1, fnum1)) {
3057                         printf("[2] close failed (%s)\n", cli_errstr(cli1));
3058                         correct = False;
3059                         goto fail;
3060                 }
3061                 cli_unlink(cli1, fname);
3062         } else
3063                 printf("second delete on close test succeeded.\n");
3064         
3065         /* Test 3 - ... */
3066         cli_setatr(cli1, fname, 0, 0);
3067         cli_unlink(cli1, fname);
3068 
3069         fnum1 = cli_nt_create_full(cli1, fname, 0, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_NORMAL,
3070                                    FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0);
3071 
3072         if (fnum1 == -1) {
3073                 printf("[3] open - 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3074                 correct = False;
3075                 goto fail;
3076         }
3077 
3078         /* This should fail with a sharing violation - open for delete is only compatible
3079            with SHARE_DELETE. */
3080 
3081         fnum2 = cli_nt_create_full(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3082                         FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN, 0, 0);
3083 
3084         if (fnum2 != -1) {
3085                 printf("[3] open  - 2 of %s succeeded - should have failed.\n", fname);
3086                 correct = False;
3087                 goto fail;
3088         }
3089 
3090         /* This should succeed. */
3091 
3092         fnum2 = cli_nt_create_full(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3093                         FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN, 0, 0);
3094 
3095         if (fnum2 == -1) {
3096                 printf("[3] open  - 2 of %s failed (%s)\n", fname, cli_errstr(cli1));
3097                 correct = False;
3098                 goto fail;
3099         }
3100 
3101         if (!cli_nt_delete_on_close(cli1, fnum1, True)) {
3102                 printf("[3] setting delete_on_close failed (%s)\n", cli_errstr(cli1));
3103                 correct = False;
3104                 goto fail;
3105         }
3106         
3107         if (!cli_close(cli1, fnum1)) {
3108                 printf("[3] close 1 failed (%s)\n", cli_errstr(cli1));
3109                 correct = False;
3110                 goto fail;
3111         }
3112         
3113         if (!cli_close(cli1, fnum2)) {
3114                 printf("[3] close 2 failed (%s)\n", cli_errstr(cli1));
3115                 correct = False;
3116                 goto fail;
3117         }
3118         
3119         /* This should fail - file should no longer be there. */
3120 
3121         fnum1 = cli_open(cli1, fname, O_RDONLY, DENY_NONE);
3122         if (fnum1 != -1) {
3123                 printf("[3] open of %s succeeded should have been deleted on close !\n", fname);
3124                 if (!cli_close(cli1, fnum1)) {
3125                         printf("[3] close failed (%s)\n", cli_errstr(cli1));
3126                 }
3127                 cli_unlink(cli1, fname);
3128                 correct = False;
3129                 goto fail;
3130         } else
3131                 printf("third delete on close test succeeded.\n");
3132 
3133         /* Test 4 ... */
3134         cli_setatr(cli1, fname, 0, 0);
3135         cli_unlink(cli1, fname);
3136 
3137         fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
3138                         FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0);
3139                                                                 
3140         if (fnum1 == -1) {
3141                 printf("[4] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3142                 correct = False;
3143                 goto fail;
3144         }
3145 
3146         /* This should succeed. */
3147         fnum2 = cli_nt_create_full(cli1, fname, 0, GENERIC_READ_ACCESS,
3148                         FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN, 0, 0);
3149         if (fnum2 == -1) {
3150                 printf("[4] open  - 2 of %s failed (%s)\n", fname, cli_errstr(cli1));
3151                 correct = False;
3152                 goto fail;
3153         }
3154         
3155         if (!cli_close(cli1, fnum2)) {
3156                 printf("[4] close - 1 failed (%s)\n", cli_errstr(cli1));
3157                 correct = False;
3158                 goto fail;
3159         }
3160         
3161         if (!cli_nt_delete_on_close(cli1, fnum1, True)) {
3162                 printf("[4] setting delete_on_close failed (%s)\n", cli_errstr(cli1));
3163                 correct = False;
3164                 goto fail;
3165         }
3166         
3167         /* This should fail - no more opens once delete on close set. */
3168         fnum2 = cli_nt_create_full(cli1, fname, 0, GENERIC_READ_ACCESS,
3169                                    FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3170                                    FILE_OPEN, 0, 0);
3171         if (fnum2 != -1) {
3172                 printf("[4] open  - 3 of %s succeeded ! Should have failed.\n", fname );
3173                 correct = False;
3174                 goto fail;
3175         } else
3176                 printf("fourth delete on close test succeeded.\n");
3177         
3178         if (!cli_close(cli1, fnum1)) {
3179                 printf("[4] close - 2 failed (%s)\n", cli_errstr(cli1));
3180                 correct = False;
3181                 goto fail;
3182         }
3183         
3184         /* Test 5 ... */
3185         cli_setatr(cli1, fname, 0, 0);
3186         cli_unlink(cli1, fname);
3187         
3188         fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT, DENY_NONE);
3189         if (fnum1 == -1) {
3190                 printf("[5] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3191                 correct = False;
3192                 goto fail;
3193         }
3194 
3195         /* This should fail - only allowed on NT opens with DELETE access. */
3196 
3197         if (cli_nt_delete_on_close(cli1, fnum1, True)) {
3198                 printf("[5] setting delete_on_close on OpenX file succeeded - should fail !\n");
3199                 correct = False;
3200                 goto fail;
3201         }
3202 
3203         if (!cli_close(cli1, fnum1)) {
3204                 printf("[5] close - 2 failed (%s)\n", cli_errstr(cli1));
3205                 correct = False;
3206                 goto fail;
3207         }
3208         
3209         printf("fifth delete on close test succeeded.\n");
3210         
3211         /* Test 6 ... */
3212         cli_setatr(cli1, fname, 0, 0);
3213         cli_unlink(cli1, fname);
3214         
3215         fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA,
3216                                    FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3217                                    FILE_OVERWRITE_IF, 0, 0);
3218         
3219         if (fnum1 == -1) {
3220                 printf("[6] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3221                 correct = False;
3222                 goto fail;
3223         }
3224         
3225         /* This should fail - only allowed on NT opens with DELETE access. */
3226         
3227         if (cli_nt_delete_on_close(cli1, fnum1, True)) {
3228                 printf("[6] setting delete_on_close on file with no delete access succeeded - should fail !\n");
3229                 correct = False;
3230                 goto fail;
3231         }
3232 
3233         if (!cli_close(cli1, fnum1)) {
3234                 printf("[6] close - 2 failed (%s)\n", cli_errstr(cli1));
3235                 correct = False;
3236                 goto fail;
3237         }
3238 
3239         printf("sixth delete on close test succeeded.\n");
3240         
3241         /* Test 7 ... */
3242         cli_setatr(cli1, fname, 0, 0);
3243         cli_unlink(cli1, fname);
3244         
3245         fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
3246                                    FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF, 0, 0);
3247                                                                 
3248         if (fnum1 == -1) {
3249                 printf("[7] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3250                 correct = False;
3251                 goto fail;
3252         }
3253 
3254         if (!cli_nt_delete_on_close(cli1, fnum1, True)) {
3255                 printf("[7] setting delete_on_close on file failed !\n");
3256                 correct = False;
3257                 goto fail;
3258         }
3259         
3260         if (!cli_nt_delete_on_close(cli1, fnum1, False)) {
3261                 printf("[7] unsetting delete_on_close on file failed !\n");
3262                 correct = False;
3263                 goto fail;
3264         }
3265 
3266         if (!cli_close(cli1, fnum1)) {
3267                 printf("[7] close - 2 failed (%s)\n", cli_errstr(cli1));
3268                 correct = False;
3269                 goto fail;
3270         }
3271         
3272         /* This next open should succeed - we reset the flag. */
3273         
3274         fnum1 = cli_open(cli1, fname, O_RDONLY, DENY_NONE);
3275         if (fnum1 == -1) {
3276                 printf("[5] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3277                 correct = False;
3278                 goto fail;
3279         }
3280 
3281         if (!cli_close(cli1, fnum1)) {
3282                 printf("[7] close - 2 failed (%s)\n", cli_errstr(cli1));
3283                 correct = False;
3284                 goto fail;
3285         }
3286 
3287         printf("seventh delete on close test succeeded.\n");
3288         
3289         /* Test 7 ... */
3290         cli_setatr(cli1, fname, 0, 0);
3291         cli_unlink(cli1, fname);
3292         
3293         if (!torture_open_connection(&cli2, 1)) {
3294                 printf("[8] failed to open second connection.\n");
3295                 correct = False;
3296                 goto fail;
3297         }
3298 
3299         cli_sockopt(cli1, sockops);
3300         
3301         fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
3302                                    FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3303                                    FILE_OVERWRITE_IF, 0, 0);
3304         
3305         if (fnum1 == -1) {
3306                 printf("[8] open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3307                 correct = False;
3308                 goto fail;
3309         }
3310 
3311         fnum2 = cli_nt_create_full(cli2, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
3312                                    FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3313                                    FILE_OPEN, 0, 0);
3314         
3315         if (fnum2 == -1) {
3316                 printf("[8] open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
3317                 correct = False;
3318                 goto fail;
3319         }
3320 
3321         if (!cli_nt_delete_on_close(cli1, fnum1, True)) {
3322                 printf("[8] setting delete_on_close on file failed !\n");
3323                 correct = False;
3324                 goto fail;
3325         }
3326         
3327         if (!cli_close(cli1, fnum1)) {
3328                 printf("[8] close - 1 failed (%s)\n", cli_errstr(cli1));
3329                 correct = False;
3330                 goto fail;
3331         }
3332 
3333         if (!cli_close(cli2, fnum2)) {
3334                 printf("[8] close - 2 failed (%s)\n", cli_errstr(cli2));
3335                 correct = False;
3336                 goto fail;
3337         }
3338 
3339         /* This should fail.. */
3340         fnum1 = cli_open(cli1, fname, O_RDONLY, DENY_NONE);
3341         if (fnum1 != -1) {
3342                 printf("[8] open of %s succeeded should have been deleted on close !\n", fname);
3343                 goto fail;
3344                 correct = False;
3345         } else
3346                 printf("eighth delete on close test succeeded.\n");
3347 
3348         /* This should fail - we need to set DELETE_ACCESS. */
3349         fnum1 = cli_nt_create_full(cli1, fname, 0,FILE_READ_DATA|FILE_WRITE_DATA,
3350                                    FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE, FILE_OVERWRITE_IF, FILE_DELETE_ON_CLOSE, 0);
3351         
3352         if (fnum1 != -1) {
3353                 printf("[9] open of %s succeeded should have failed!\n", fname);
3354                 correct = False;
3355                 goto fail;
3356         }
3357 
3358         printf("ninth delete on close test succeeded.\n");
3359 
3360         fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
3361                                    FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE, FILE_OVERWRITE_IF, FILE_DELETE_ON_CLOSE, 0);
3362         if (fnum1 == -1) {
3363                 printf("[10] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3364                 correct = False;
3365                 goto fail;
3366         }
3367 
3368         /* This should delete the file. */
3369         if (!cli_close(cli1, fnum1)) {
3370                 printf("[10] close failed (%s)\n", cli_errstr(cli1));
3371                 correct = False;
3372                 goto fail;
3373         }
3374 
3375         /* This should fail.. */
3376         fnum1 = cli_open(cli1, fname, O_RDONLY, DENY_NONE);
3377         if (fnum1 != -1) {
3378                 printf("[10] open of %s succeeded should have been deleted on close !\n", fname);
3379                 goto fail;
3380                 correct = False;
3381         } else
3382                 printf("tenth delete on close test succeeded.\n");
3383 
3384         cli_setatr(cli1, fname, 0, 0);
3385         cli_unlink(cli1, fname);
3386 
3387         /* What error do we get when attempting to open a read-only file with
3388            delete access ? */
3389 
3390         /* Create a readonly file. */
3391         fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA,
3392                                    FILE_ATTRIBUTE_READONLY, FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0);
3393         if (fnum1 == -1) {
3394                 printf("[11] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3395                 correct = False;
3396                 goto fail;
3397         }
3398 
3399         if (!cli_close(cli1, fnum1)) {
3400                 printf("[11] close failed (%s)\n", cli_errstr(cli1));
3401                 correct = False;
3402                 goto fail;
3403         }
3404 
3405         /* Now try open for delete access. */
3406         fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_READ_ATTRIBUTES|DELETE_ACCESS,
3407                                    0, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3408                                    FILE_OVERWRITE_IF, 0, 0);
3409         
3410         if (fnum1 != -1) {
3411                 printf("[11] open of %s succeeded should have been denied with ACCESS_DENIED!\n", fname);
3412                 cli_close(cli1, fnum1);
3413                 goto fail;
3414                 correct = False;
3415         } else {
3416                 NTSTATUS nterr = cli_nt_error(cli1);
3417                 if (!NT_STATUS_EQUAL(nterr,NT_STATUS_ACCESS_DENIED)) {
3418                         printf("[11] open of %s should have been denied with ACCESS_DENIED! Got error %s\n", fname, nt_errstr(nterr));
3419                         goto fail;
3420                         correct = False;
3421                 } else {
3422                         printf("eleventh delete on close test succeeded.\n");
3423                 }
3424         }
3425         
3426         printf("finished delete test\n");
3427 
3428   fail:
3429         /* FIXME: This will crash if we aborted before cli2 got
3430          * intialized, because these functions don't handle
3431          * uninitialized connections. */
3432                 
3433         if (fnum1 != -1) cli_close(cli1, fnum1);
3434         if (fnum2 != -1) cli_close(cli1, fnum2);
3435         cli_setatr(cli1, fname, 0, 0);
3436         cli_unlink(cli1, fname);
3437 
3438         if (cli1 && !torture_close_connection(cli1)) {
3439                 correct = False;
3440         }
3441         if (cli2 && !torture_close_connection(cli2)) {
3442                 correct = False;
3443         }
3444         return correct;
3445 }
3446 
3447 
3448 /*
3449   print out server properties
3450  */
3451 static bool run_properties(int dummy)
     /* [<][>][^][v][top][bottom][index][help] */
3452 {
3453         static struct cli_state *cli;
3454         bool correct = True;
3455         
3456         printf("starting properties test\n");
3457         
3458         ZERO_STRUCT(cli);
3459 
3460         if (!torture_open_connection(&cli, 0)) {
3461                 return False;
3462         }
3463         
3464         cli_sockopt(cli, sockops);
3465 
3466         d_printf("Capabilities 0x%08x\n", cli->capabilities);
3467 
3468         if (!torture_close_connection(cli)) {
3469                 correct = False;
3470         }
3471 
3472         return correct;
3473 }
3474 
3475 
3476 
3477 /* FIRST_DESIRED_ACCESS   0xf019f */
3478 #define FIRST_DESIRED_ACCESS   FILE_READ_DATA|FILE_WRITE_DATA|FILE_APPEND_DATA|\
3479                                FILE_READ_EA|                           /* 0xf */ \
3480                                FILE_WRITE_EA|FILE_READ_ATTRIBUTES|     /* 0x90 */ \
3481                                FILE_WRITE_ATTRIBUTES|                  /* 0x100 */ \
3482                                DELETE_ACCESS|READ_CONTROL_ACCESS|\
3483                                WRITE_DAC_ACCESS|WRITE_OWNER_ACCESS     /* 0xf0000 */
3484 /* SECOND_DESIRED_ACCESS  0xe0080 */
3485 #define SECOND_DESIRED_ACCESS  FILE_READ_ATTRIBUTES|                   /* 0x80 */ \
3486                                READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|\
3487                                WRITE_OWNER_ACCESS                      /* 0xe0000 */
3488 
3489 #if 0
3490 #define THIRD_DESIRED_ACCESS   FILE_READ_ATTRIBUTES|                   /* 0x80 */ \
3491                                READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|\
3492                                FILE_READ_DATA|\
3493                                WRITE_OWNER_ACCESS                      /* */
3494 #endif
3495 
3496 /*
3497   Test ntcreate calls made by xcopy
3498  */
3499 static bool run_xcopy(int dummy)
     /* [<][>][^][v][top][bottom][index][help] */
3500 {
3501         static struct cli_state *cli1;
3502         const char *fname = "\\test.txt";
3503         bool correct = True;
3504         int fnum1, fnum2;
3505 
3506         printf("starting xcopy test\n");
3507         
3508         if (!torture_open_connection(&cli1, 0)) {
3509                 return False;
3510         }
3511         
3512         fnum1 = cli_nt_create_full(cli1, fname, 0,
3513                                    FIRST_DESIRED_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
3514                                    FILE_SHARE_NONE, FILE_OVERWRITE_IF, 
3515                                    0x4044, 0);
3516 
3517         if (fnum1 == -1) {
3518                 printf("First open failed - %s\n", cli_errstr(cli1));
3519                 return False;
3520         }
3521 
3522         fnum2 = cli_nt_create_full(cli1, fname, 0,
3523                                    SECOND_DESIRED_ACCESS, 0,
3524                                    FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN, 
3525                                    0x200000, 0);
3526         if (fnum2 == -1) {
3527                 printf("second open failed - %s\n", cli_errstr(cli1));
3528                 return False;
3529         }
3530         
3531         if (!torture_close_connection(cli1)) {
3532                 correct = False;
3533         }
3534         
3535         return correct;
3536 }
3537 
3538 /*
3539   Test rename on files open with share delete and no share delete.
3540  */
3541 static bool run_rename(int dummy)
     /* [<][>][^][v][top][bottom][index][help] */
3542 {
3543         static struct cli_state *cli1;
3544         const char *fname = "\\test.txt";
3545         const char *fname1 = "\\test1.txt";
3546         bool correct = True;
3547         int fnum1;
3548 
3549         printf("starting rename test\n");
3550         
3551         if (!torture_open_connection(&cli1, 0)) {
3552                 return False;
3553         }
3554         
3555         cli_unlink(cli1, fname);
3556         cli_unlink(cli1, fname1);
3557         fnum1 = cli_nt_create_full(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3558                                    FILE_SHARE_READ, FILE_OVERWRITE_IF, 0, 0);
3559 
3560         if (fnum1 == -1) {
3561                 printf("First open failed - %s\n", cli_errstr(cli1));
3562                 return False;
3563         }
3564 
3565         if (!cli_rename(cli1, fname, fname1)) {
3566                 printf("First rename failed (SHARE_READ) (this is correct) - %s\n", cli_errstr(cli1));
3567         } else {
3568                 printf("First rename succeeded (SHARE_READ) - this should have failed !\n");
3569                 correct = False;
3570         }
3571 
3572         if (!cli_close(cli1, fnum1)) {
3573                 printf("close - 1 failed (%s)\n", cli_errstr(cli1));
3574                 return False;
3575         }
3576 
3577         cli_unlink(cli1, fname);
3578         cli_unlink(cli1, fname1);
3579         fnum1 = cli_nt_create_full(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3580 #if 0
3581                                    FILE_SHARE_DELETE|FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0);
3582 #else
3583                                    FILE_SHARE_DELETE|FILE_SHARE_READ, FILE_OVERWRITE_IF, 0, 0);
3584 #endif
3585 
3586         if (fnum1 == -1) {
3587                 printf("Second open failed - %s\n", cli_errstr(cli1));
3588                 return False;
3589         }
3590 
3591         if (!cli_rename(cli1, fname, fname1)) {
3592                 printf("Second rename failed (SHARE_DELETE | SHARE_READ) - this should have succeeded - %s\n", cli_errstr(cli1));
3593                 correct = False;
3594         } else {
3595                 printf("Second rename succeeded (SHARE_DELETE | SHARE_READ)\n");
3596         }
3597 
3598         if (!cli_close(cli1, fnum1)) {
3599                 printf("close - 2 failed (%s)\n", cli_errstr(cli1));
3600                 return False;
3601         }
3602 
3603         cli_unlink(cli1, fname);
3604         cli_unlink(cli1, fname1);
3605 
3606         fnum1 = cli_nt_create_full(cli1, fname, 0, READ_CONTROL_ACCESS, FILE_ATTRIBUTE_NORMAL,
3607                                    FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0);
3608 
3609         if (fnum1 == -1) {
3610                 printf("Third open failed - %s\n", cli_errstr(cli1));
3611                 return False;
3612         }
3613 
3614 
3615 #if 0
3616   {
3617   int fnum2;
3618 
3619         fnum2 = cli_nt_create_full(cli1, fname, 0, DELETE_ACCESS, FILE_ATTRIBUTE_NORMAL,
3620                                    FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0);
3621 
3622         if (fnum2 == -1) {
3623                 printf("Fourth open failed - %s\n", cli_errstr(cli1));
3624                 return False;
3625         }
3626         if (!cli_nt_delete_on_close(cli1, fnum2, True)) {
3627                 printf("[8] setting delete_on_close on file failed !\n");
3628                 return False;
3629         }
3630         
3631         if (!cli_close(cli1, fnum2)) {
3632                 printf("close - 4 failed (%s)\n", cli_errstr(cli1));
3633                 return False;
3634         }
3635   }
3636 #endif
3637 
3638         if (!cli_rename(cli1, fname, fname1)) {
3639                 printf("Third rename failed (SHARE_NONE) - this should have succeeded - %s\n", cli_errstr(cli1));
3640                 correct = False;
3641         } else {
3642                 printf("Third rename succeeded (SHARE_NONE)\n");
3643         }
3644 
3645         if (!cli_close(cli1, fnum1)) {
3646                 printf("close - 3 failed (%s)\n", cli_errstr(cli1));
3647                 return False;
3648         }
3649 
3650         cli_unlink(cli1, fname);
3651         cli_unlink(cli1, fname1);
3652 
3653         /*----*/
3654 
3655         fnum1 = cli_nt_create_full(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3656                                    FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0);
3657 
3658         if (fnum1 == -1) {
3659                 printf("Fourth open failed - %s\n", cli_errstr(cli1));
3660                 return False;
3661         }
3662 
3663         if (!cli_rename(cli1, fname, fname1)) {
3664                 printf("Fourth rename failed (SHARE_READ | SHARE_WRITE) (this is correct) - %s\n", cli_errstr(cli1));
3665         } else {
3666                 printf("Fourth rename succeeded (SHARE_READ | SHARE_WRITE) - this should have failed !\n");
3667                 correct = False;
3668         }
3669 
3670         if (!cli_close(cli1, fnum1)) {
3671                 printf("close - 4 failed (%s)\n", cli_errstr(cli1));
3672                 return False;
3673         }
3674 
3675         cli_unlink(cli1, fname);
3676         cli_unlink(cli1, fname1);
3677 
3678         /*--*/
3679 
3680         fnum1 = cli_nt_create_full(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3681                                    FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, FILE_OVERWRITE_IF, 0, 0);
3682 
3683         if (fnum1 == -1) {
3684                 printf("Fifth open failed - %s\n", cli_errstr(cli1));
3685                 return False;
3686         }
3687 
3688         if (!cli_rename(cli1, fname, fname1)) {
3689                 printf("Fifth rename failed (SHARE_READ | SHARE_WRITE | SHARE_DELETE) - this should have succeeded - %s ! \n",
3690                         cli_errstr(cli1));
3691                 correct = False;
3692         } else {
3693                 printf("Fifth rename succeeded (SHARE_READ | SHARE_WRITE | SHARE_DELETE) (this is correct) - %s\n", cli_errstr(cli1));
3694         }
3695 
3696         /*
3697          * Now check if the first name still exists ...
3698          */
3699 
3700         /*fnum2 = cli_nt_create_full(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3701                                    FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, FILE_OVERWRITE_IF, 0, 0);
3702 
3703         if (fnum2 == -1) {
3704           printf("Opening original file after rename of open file fails: %s\n",
3705               cli_errstr(cli1));
3706         }
3707         else {
3708           printf("Opening original file after rename of open file works ...\n");
3709           (void)cli_close(cli1, fnum2);
3710           } */
3711 
3712         /*--*/
3713 
3714 
3715         if (!cli_close(cli1, fnum1)) {
3716                 printf("close - 5 failed (%s)\n", cli_errstr(cli1));
3717                 return False;
3718         }
3719 
3720         cli_unlink(cli1, fname);
3721         cli_unlink(cli1, fname1);
3722         
3723         if (!torture_close_connection(cli1)) {
3724                 correct = False;
3725         }
3726         
3727         return correct;
3728 }
3729 
3730 static bool run_pipe_number(int dummy)
     /* [<][>][^][v][top][bottom][index][help] */
3731 {
3732         struct cli_state *cli1;
3733         const char *pipe_name = "\\SPOOLSS";
3734         int fnum;
3735         int num_pipes = 0;
3736 
3737         printf("starting pipenumber test\n");
3738         if (!torture_open_connection(&cli1, 0)) {
3739                 return False;
3740         }
3741 
3742         cli_sockopt(cli1, sockops);
3743         while(1) {
3744                 fnum = cli_nt_create_full(cli1, pipe_name, 0, FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
3745                                    FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN_IF, 0, 0);
3746 
3747                 if (fnum == -1) {
3748                         printf("Open of pipe %s failed with error (%s)\n", pipe_name, cli_errstr(cli1));
3749                         break;
3750                 }
3751                 num_pipes++;
3752                 printf("\r%6d", num_pipes);
3753         }
3754 
3755         printf("pipe_number test - we can open %d %s pipes.\n", num_pipes, pipe_name );
3756         torture_close_connection(cli1);
3757         return True;
3758 }
3759 
3760 /*
3761   Test open mode returns on read-only files.
3762  */
3763 static bool run_opentest(int dummy)
     /* [<][>][^][v][top][bottom][index][help] */
3764 {
3765         static struct cli_state *cli1;
3766         static struct cli_state *cli2;
3767         const char *fname = "\\readonly.file";
3768         int fnum1, fnum2;
3769         char buf[20];
3770         SMB_OFF_T fsize;
3771         bool correct = True;
3772         char *tmp_path;
3773 
3774         printf("starting open test\n");
3775         
3776         if (!torture_open_connection(&cli1, 0)) {
3777                 return False;
3778         }
3779         
3780         cli_setatr(cli1, fname, 0, 0);
3781         cli_unlink(cli1, fname);
3782         
3783         cli_sockopt(cli1, sockops);
3784         
3785         fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
3786         if (fnum1 == -1) {
3787                 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
3788                 return False;
3789         }
3790 
3791         if (!cli_close(cli1, fnum1)) {
3792                 printf("close2 failed (%s)\n", cli_errstr(cli1));
3793                 return False;
3794         }
3795         
3796         if (!cli_setatr(cli1, fname, aRONLY, 0)) {
3797                 printf("cli_setatr failed (%s)\n", cli_errstr(cli1));
3798                 return False;
3799         }
3800         
3801         fnum1 = cli_open(cli1, fname, O_RDONLY, DENY_WRITE);
3802         if (fnum1 == -1) {
3803                 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
3804                 return False;
3805         }
3806         
3807         /* This will fail - but the error should be ERRnoaccess, not ERRbadshare. */
3808         fnum2 = cli_open(cli1, fname, O_RDWR, DENY_ALL);
3809         
3810         if (check_error(__LINE__, cli1, ERRDOS, ERRnoaccess, 
3811                         NT_STATUS_ACCESS_DENIED)) {
3812                 printf("correct error code ERRDOS/ERRnoaccess returned\n");
3813         }
3814         
3815         printf("finished open test 1\n");
3816         
3817         cli_close(cli1, fnum1);
3818         
3819         /* Now try not readonly and ensure ERRbadshare is returned. */
3820         
3821         cli_setatr(cli1, fname, 0, 0);
3822         
3823         fnum1 = cli_open(cli1, fname, O_RDONLY, DENY_WRITE);
3824         if (fnum1 == -1) {
3825                 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
3826                 return False;
3827         }
3828         
3829         /* This will fail - but the error should be ERRshare. */
3830         fnum2 = cli_open(cli1, fname, O_RDWR, DENY_ALL);
3831         
3832         if (check_error(__LINE__, cli1, ERRDOS, ERRbadshare, 
3833                         NT_STATUS_SHARING_VIOLATION)) {
3834                 printf("correct error code ERRDOS/ERRbadshare returned\n");
3835         }
3836         
3837         if (!cli_close(cli1, fnum1)) {
3838                 printf("close2 failed (%s)\n", cli_errstr(cli1));
3839                 return False;
3840         }
3841         
3842         cli_unlink(cli1, fname);
3843         
3844         printf("finished open test 2\n");
3845         
3846         /* Test truncate open disposition on file opened for read. */
3847         
3848         fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
3849         if (fnum1 == -1) {
3850                 printf("(3) open (1) of %s failed (%s)\n", fname, cli_errstr(cli1));
3851                 return False;
3852         }
3853         
3854         /* write 20 bytes. */
3855         
3856         memset(buf, '\0', 20);
3857 
3858         if (cli_write(cli1, fnum1, 0, buf, 0, 20) != 20) {
3859                 printf("write failed (%s)\n", cli_errstr(cli1));
3860                 correct = False;
3861         }
3862 
3863         if (!cli_close(cli1, fnum1)) {
3864                 printf("(3) close1 failed (%s)\n", cli_errstr(cli1));
3865                 return False;
3866         }
3867         
3868         /* Ensure size == 20. */
3869         if (!cli_getatr(cli1, fname, NULL, &fsize, NULL)) {
3870                 printf("(3) getatr failed (%s)\n", cli_errstr(cli1));
3871                 return False;
3872         }
3873         
3874         if (fsize != 20) {
3875                 printf("(3) file size != 20\n");
3876                 return False;
3877         }
3878 
3879         /* Now test if we can truncate a file opened for readonly. */
3880         
3881         fnum1 = cli_open(cli1, fname, O_RDONLY|O_TRUNC, DENY_NONE);
3882         if (fnum1 == -1) {
3883                 printf("(3) open (2) of %s failed (%s)\n", fname, cli_errstr(cli1));
3884                 return False;
3885         }
3886         
3887         if (!cli_close(cli1, fnum1)) {
3888                 printf("close2 failed (%s)\n", cli_errstr(cli1));
3889                 return False;
3890         }
3891 
3892         /* Ensure size == 0. */
3893         if (!cli_getatr(cli1, fname, NULL, &fsize, NULL)) {
3894                 printf("(3) getatr failed (%s)\n", cli_errstr(cli1));
3895                 return False;
3896         }
3897 
3898         if (fsize != 0) {
3899                 printf("(3) file size != 0\n");
3900                 return False;
3901         }
3902         printf("finished open test 3\n");
3903         
3904         cli_unlink(cli1, fname);
3905 
3906 
3907         printf("testing ctemp\n");
3908         fnum1 = cli_ctemp(cli1, "\\", &tmp_path);
3909         if (fnum1 == -1) {
3910                 printf("ctemp failed (%s)\n", cli_errstr(cli1));
3911                 return False;
3912         }
3913         printf("ctemp gave path %s\n", tmp_path);
3914         if (!cli_close(cli1, fnum1)) {
3915                 printf("close of temp failed (%s)\n", cli_errstr(cli1));
3916         }
3917         if (!cli_unlink(cli1, tmp_path)) {
3918                 printf("unlink of temp failed (%s)\n", cli_errstr(cli1));
3919         }
3920         
3921         /* Test the non-io opens... */
3922 
3923         if (!torture_open_connection(&cli2, 1)) {
3924                 return False;
3925         }
3926         
3927         cli_setatr(cli2, fname, 0, 0);
3928         cli_unlink(cli2, fname);
3929         
3930         cli_sockopt(cli2, sockops);
3931 
3932         printf("TEST #1 testing 2 non-io opens (no delete)\n");
3933         
3934         fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3935                                    FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0);
3936 
3937         if (fnum1 == -1) {
3938                 printf("test 1 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3939                 return False;
3940         }
3941 
3942         fnum2 = cli_nt_create_full(cli2, fname, 0, FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3943                                    FILE_SHARE_NONE, FILE_OPEN_IF, 0, 0);
3944 
3945         if (fnum2 == -1) {
3946                 printf("test 1 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
3947                 return False;
3948         }
3949 
3950         if (!cli_close(cli1, fnum1)) {
3951                 printf("test 1 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3952                 return False;
3953         }
3954         if (!cli_close(cli2, fnum2)) {
3955                 printf("test 1 close 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
3956                 return False;
3957         }
3958 
3959         printf("non-io open test #1 passed.\n");
3960 
3961         cli_unlink(cli1, fname);
3962 
3963         printf("TEST #2 testing 2 non-io opens (first with delete)\n");
3964         
3965         fnum1 = cli_nt_create_full(cli1, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3966                                    FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0);
3967 
3968         if (fnum1 == -1) {
3969                 printf("test 2 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3970                 return False;
3971         }
3972 
3973         fnum2 = cli_nt_create_full(cli2, fname, 0, FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3974                                    FILE_SHARE_NONE, FILE_OPEN_IF, 0, 0);
3975 
3976         if (fnum2 == -1) {
3977                 printf("test 2 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
3978                 return False;
3979         }
3980 
3981         if (!cli_close(cli1, fnum1)) {
3982                 printf("test 1 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3983                 return False;
3984         }
3985         if (!cli_close(cli2, fnum2)) {
3986                 printf("test 1 close 2 of %s failed (%s)\n", fname, cli_errstr(cli1));
3987                 return False;
3988         }
3989 
3990         printf("non-io open test #2 passed.\n");
3991 
3992         cli_unlink(cli1, fname);
3993 
3994         printf("TEST #3 testing 2 non-io opens (second with delete)\n");
3995         
3996         fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3997                                    FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0);
3998 
3999         if (fnum1 == -1) {
4000                 printf("test 3 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4001                 return False;
4002         }
4003 
4004         fnum2 = cli_nt_create_full(cli2, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4005                                    FILE_SHARE_NONE, FILE_OPEN_IF, 0, 0);
4006 
4007         if (fnum2 == -1) {
4008                 printf("test 3 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4009                 return False;
4010         }
4011 
4012         if (!cli_close(cli1, fnum1)) {
4013                 printf("test 3 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4014                 return False;
4015         }
4016         if (!cli_close(cli2, fnum2)) {
4017                 printf("test 3 close 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4018                 return False;
4019         }
4020 
4021         printf("non-io open test #3 passed.\n");
4022 
4023         cli_unlink(cli1, fname);
4024 
4025         printf("TEST #4 testing 2 non-io opens (both with delete)\n");
4026         
4027         fnum1 = cli_nt_create_full(cli1, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4028                                    FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0);
4029 
4030         if (fnum1 == -1) {
4031                 printf("test 4 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4032                 return False;
4033         }
4034 
4035         fnum2 = cli_nt_create_full(cli2, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4036                                    FILE_SHARE_NONE, FILE_OPEN_IF, 0, 0);
4037 
4038         if (fnum2 != -1) {
4039                 printf("test 4 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, cli_errstr(cli2));
4040                 return False;
4041         }
4042 
4043         printf("test 3 open 2 of %s gave %s (correct error should be %s)\n", fname, cli_errstr(cli2), "sharing violation");
4044 
4045         if (!cli_close(cli1, fnum1)) {
4046                 printf("test 4 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4047                 return False;
4048         }
4049 
4050         printf("non-io open test #4 passed.\n");
4051 
4052         cli_unlink(cli1, fname);
4053 
4054         printf("TEST #5 testing 2 non-io opens (both with delete - both with file share delete)\n");
4055         
4056         fnum1 = cli_nt_create_full(cli1, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4057                                    FILE_SHARE_DELETE, FILE_OVERWRITE_IF, 0, 0);
4058 
4059         if (fnum1 == -1) {
4060                 printf("test 5 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4061                 return False;
4062         }
4063 
4064         fnum2 = cli_nt_create_full(cli2, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4065                                    FILE_SHARE_DELETE, FILE_OPEN_IF, 0, 0);
4066 
4067         if (fnum2 == -1) {
4068                 printf("test 5 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4069                 return False;
4070         }
4071 
4072         if (!cli_close(cli1, fnum1)) {
4073                 printf("test 5 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4074                 return False;
4075         }
4076 
4077         if (!cli_close(cli2, fnum2)) {
4078                 printf("test 5 close 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4079                 return False;
4080         }
4081 
4082         printf("non-io open test #5 passed.\n");
4083 
4084         printf("TEST #6 testing 1 non-io open, one io open\n");
4085         
4086         cli_unlink(cli1, fname);
4087 
4088         fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
4089                                    FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0);
4090 
4091         if (fnum1 == -1) {
4092                 printf("test 6 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4093                 return False;
4094         }
4095 
4096         fnum2 = cli_nt_create_full(cli2, fname, 0, FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4097                                    FILE_SHARE_READ, FILE_OPEN_IF, 0, 0);
4098 
4099         if (fnum2 == -1) {
4100                 printf("test 6 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4101                 return False;
4102         }
4103 
4104         if (!cli_close(cli1, fnum1)) {
4105                 printf("test 6 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4106                 return False;
4107         }
4108 
4109         if (!cli_close(cli2, fnum2)) {
4110                 printf("test 6 close 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4111                 return False;
4112         }
4113 
4114         printf("non-io open test #6 passed.\n");
4115 
4116         printf("TEST #7 testing 1 non-io open, one io open with delete\n");
4117 
4118         cli_unlink(cli1, fname);
4119 
4120         fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
4121                                    FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0);
4122 
4123         if (fnum1 == -1) {
4124                 printf("test 7 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4125                 return False;
4126         }
4127 
4128         fnum2 = cli_nt_create_full(cli2, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4129                                    FILE_SHARE_READ|FILE_SHARE_DELETE, FILE_OPEN_IF, 0, 0);
4130 
4131         if (fnum2 != -1) {
4132                 printf("test 7 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, cli_errstr(cli2));
4133                 return False;
4134         }
4135 
4136         printf("test 7 open 2 of %s gave %s (correct error should be %s)\n", fname, cli_errstr(cli2), "sharing violation");
4137 
4138         if (!cli_close(cli1, fnum1)) {
4139                 printf("test 7 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4140                 return False;
4141         }
4142 
4143         printf("non-io open test #7 passed.\n");
4144 
4145         cli_unlink(cli1, fname);
4146 
4147         if (!torture_close_connection(cli1)) {
4148                 correct = False;
4149         }
4150         if (!torture_close_connection(cli2)) {
4151                 correct = False;
4152         }
4153         
4154         return correct;
4155 }
4156 
4157 /*
4158   Test POSIX open /mkdir calls.
4159  */
4160 static bool run_simple_posix_open_test(int dummy)
     /* [<][>][^][v][top][bottom][index][help] */
4161 {
4162         static struct cli_state *cli1;
4163         const char *fname = "\\posix:file";
4164         const char *dname = "\\posix:dir";
4165         uint16 major, minor;
4166         uint32 caplow, caphigh;
4167         int fnum1 = -1;
4168         bool correct = false;
4169 
4170         printf("Starting simple POSIX open test\n");
4171 
4172         if (!torture_open_connection(&cli1, 0)) {
4173                 return false;
4174         }
4175 
4176         cli_sockopt(cli1, sockops);
4177 
4178         if (!SERVER_HAS_UNIX_CIFS(cli1)) {
4179                 printf("Server doesn't support UNIX CIFS extensions.\n");
4180                 return false;
4181         }
4182 
4183         if (!cli_unix_extensions_version(cli1, &major,
4184                         &minor, &caplow, &caphigh)) {
4185                 printf("Server didn't return UNIX CIFS extensions.\n");
4186                 return false;
4187         }
4188 
4189         if (!cli_set_unix_extensions_capabilities(cli1,
4190                         major, minor, caplow, caphigh)) {
4191                 printf("Server doesn't support setting UNIX CIFS extensions.\n");
4192                 return false;
4193         }
4194 
4195         cli_setatr(cli1, fname, 0, 0);
4196         cli_posix_unlink(cli1, fname);
4197         cli_setatr(cli1, dname, 0, 0);
4198         cli_posix_rmdir(cli1, dname);
4199 
4200         /* Create a directory. */
4201         if (cli_posix_mkdir(cli1, dname, 0777) == -1) {
4202                 printf("Server doesn't support setting UNIX CIFS extensions.\n");
4203                 goto out;
4204         }
4205 
4206         fnum1 = cli_posix_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, 0600);
4207         if (fnum1 == -1) {
4208                 printf("POSIX create of %s failed (%s)\n", fname, cli_errstr(cli1));
4209                 goto out;
4210         }
4211 
4212         if (!cli_close(cli1, fnum1)) {
4213                 printf("close failed (%s)\n", cli_errstr(cli1));
4214                 goto out;
4215         }
4216 
4217         /* Now open the file again for read only. */
4218         fnum1 = cli_posix_open(cli1, fname, O_RDONLY, 0);
4219         if (fnum1 == -1) {
4220                 printf("POSIX open of %s failed (%s)\n", fname, cli_errstr(cli1));
4221                 goto out;
4222         }
4223 
4224         /* Now unlink while open. */
4225         if (!cli_posix_unlink(cli1, fname)) {
4226                 printf("POSIX unlink of %s failed (%s)\n", fname, cli_errstr(cli1));
4227                 goto out;
4228         }
4229 
4230         if (!cli_close(cli1, fnum1)) {
4231                 printf("close(2) failed (%s)\n", cli_errstr(cli1));
4232                 goto out;
4233         }
4234 
4235         /* Ensure the file has gone. */
4236         fnum1 = cli_posix_open(cli1, fname, O_RDONLY, 0);
4237         if (fnum1 != -1) {
4238                 printf("POSIX open of %s succeeded, should have been deleted.\n", fname);
4239                 goto out;
4240         }
4241 
4242         /* What happens when we try and POSIX open a directory ? */
4243         fnum1 = cli_posix_open(cli1, dname, O_RDONLY, 0);
4244         if (fnum1 != -1) {
4245                 printf("POSIX open of directory %s succeeded, should have failed.\n", fname);
4246                 goto out;
4247         } else {
4248                 if (!check_error(__LINE__, cli1, ERRDOS, EISDIR,
4249                                 NT_STATUS_FILE_IS_A_DIRECTORY)) {
4250                         goto out;
4251                 }
4252         }
4253 
4254         if (!cli_posix_rmdir(cli1, dname)) {
4255                 printf("POSIX rmdir failed (%s)\n", cli_errstr(cli1));
4256                 goto out;
4257         }
4258 
4259         printf("Simple POSIX open test passed\n");
4260         correct = true;
4261 
4262   out:
4263 
4264         if (fnum1 != -1) {
4265                 cli_close(cli1, fnum1);
4266                 fnum1 = -1;
4267         }
4268 
4269         cli_setatr(cli1, fname, 0, 0);
4270         cli_posix_unlink(cli1, fname);
4271         cli_setatr(cli1, dname, 0, 0);
4272         cli_posix_rmdir(cli1, dname);
4273 
4274         if (!torture_close_connection(cli1)) {
4275                 correct = false;
4276         }
4277 
4278         return correct;
4279 }
4280 
4281 
4282 static uint32 open_attrs_table[] = {
4283                 FILE_ATTRIBUTE_NORMAL,
4284                 FILE_ATTRIBUTE_ARCHIVE,
4285                 FILE_ATTRIBUTE_READONLY,
4286                 FILE_ATTRIBUTE_HIDDEN,
4287                 FILE_ATTRIBUTE_SYSTEM,
4288 
4289                 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY,
4290                 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN,
4291                 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM,
4292                 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN,
4293                 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM,
4294                 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM,
4295 
4296                 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN,
4297                 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM,
4298                 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM,
4299                 FILE_ATTRIBUTE_HIDDEN,FILE_ATTRIBUTE_SYSTEM,
4300 };
4301 
4302 struct trunc_open_results {
4303         unsigned int num;
4304         uint32 init_attr;
4305         uint32 trunc_attr;
4306         uint32 result_attr;
4307 };
4308 
4309 static struct trunc_open_results attr_results[] = {
4310         { 0, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE },
4311         { 1, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE },
4312         { 2, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_READONLY, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY },
4313         { 16, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE },
4314         { 17, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE },
4315         { 18, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_READONLY, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY },
4316         { 51, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
4317         { 54, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
4318         { 56, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN },
4319         { 68, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
4320         { 71, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
4321         { 73, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM },
4322         { 99, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN,FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
4323         { 102, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
4324         { 104, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN },
4325         { 116, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
4326         { 119,  FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM,  FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
4327         { 121, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM },
4328         { 170, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM|FILE_ATTRIBUTE_HIDDEN },
4329         { 173, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM },
4330         { 227, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
4331         { 230, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
4332         { 232, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN },
4333         { 244, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
4334         { 247, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
4335         { 249, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM }
4336 };
4337 
4338 static bool run_openattrtest(int dummy)
     /* [<][>][^][v][top][bottom][index][help] */
4339 {
4340         static struct cli_state *cli1;
4341         const char *fname = "\\openattr.file";
4342         int fnum1;
4343         bool correct = True;
4344         uint16 attr;
4345         unsigned int i, j, k, l;
4346 
4347         printf("starting open attr test\n");
4348         
4349         if (!torture_open_connection(&cli1, 0)) {
4350                 return False;
4351         }
4352         
4353         cli_sockopt(cli1, sockops);
4354 
4355         for (k = 0, i = 0; i < sizeof(open_attrs_table)/sizeof(uint32); i++) {
4356                 cli_setatr(cli1, fname, 0, 0);
4357                 cli_unlink(cli1, fname);
4358                 fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_WRITE_DATA, open_attrs_table[i],
4359                                    FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0);
4360 
4361                 if (fnum1 == -1) {
4362                         printf("open %d (1) of %s failed (%s)\n", i, fname, cli_errstr(cli1));
4363                         return False;
4364                 }
4365 
4366                 if (!cli_close(cli1, fnum1)) {
4367                         printf("close %d (1) of %s failed (%s)\n", i, fname, cli_errstr(cli1));
4368                         return False;
4369                 }
4370 
4371                 for (j = 0; j < sizeof(open_attrs_table)/sizeof(uint32); j++) {
4372                         fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA, open_attrs_table[j],
4373                                            FILE_SHARE_NONE, FILE_OVERWRITE, 0, 0);
4374 
4375                         if (fnum1 == -1) {
4376                                 for (l = 0; l < sizeof(attr_results)/sizeof(struct trunc_open_results); l++) {
4377                                         if (attr_results[l].num == k) {
4378                                                 printf("[%d] trunc open 0x%x -> 0x%x of %s failed - should have succeeded !(0x%x:%s)\n",
4379                                                                 k, open_attrs_table[i],
4380                                                                 open_attrs_table[j],
4381                                                                 fname, NT_STATUS_V(cli_nt_error(cli1)), cli_errstr(cli1));
4382                                                 correct = False;
4383                                         }
4384                                 }
4385                                 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_ACCESS_DENIED)) {
4386                                         printf("[%d] trunc open 0x%x -> 0x%x failed with wrong error code %s\n",
4387                                                         k, open_attrs_table[i], open_attrs_table[j],
4388                                                         cli_errstr(cli1));
4389                                         correct = False;
4390                                 }
4391 #if 0
4392                                 printf("[%d] trunc open 0x%x -> 0x%x failed\n", k, open_attrs_table[i], open_attrs_table[j]);
4393 #endif
4394                                 k++;
4395                                 continue;
4396                         }
4397 
4398                         if (!cli_close(cli1, fnum1)) {
4399                                 printf("close %d (2) of %s failed (%s)\n", j, fname, cli_errstr(cli1));
4400                                 return False;
4401                         }
4402 
4403                         if (!cli_getatr(cli1, fname, &attr, NULL, NULL)) {
4404                                 printf("getatr(2) failed (%s)\n", cli_errstr(cli1));
4405                                 return False;
4406                         }
4407 
4408 #if 0
4409                         printf("[%d] getatr check [0x%x] trunc [0x%x] got attr 0x%x\n",
4410                                         k,  open_attrs_table[i],  open_attrs_table[j], attr );
4411 #endif
4412 
4413                         for (l = 0; l < sizeof(attr_results)/sizeof(struct trunc_open_results); l++) {
4414                                 if (attr_results[l].num == k) {
4415                                         if (attr != attr_results[l].result_attr ||
4416                                                         open_attrs_table[i] != attr_results[l].init_attr ||
4417                                                         open_attrs_table[j] != attr_results[l].trunc_attr) {
4418                                                 printf("getatr check failed. [0x%x] trunc [0x%x] got attr 0x%x, should be 0x%x\n",
4419                                                 open_attrs_table[i],
4420                                                 open_attrs_table[j],
4421                                                 (unsigned int)attr,
4422                                                 attr_results[l].result_attr);
4423                                                 correct = False;
4424                                         }
4425                                         break;
4426                                 }
4427                         }
4428                         k++;
4429                 }
4430         }
4431 
4432         cli_setatr(cli1, fname, 0, 0);
4433         cli_unlink(cli1, fname);
4434 
4435         printf("open attr test %s.\n", correct ? "passed" : "failed");
4436 
4437         if (!torture_close_connection(cli1)) {
4438                 correct = False;
4439         }
4440         return correct;
4441 }
4442 
4443 static void list_fn(const char *mnt, file_info *finfo, const char *name, void *state)
     /* [<][>][^][v][top][bottom][index][help] */
4444 {
4445         
4446 }
4447 
4448 /*
4449   test directory listing speed
4450  */
4451 static bool run_dirtest(int dummy)
     /* [<][>][^][v][top][bottom][index][help] */
4452 {
4453         int i;
4454         static struct cli_state *cli;
4455         int fnum;
4456         double t1;
4457         bool correct = True;
4458 
4459         printf("starting directory test\n");
4460 
4461         if (!torture_open_connection(&cli, 0)) {
4462                 return False;
4463         }
4464 
4465         cli_sockopt(cli, sockops);
4466 
4467         srandom(0);
4468         for (i=0;i<torture_numops;i++) {
4469                 fstring fname;
4470                 slprintf(fname, sizeof(fname), "\\%x", (int)random());
4471                 fnum = cli_open(cli, fname, O_RDWR|O_CREAT, DENY_NONE);
4472                 if (fnum == -1) {
4473                         fprintf(stderr,"Failed to open %s\n", fname);
4474                         return False;
4475                 }
4476                 cli_close(cli, fnum);
4477         }
4478 
4479         t1 = end_timer();
4480 
4481         printf("Matched %d\n", cli_list(cli, "a*.*", 0, list_fn, NULL));
4482         printf("Matched %d\n", cli_list(cli, "b*.*", 0, list_fn, NULL));
4483         printf("Matched %d\n", cli_list(cli, "xyzabc", 0, list_fn, NULL));
4484 
4485         printf("dirtest core %g seconds\n", end_timer() - t1);
4486 
4487         srandom(0);
4488         for (i=0;i<torture_numops;i++) {
4489                 fstring fname;
4490                 slprintf(fname, sizeof(fname), "\\%x", (int)random());
4491                 cli_unlink(cli, fname);
4492         }
4493 
4494         if (!torture_close_connection(cli)) {
4495                 correct = False;
4496         }
4497 
4498         printf("finished dirtest\n");
4499 
4500         return correct;
4501 }
4502 
4503 static void del_fn(const char *mnt, file_info *finfo, const char *mask, void *state)
     /* [<][>][^][v][top][bottom][index][help] */
4504 {
4505         struct cli_state *pcli = (struct cli_state *)state;
4506         fstring fname;
4507         slprintf(fname, sizeof(fname), "\\LISTDIR\\%s", finfo->name);
4508 
4509         if (strcmp(finfo->name, ".") == 0 || strcmp(finfo->name, "..") == 0)
4510                 return;
4511 
4512         if (finfo->mode & aDIR) {
4513                 if (!cli_rmdir(pcli, fname))
4514                         printf("del_fn: failed to rmdir %s\n,", fname );
4515         } else {
4516                 if (!cli_unlink(pcli, fname))
4517                         printf("del_fn: failed to unlink %s\n,", fname );
4518         }
4519 }
4520 
4521 
4522 /*
4523   sees what IOCTLs are supported
4524  */
4525 bool torture_ioctl_test(int dummy)
     /* [<][>][^][v][top][bottom][index][help] */
4526 {
4527         static struct cli_state *cli;
4528         uint16 device, function;
4529         int fnum;
4530         const char *fname = "\\ioctl.dat";
4531         DATA_BLOB blob;
4532         NTSTATUS status;
4533 
4534         if (!torture_open_connection(&cli, 0)) {
4535                 return False;
4536         }
4537 
4538         printf("starting ioctl test\n");
4539 
4540         cli_unlink(cli, fname);
4541 
4542         fnum = cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
4543         if (fnum == -1) {
4544                 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
4545                 return False;
4546         }
4547 
4548         status = cli_raw_ioctl(cli, fnum, 0x2d0000 | (0x0420<<2), &blob);
4549         printf("ioctl device info: %s\n", cli_errstr(cli));
4550 
4551         status = cli_raw_ioctl(cli, fnum, IOCTL_QUERY_JOB_INFO, &blob);
4552         printf("ioctl job info: %s\n", cli_errstr(cli));
4553 
4554         for (device=0;device<0x100;device++) {
4555                 printf("testing device=0x%x\n", device);
4556                 for (function=0;function<0x100;function++) {
4557                         uint32 code = (device<<16) | function;
4558 
4559                         status = cli_raw_ioctl(cli, fnum, code, &blob);
4560 
4561                         if (NT_STATUS_IS_OK(status)) {
4562                                 printf("ioctl 0x%x OK : %d bytes\n", (int)code,
4563                                        (int)blob.length);
4564                                 data_blob_free(&blob);
4565                         }
4566                 }
4567         }
4568 
4569         if (!torture_close_connection(cli)) {
4570                 return False;
4571         }
4572 
4573         return True;
4574 }
4575 
4576 
4577 /*
4578   tries varients of chkpath
4579  */
4580 bool torture_chkpath_test(int dummy)
     /* [<][>][^][v][top][bottom][index][help] */
4581 {
4582         static struct cli_state *cli;
4583         int fnum;
4584         bool ret;
4585 
4586         if (!torture_open_connection(&cli, 0)) {
4587                 return False;
4588         }
4589 
4590         printf("starting chkpath test\n");
4591 
4592         /* cleanup from an old run */
4593         cli_rmdir(cli, "\\chkpath.dir\\dir2");
4594         cli_unlink(cli, "\\chkpath.dir\\*");
4595         cli_rmdir(cli, "\\chkpath.dir");
4596 
4597         if (!cli_mkdir(cli, "\\chkpath.dir")) {
4598                 printf("mkdir1 failed : %s\n", cli_errstr(cli));
4599                 return False;
4600         }
4601 
4602         if (!cli_mkdir(cli, "\\chkpath.dir\\dir2")) {
4603                 printf("mkdir2 failed : %s\n", cli_errstr(cli));
4604                 return False;
4605         }
4606 
4607         fnum = cli_open(cli, "\\chkpath.dir\\foo.txt", O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
4608         if (fnum == -1) {
4609                 printf("open1 failed (%s)\n", cli_errstr(cli));
4610                 return False;
4611         }
4612         cli_close(cli, fnum);
4613 
4614         if (!cli_chkpath(cli, "\\chkpath.dir")) {
4615                 printf("chkpath1 failed: %s\n", cli_errstr(cli));
4616                 ret = False;
4617         }
4618 
4619         if (!cli_chkpath(cli, "\\chkpath.dir\\dir2")) {
4620                 printf("chkpath2 failed: %s\n", cli_errstr(cli));
4621                 ret = False;
4622         }
4623 
4624         if (!cli_chkpath(cli, "\\chkpath.dir\\foo.txt")) {
4625                 ret = check_error(__LINE__, cli, ERRDOS, ERRbadpath, 
4626                                   NT_STATUS_NOT_A_DIRECTORY);
4627         } else {
4628                 printf("* chkpath on a file should fail\n");
4629                 ret = False;
4630         }
4631 
4632         if (!cli_chkpath(cli, "\\chkpath.dir\\bar.txt")) {
4633                 ret = check_error(__LINE__, cli, ERRDOS, ERRbadfile, 
4634                                   NT_STATUS_OBJECT_NAME_NOT_FOUND);
4635         } else {
4636                 printf("* chkpath on a non existant file should fail\n");
4637                 ret = False;
4638         }
4639 
4640         if (!cli_chkpath(cli, "\\chkpath.dir\\dirxx\\bar.txt")) {
4641                 ret = check_error(__LINE__, cli, ERRDOS, ERRbadpath, 
4642                                   NT_STATUS_OBJECT_PATH_NOT_FOUND);
4643         } else {
4644                 printf("* chkpath on a non existent component should fail\n");
4645                 ret = False;
4646         }
4647 
4648         cli_rmdir(cli, "\\chkpath.dir\\dir2");
4649         cli_unlink(cli, "\\chkpath.dir\\*");
4650         cli_rmdir(cli, "\\chkpath.dir");
4651 
4652         if (!torture_close_connection(cli)) {
4653                 return False;
4654         }
4655 
4656         return ret;
4657 }
4658 
4659 static bool run_eatest(int dummy)
     /* [<][>][^][v][top][bottom][index][help] */
4660 {
4661         static struct cli_state *cli;
4662         const char *fname = "\\eatest.txt";
4663         bool correct = True;
4664         int fnum, i;
4665         size_t num_eas;
4666         struct ea_struct *ea_list = NULL;
4667         TALLOC_CTX *mem_ctx = talloc_init("eatest");
4668 
4669         printf("starting eatest\n");
4670         
4671         if (!torture_open_connection(&cli, 0)) {
4672                 talloc_destroy(mem_ctx);
4673                 return False;
4674         }
4675         
4676         cli_unlink(cli, fname);
4677         fnum = cli_nt_create_full(cli, fname, 0,
4678                                    FIRST_DESIRED_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
4679                                    FILE_SHARE_NONE, FILE_OVERWRITE_IF, 
4680                                    0x4044, 0);
4681 
4682         if (fnum == -1) {
4683                 printf("open failed - %s\n", cli_errstr(cli));
4684                 talloc_destroy(mem_ctx);
4685                 return False;
4686         }
4687 
4688         for (i = 0; i < 10; i++) {
4689                 fstring ea_name, ea_val;
4690 
4691                 slprintf(ea_name, sizeof(ea_name), "EA_%d", i);
4692                 memset(ea_val, (char)i+1, i+1);
4693                 if (!cli_set_ea_fnum(cli, fnum, ea_name, ea_val, i+1)) {
4694                         printf("ea_set of name %s failed - %s\n", ea_name, cli_errstr(cli));
4695                         talloc_destroy(mem_ctx);
4696                         return False;
4697                 }
4698         }
4699         
4700         cli_close(cli, fnum);
4701         for (i = 0; i < 10; i++) {
4702                 fstring ea_name, ea_val;
4703 
4704                 slprintf(ea_name, sizeof(ea_name), "EA_%d", i+10);
4705                 memset(ea_val, (char)i+1, i+1);
4706                 if (!cli_set_ea_path(cli, fname, ea_name, ea_val, i+1)) {
4707                         printf("ea_set of name %s failed - %s\n", ea_name, cli_errstr(cli));
4708                         talloc_destroy(mem_ctx);
4709                         return False;
4710                 }
4711         }
4712         
4713         if (!cli_get_ea_list_path(cli, fname, mem_ctx, &num_eas, &ea_list)) {
4714                 printf("ea_get list failed - %s\n", cli_errstr(cli));
4715                 correct = False;
4716         }
4717 
4718         printf("num_eas = %d\n", (int)num_eas);
4719 
4720         if (num_eas != 20) {
4721                 printf("Should be 20 EA's stored... failing.\n");
4722                 correct = False;
4723         }
4724 
4725         for (i = 0; i < num_eas; i++) {
4726                 printf("%d: ea_name = %s. Val = ", i, ea_list[i].name);
4727                 dump_data(0, ea_list[i].value.data,
4728                           ea_list[i].value.length);
4729         }
4730 
4731         /* Setting EA's to zero length deletes them. Test this */
4732         printf("Now deleting all EA's - case indepenent....\n");
4733 
4734 #if 1
4735         cli_set_ea_path(cli, fname, "", "", 0);
4736 #else
4737         for (i = 0; i < 20; i++) {
4738                 fstring ea_name;
4739                 slprintf(ea_name, sizeof(ea_name), "ea_%d", i);
4740                 if (!cli_set_ea_path(cli, fname, ea_name, "", 0)) {
4741                         printf("ea_set of name %s failed - %s\n", ea_name, cli_errstr(cli));
4742                         talloc_destroy(mem_ctx);
4743                         return False;
4744                 }
4745         }
4746 #endif
4747 
4748         if (!cli_get_ea_list_path(cli, fname, mem_ctx, &num_eas, &ea_list)) {
4749                 printf("ea_get list failed - %s\n", cli_errstr(cli));
4750                 correct = False;
4751         }
4752 
4753         printf("num_eas = %d\n", (int)num_eas);
4754         for (i = 0; i < num_eas; i++) {
4755                 printf("%d: ea_name = %s. Val = ", i, ea_list[i].name);
4756                 dump_data(0, ea_list[i].value.data,
4757                           ea_list[i].value.length);
4758         }
4759 
4760         if (num_eas != 0) {
4761                 printf("deleting EA's failed.\n");
4762                 correct = False;
4763         }
4764 
4765         /* Try and delete a non existant EA. */
4766         if (!cli_set_ea_path(cli, fname, "foo", "", 0)) {
4767                 printf("deleting non-existant EA 'foo' should succeed. %s\n", cli_errstr(cli));
4768                 correct = False;
4769         }
4770 
4771         talloc_destroy(mem_ctx);
4772         if (!torture_close_connection(cli)) {
4773                 correct = False;
4774         }
4775         
4776         return correct;
4777 }
4778 
4779 static bool run_dirtest1(int dummy)
     /* [<][>][^][v][top][bottom][index][help] */
4780 {
4781         int i;
4782         static struct cli_state *cli;
4783         int fnum, num_seen;
4784         bool correct = True;
4785 
4786         printf("starting directory test\n");
4787 
4788         if (!torture_open_connection(&cli, 0)) {
4789                 return False;
4790         }
4791 
4792         cli_sockopt(cli, sockops);
4793 
4794         cli_list(cli, "\\LISTDIR\\*", 0, del_fn, cli);
4795         cli_list(cli, "\\LISTDIR\\*", aDIR, del_fn, cli);
4796         cli_rmdir(cli, "\\LISTDIR");
4797         cli_mkdir(cli, "\\LISTDIR");
4798 
4799         /* Create 1000 files and 1000 directories. */
4800         for (i=0;i<1000;i++) {
4801                 fstring fname;
4802                 slprintf(fname, sizeof(fname), "\\LISTDIR\\f%d", i);
4803                 fnum = cli_nt_create_full(cli, fname, 0, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
4804                                    FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0);
4805                 if (fnum == -1) {
4806                         fprintf(stderr,"Failed to open %s\n", fname);
4807                         return False;
4808                 }
4809                 cli_close(cli, fnum);
4810         }
4811         for (i=0;i<1000;i++) {
4812                 fstring fname;
4813                 slprintf(fname, sizeof(fname), "\\LISTDIR\\d%d", i);
4814                 if (!cli_mkdir(cli, fname)) {
4815                         fprintf(stderr,"Failed to open %s\n", fname);
4816                         return False;
4817                 }
4818         }
4819 
4820         /* Now ensure that doing an old list sees both files and directories. */
4821         num_seen = cli_list_old(cli, "\\LISTDIR\\*", aDIR, list_fn, NULL);
4822         printf("num_seen = %d\n", num_seen );
4823         /* We should see 100 files + 1000 directories + . and .. */
4824         if (num_seen != 2002)
4825                 correct = False;
4826 
4827         /* Ensure if we have the "must have" bits we only see the
4828          * relevent entries.
4829          */
4830         num_seen = cli_list_old(cli, "\\LISTDIR\\*", (aDIR<<8)|aDIR, list_fn, NULL);
4831         printf("num_seen = %d\n", num_seen );
4832         if (num_seen != 1002)
4833                 correct = False;
4834 
4835         num_seen = cli_list_old(cli, "\\LISTDIR\\*", (aARCH<<8)|aDIR, list_fn, NULL);
4836         printf("num_seen = %d\n", num_seen );
4837         if (num_seen != 1000)
4838                 correct = False;
4839 
4840         /* Delete everything. */
4841         cli_list(cli, "\\LISTDIR\\*", 0, del_fn, cli);
4842         cli_list(cli, "\\LISTDIR\\*", aDIR, del_fn, cli);
4843         cli_rmdir(cli, "\\LISTDIR");
4844 
4845 #if 0
4846         printf("Matched %d\n", cli_list(cli, "a*.*", 0, list_fn, NULL));
4847         printf("Matched %d\n", cli_list(cli, "b*.*", 0, list_fn, NULL));
4848         printf("Matched %d\n", cli_list(cli, "xyzabc", 0, list_fn, NULL));
4849 #endif
4850 
4851         if (!torture_close_connection(cli)) {
4852                 correct = False;
4853         }
4854 
4855         printf("finished dirtest1\n");
4856 
4857         return correct;
4858 }
4859 
4860 static bool run_error_map_extract(int dummy) {
     /* [<][>][^][v][top][bottom][index][help] */
4861         
4862         static struct cli_state *c_dos;
4863         static struct cli_state *c_nt;
4864         NTSTATUS status;
4865 
4866         uint32 error;
4867 
4868         uint32 flgs2, errnum;
4869         uint8 errclass;
4870 
4871         NTSTATUS nt_status;
4872 
4873         fstring user;
4874 
4875         /* NT-Error connection */
4876 
4877         if (!(c_nt = open_nbt_connection())) {
4878                 return False;
4879         }
4880 
4881         c_nt->use_spnego = False;
4882 
4883         status = cli_negprot(c_nt);
4884 
4885         if (!NT_STATUS_IS_OK(status)) {
4886                 printf("%s rejected the NT-error negprot (%s)\n", host,
4887                        nt_errstr(status));
4888                 cli_shutdown(c_nt);
4889                 return False;
4890         }
4891 
4892         if (!NT_STATUS_IS_OK(cli_session_setup(c_nt, "", "", 0, "", 0,
4893                                                workgroup))) {
4894                 printf("%s rejected the NT-error initial session setup (%s)\n",host, cli_errstr(c_nt));
4895                 return False;
4896         }
4897 
4898         /* DOS-Error connection */
4899 
4900         if (!(c_dos = open_nbt_connection())) {
4901                 return False;
4902         }
4903 
4904         c_dos->use_spnego = False;
4905         c_dos->force_dos_errors = True;
4906 
4907         status = cli_negprot(c_dos);
4908         if (!NT_STATUS_IS_OK(status)) {
4909                 printf("%s rejected the DOS-error negprot (%s)\n", host,
4910                        nt_errstr(status));
4911                 cli_shutdown(c_dos);
4912                 return False;
4913         }
4914 
4915         if (!NT_STATUS_IS_OK(cli_session_setup(c_dos, "", "", 0, "", 0,
4916                                                workgroup))) {
4917                 printf("%s rejected the DOS-error initial session setup (%s)\n",host, cli_errstr(c_dos));
4918                 return False;
4919         }
4920 
4921         for (error=(0xc0000000 | 0x1); error < (0xc0000000| 0xFFF); error++) {
4922                 fstr_sprintf(user, "%X", error);
4923 
4924                 if (NT_STATUS_IS_OK(cli_session_setup(c_nt, user, 
4925                                                       password, strlen(password),
4926                                                       password, strlen(password),
4927                                                       workgroup))) {
4928                         printf("/** Session setup succeeded.  This shouldn't happen...*/\n");
4929                 }
4930                 
4931                 flgs2 = SVAL(c_nt->inbuf,smb_flg2);
4932                 
4933                 /* Case #1: 32-bit NT errors */
4934                 if (flgs2 & FLAGS2_32_BIT_ERROR_CODES) {
4935                         nt_status = NT_STATUS(IVAL(c_nt->inbuf,smb_rcls));
4936                 } else {
4937                         printf("/** Dos error on NT connection! (%s) */\n", 
4938                                cli_errstr(c_nt));
4939                         nt_status = NT_STATUS(0xc0000000);
4940                 }
4941 
4942                 if (NT_STATUS_IS_OK(cli_session_setup(c_dos, user, 
4943                                                       password, strlen(password),
4944                                                       password, strlen(password),
4945                                                       workgroup))) {
4946                         printf("/** Session setup succeeded.  This shouldn't happen...*/\n");
4947                 }
4948                 flgs2 = SVAL(c_dos->inbuf,smb_flg2), errnum;
4949                 
4950                 /* Case #1: 32-bit NT errors */
4951                 if (flgs2 & FLAGS2_32_BIT_ERROR_CODES) {
4952                         printf("/** NT error on DOS connection! (%s) */\n", 
4953                                cli_errstr(c_nt));
4954                         errnum = errclass = 0;
4955                 } else {
4956                         cli_dos_error(c_dos, &errclass, &errnum);
4957                 }
4958 
4959                 if (NT_STATUS_V(nt_status) != error) { 
4960                         printf("/*\t{ This NT error code was 'sqashed'\n\t from %s to %s \n\t during the session setup }\n*/\n", 
4961                                get_nt_error_c_code(NT_STATUS(error)), 
4962                                get_nt_error_c_code(nt_status));
4963                 }
4964                 
4965                 printf("\t{%s,\t%s,\t%s},\n", 
4966                        smb_dos_err_class(errclass), 
4967                        smb_dos_err_name(errclass, errnum), 
4968                        get_nt_error_c_code(NT_STATUS(error)));
4969         }
4970         return True;
4971 }
4972 
4973 static bool run_sesssetup_bench(int dummy)
     /* [<][>][^][v][top][bottom][index][help] */
4974 {
4975         static struct cli_state *c;
4976         const char *fname = "\\file.dat";
4977         int fnum;
4978         NTSTATUS status;
4979         int i;
4980 
4981         if (!torture_open_connection(&c, 0)) {
4982                 return false;
4983         }
4984 
4985         fnum = cli_nt_create_full(
4986                 c, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS,
4987                 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
4988                 FILE_DELETE_ON_CLOSE, 0);
4989         if (fnum == -1) {
4990                 d_printf("open %s failed: %s\n", fname, cli_errstr(c));
4991                 return false;
4992         }
4993 
4994         for (i=0; i<torture_numops; i++) {
4995                 status = cli_session_setup(
4996                         c, username,
4997                         password, strlen(password),
4998                         password, strlen(password),
4999                         workgroup);
5000                 if (!NT_STATUS_IS_OK(status)) {
5001                         d_printf("(%s) cli_session_setup failed: %s\n",
5002                                  __location__, nt_errstr(status));
5003                         return false;
5004                 }
5005 
5006                 d_printf("\r%d   ", (int)c->vuid);
5007 
5008                 if (!cli_ulogoff(c)) {
5009                         d_printf("(%s) cli_ulogoff failed: %s\n",
5010                                  __location__, cli_errstr(c));
5011                         return false;
5012                 }
5013                 c->vuid = 0;
5014         }
5015 
5016         return true;
5017 }
5018 
5019 static bool subst_test(const char *str, const char *user, const char *domain,
     /* [<][>][^][v][top][bottom][index][help] */
5020                        uid_t uid, gid_t gid, const char *expected)
5021 {
5022         char *subst;
5023         bool result = true;
5024 
5025         subst = talloc_sub_specified(talloc_tos(), str, user, domain, uid, gid);
5026 
5027         if (strcmp(subst, expected) != 0) {
5028                 printf("sub_specified(%s, %s, %s, %d, %d) returned [%s], expected "
5029                        "[%s]\n", str, user, domain, (int)uid, (int)gid, subst,
5030                        expected);
5031                 result = false;
5032         }
5033 
5034         TALLOC_FREE(subst);
5035         return result;
5036 }
5037 
5038 static void chain1_open_completion(struct async_req *req)
     /* [<][>][^][v][top][bottom][index][help] */
5039 {
5040         int fnum;
5041         NTSTATUS status;
5042 
5043         status = cli_open_recv(req, &fnum);
5044         TALLOC_FREE(req);
5045 
5046         d_printf("cli_open_recv returned %s: %d\n",
5047                  nt_errstr(status),
5048                  NT_STATUS_IS_OK(status) ? fnum : -1);
5049 }
5050 
5051 static void chain1_read_completion(struct async_req *req)
     /* [<][>][^][v][top][bottom][index][help] */
5052 {
5053         NTSTATUS status;
5054         ssize_t received;
5055         uint8_t *rcvbuf;
5056 
5057         status = cli_read_andx_recv(req, &received, &rcvbuf);
5058         if (!NT_STATUS_IS_OK(status)) {
5059                 TALLOC_FREE(req);
5060                 d_printf("cli_read_andx_recv returned %s\n",
5061                          nt_errstr(status));
5062                 return;
5063         }
5064 
5065         d_printf("got %d bytes: %.*s\n", (int)received, (int)received,
5066                  (char *)rcvbuf);
5067         TALLOC_FREE(req);
5068 }
5069 
5070 static void chain1_write_completion(struct async_req *req)
     /* [<][>][^][v][top][bottom][index][help] */
5071 {
5072         NTSTATUS status;
5073         size_t written;
5074 
5075         status = cli_write_andx_recv(req, &written);
5076         if (!NT_STATUS_IS_OK(status)) {
5077                 TALLOC_FREE(req);
5078                 d_printf("cli_write_andx_recv returned %s\n",
5079                          nt_errstr(status));
5080                 return;
5081         }
5082 
5083         d_printf("wrote %d bytes\n", (int)written);
5084         TALLOC_FREE(req);
5085 }
5086 
5087 static void chain1_close_completion(struct async_req *req)
     /* [<][>][^][v][top][bottom][index][help] */
5088 {
5089         NTSTATUS status;
5090 
5091         status = cli_close_recv(req);
5092         *((bool *)(req->async.priv)) = true;
5093 
5094         TALLOC_FREE(req);
5095 
5096         d_printf("cli_close returned %s\n", nt_errstr(status));
5097 }
5098 
5099 static bool run_chain1(int dummy)
     /* [<][>][^][v][top][bottom][index][help] */
5100 {
5101         struct cli_state *cli1;
5102         struct event_context *evt = event_context_init(NULL);
5103         struct async_req *reqs[4];
5104         bool done = false;
5105         const char *text = "hallo";
5106 
5107         printf("starting chain1 test\n");
5108         if (!torture_open_connection(&cli1, 0)) {
5109                 return False;
5110         }
5111 
5112         cli_sockopt(cli1, sockops);
5113 
5114         cli_chain_cork(cli1, evt, 0);
5115         reqs[0] = cli_open_send(talloc_tos(), evt, cli1, "\\test",
5116                                 O_CREAT|O_RDWR, 0);
5117         reqs[0]->async.fn = chain1_open_completion;
5118         reqs[1] = cli_write_andx_send(talloc_tos(), evt, cli1, 0, 0,
5119                                       (uint8_t *)text, 0, strlen(text));
5120         reqs[1]->async.fn = chain1_write_completion;
5121         reqs[2] = cli_read_andx_send(talloc_tos(), evt, cli1, 0, 1, 10);
5122         reqs[2]->async.fn = chain1_read_completion;
5123         reqs[3] = cli_close_send(talloc_tos(), evt, cli1, 0);
5124         reqs[3]->async.fn = chain1_close_completion;
5125         reqs[3]->async.priv = (void *)&done;
5126         cli_chain_uncork(cli1);
5127 
5128         while (!done) {
5129                 event_loop_once(evt);
5130         }
5131 
5132         torture_close_connection(cli1);
5133         return True;
5134 }
5135 
5136 static size_t null_source(uint8_t *buf, size_t n, void *priv)
     /* [<][>][^][v][top][bottom][index][help] */
5137 {
5138         size_t *to_pull = (size_t *)priv;
5139         size_t thistime = *to_pull;
5140 
5141         thistime = MIN(thistime, n);
5142         if (thistime == 0) {
5143                 return 0;
5144         }
5145 
5146         memset(buf, 0, thistime);
5147         *to_pull -= thistime;
5148         return thistime;
5149 }
5150 
5151 static bool run_windows_write(int dummy)
     /* [<][>][^][v][top][bottom][index][help] */
5152 {
5153         struct cli_state *cli1;
5154         int fnum;
5155         int i;
5156         bool ret = false;
5157         const char *fname = "\\writetest.txt";
5158         double seconds;
5159         double kbytes;
5160 
5161         printf("starting windows_write test\n");
5162         if (!torture_open_connection(&cli1, 0)) {
5163                 return False;
5164         }
5165 
5166         fnum = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
5167         if (fnum == -1) {
5168                 printf("open failed (%s)\n", cli_errstr(cli1));
5169                 return False;
5170         }
5171 
5172         cli_sockopt(cli1, sockops);
5173 
5174         start_timer();
5175 
5176         for (i=0; i<torture_numops; i++) {
5177                 char c = 0;
5178                 off_t start = i * torture_blocksize;
5179                 NTSTATUS status;
5180                 size_t to_pull = torture_blocksize - 1;
5181 
5182                 if (cli_write(cli1, fnum, 0, &c,
5183                               start + torture_blocksize - 1, 1) != 1) {
5184                         printf("cli_write failed: %s\n", cli_errstr(cli1));
5185                         goto fail;
5186                 }
5187 
5188                 status = cli_push(cli1, fnum, 0, i * torture_blocksize, torture_blocksize,
5189                                   null_source, &to_pull);
5190                 if (!NT_STATUS_IS_OK(status)) {
5191                         printf("cli_push returned: %s\n", nt_errstr(status));
5192                         goto fail;
5193                 }
5194         }
5195 
5196         seconds = end_timer();
5197         kbytes = (double)torture_blocksize * torture_numops;
5198         kbytes /= 1024;
5199 
5200         printf("Wrote %d kbytes in %.2f seconds: %d kb/sec\n", (int)kbytes,
5201                (double)seconds, (int)(kbytes/seconds));
5202 
5203         ret = true;
5204  fail:
5205         cli_close(cli1, fnum);
5206         cli_unlink(cli1, fname);
5207         torture_close_connection(cli1);
5208         return ret;
5209 }
5210 
5211 static bool run_cli_echo(int dummy)
     /* [<][>][^][v][top][bottom][index][help] */
5212 {
5213         struct cli_state *cli;
5214         struct event_context *ev = event_context_init(NULL);
5215         struct async_req *req;
5216         NTSTATUS status;
5217 
5218         printf("starting cli_echo test\n");
5219         if (!torture_open_connection(&cli, 0)) {
5220                 return false;
5221         }
5222         cli_sockopt(cli, sockops);
5223 
5224         req = cli_echo_send(ev, ev, cli, 5, data_blob_const("hello", 5));
5225         if (req == NULL) {
5226                 d_printf("cli_echo_send failed\n");
5227                 return false;
5228         }
5229 
5230         while (req->state < ASYNC_REQ_DONE) {
5231                 event_loop_once(ev);
5232         }
5233 
5234         status = cli_echo_recv(req);
5235         d_printf("cli_echo returned %s\n", nt_errstr(status));
5236 
5237         TALLOC_FREE(req);
5238 
5239         torture_close_connection(cli);
5240         return NT_STATUS_IS_OK(status);
5241 }
5242 
5243 static bool run_uid_regression_test(int dummy)
     /* [<][>][^][v][top][bottom][index][help] */
5244 {
5245         static struct cli_state *cli;
5246         int16_t old_vuid;
5247         bool correct = True;
5248 
5249         printf("starting uid regression test\n");
5250 
5251         if (!torture_open_connection(&cli, 0)) {
5252                 return False;
5253         }
5254 
5255         cli_sockopt(cli, sockops);
5256 
5257         /* Ok - now save then logoff our current user. */
5258         old_vuid = cli->vuid;
5259 
5260         if (!cli_ulogoff(cli)) {
5261                 d_printf("(%s) cli_ulogoff failed: %s\n",
5262                         __location__, cli_errstr(cli));
5263                 correct = false;
5264                 goto out;
5265         }
5266 
5267         cli->vuid = old_vuid;
5268 
5269         /* Try an operation. */
5270         if (!cli_mkdir(cli, "\\uid_reg_test")) {
5271                 /* We expect bad uid. */
5272                 if (!check_error(__LINE__, cli, ERRSRV, ERRbaduid,
5273                                 NT_STATUS_NO_SUCH_USER)) {
5274                         return False;
5275                 }
5276                 goto out;
5277         }
5278 
5279         cli_rmdir(cli, "\\uid_reg_test");
5280 
5281   out:
5282 
5283         torture_close_connection(cli);
5284         return correct;
5285 }
5286 
5287 
5288 static const char *illegal_chars = "*\\/?<>|\":";
5289 static char force_shortname_chars[] = " +,.[];=\177";
5290 
5291 static void shortname_del_fn(const char *mnt, file_info *finfo, const char *mask, void *state)
     /* [<][>][^][v][top][bottom][index][help] */
5292 {
5293         struct cli_state *pcli = (struct cli_state *)state;
5294         fstring fname;
5295         slprintf(fname, sizeof(fname), "\\shortname\\%s", finfo->name);
5296 
5297         if (strcmp(finfo->name, ".") == 0 || strcmp(finfo->name, "..") == 0)
5298                 return;
5299 
5300         if (finfo->mode & aDIR) {
5301                 if (!cli_rmdir(pcli, fname))
5302                         printf("del_fn: failed to rmdir %s\n,", fname );
5303         } else {
5304                 if (!cli_unlink(pcli, fname))
5305                         printf("del_fn: failed to unlink %s\n,", fname );
5306         }
5307 }
5308 
5309 struct sn_state {
5310         int i;
5311         bool val;
5312 };
5313 
5314 static void shortname_list_fn(const char *mnt, file_info *finfo, const char *name, void *state)
     /* [<][>][^][v][top][bottom][index][help] */
5315 {
5316         struct sn_state *s = (struct sn_state  *)state;
5317         int i = s->i;
5318 
5319 #if 0
5320         printf("shortname list: i = %d, name = |%s|, shortname = |%s|\n",
5321                 i, finfo->name, finfo->short_name);
5322 #endif
5323 
5324         if (strchr(force_shortname_chars, i)) {
5325                 if (!finfo->short_name[0]) {
5326                         /* Shortname not created when it should be. */
5327                         d_printf("(%s) ERROR: Shortname was not created for file %s containing %d\n",
5328                                 __location__, finfo->name, i);
5329                         s->val = true;
5330                 }
5331         } else if (finfo->short_name[0]){
5332                 /* Shortname created when it should not be. */
5333                 d_printf("(%s) ERROR: Shortname %s was created for file %s\n",
5334                         __location__, finfo->short_name, finfo->name);
5335                 s->val = true;
5336         }
5337 }
5338 
5339 static bool run_shortname_test(int dummy)
     /* [<][>][^][v][top][bottom][index][help] */
5340 {
5341         static struct cli_state *cli;
5342         bool correct = True;
5343         int i;
5344         struct sn_state s;
5345         char fname[20];
5346 
5347         printf("starting shortname test\n");
5348 
5349         if (!torture_open_connection(&cli, 0)) {
5350                 return False;
5351         }
5352 
5353         cli_sockopt(cli, sockops);
5354 
5355         cli_list(cli, "\\shortname\\*", 0, shortname_del_fn, cli);
5356         cli_list(cli, "\\shortname\\*", aDIR, shortname_del_fn, cli);
5357         cli_rmdir(cli, "\\shortname");
5358 
5359         if (!cli_mkdir(cli, "\\shortname")) {
5360                 d_printf("(%s) cli_mkdir of \\shortname failed: %s\n",
5361                         __location__, cli_errstr(cli));
5362                 correct = false;
5363                 goto out;
5364         }
5365 
5366         strlcpy(fname, "\\shortname\\", sizeof(fname));
5367         strlcat(fname, "test .txt", sizeof(fname));
5368 
5369         s.val = false;
5370 
5371         for (i = 32; i < 128; i++) {
5372                 int fnum = -1;
5373 
5374                 s.i = i;
5375 
5376                 if (strchr(illegal_chars, i)) {
5377                         continue;
5378                 }
5379                 fname[15] = i;
5380                 fnum = cli_nt_create_full(cli, fname, 0, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_NORMAL,
5381                                    FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0);
5382                 if (fnum == -1) {
5383                         d_printf("(%s) cli_nt_create of %s failed: %s\n",
5384                                 __location__, fname, cli_errstr(cli));
5385                         correct = false;
5386                         goto out;
5387                 }
5388                 cli_close(cli, fnum);
5389                 if (cli_list(cli, "\\shortname\\test*.*", 0, shortname_list_fn, &s) != 1) {
5390                         d_printf("(%s) failed to list %s: %s\n",
5391                                 __location__, fname, cli_errstr(cli));
5392                         correct = false;
5393                         goto out;
5394                 }
5395                 if (!cli_unlink(cli, fname)) {
5396                         d_printf("(%s) failed to delete %s: %s\n",
5397                                 __location__, fname, cli_errstr(cli));
5398                         correct = false;
5399                         goto out;
5400                 }
5401 
5402                 if (s.val) {
5403                         correct = false;
5404                         goto out;
5405                 }
5406         }
5407 
5408   out:
5409 
5410         cli_list(cli, "\\shortname\\*", 0, shortname_del_fn, cli);
5411         cli_list(cli, "\\shortname\\*", aDIR, shortname_del_fn, cli);
5412         cli_rmdir(cli, "\\shortname");
5413         torture_close_connection(cli);
5414         return correct;
5415 }
5416 
5417 static bool run_local_substitute(int dummy)
     /* [<][>][^][v][top][bottom][index][help] */
5418 {
5419         bool ok = true;
5420 
5421         ok &= subst_test("%U", "bla", "", -1, -1, "bla");
5422         ok &= subst_test("%u%U", "bla", "", -1, -1, "blabla");
5423         ok &= subst_test("%g", "", "", -1, -1, "NO_GROUP");
5424         ok &= subst_test("%G", "", "", -1, -1, "NO_GROUP");
5425         ok &= subst_test("%g", "", "", -1, 0, gidtoname(0));
5426         ok &= subst_test("%G", "", "", -1, 0, gidtoname(0));
5427         ok &= subst_test("%D%u", "u", "dom", -1, 0, "domu");
5428         ok &= subst_test("%i %I", "", "", -1, -1, "0.0.0.0 0.0.0.0");
5429 
5430         /* Different captialization rules in sub_basic... */
5431 
5432         ok &=  (strcmp(talloc_sub_basic(talloc_tos(), "BLA", "dom", "%U%D"),
5433                        "blaDOM") == 0);
5434 
5435         return ok;
5436 }
5437 
5438 static bool run_local_gencache(int dummy)
     /* [<][>][^][v][top][bottom][index][help] */
5439 {
5440         char *val;
5441         time_t tm;
5442         DATA_BLOB blob;
5443 
5444         if (!gencache_init()) {
5445                 d_printf("%s: gencache_init() failed\n", __location__);
5446                 return False;
5447         }
5448 
5449         if (!gencache_set("foo", "bar", time(NULL) + 1000)) {
5450                 d_printf("%s: gencache_set() failed\n", __location__);
5451                 return False;
5452         }
5453 
5454         if (!gencache_get("foo", &val, &tm)) {
5455                 d_printf("%s: gencache_get() failed\n", __location__);
5456                 return False;
5457         }
5458 
5459         if (strcmp(val, "bar") != 0) {
5460                 d_printf("%s: gencache_get() returned %s, expected %s\n",
5461                          __location__, val, "bar");
5462                 SAFE_FREE(val);
5463                 return False;
5464         }
5465 
5466         SAFE_FREE(val);
5467 
5468         if (!gencache_del("foo")) {
5469                 d_printf("%s: gencache_del() failed\n", __location__);
5470                 return False;
5471         }
5472         if (gencache_del("foo")) {
5473                 d_printf("%s: second gencache_del() succeeded\n",
5474                          __location__);
5475                 return False;
5476         }
5477                         
5478         if (gencache_get("foo", &val, &tm)) {
5479                 d_printf("%s: gencache_get() on deleted entry "
5480                          "succeeded\n", __location__);
5481                 return False;
5482         }
5483 
5484         blob = data_blob_string_const_null("bar");
5485         tm = time(NULL);
5486 
5487         if (!gencache_set_data_blob("foo", &blob, tm)) {
5488                 d_printf("%s: gencache_set_data_blob() failed\n", __location__);
5489                 return False;
5490         }
5491 
5492         data_blob_free(&blob);
5493 
5494         if (!gencache_get_data_blob("foo", &blob, NULL)) {
5495                 d_printf("%s: gencache_get_data_blob() failed\n", __location__);
5496                 return False;
5497         }
5498 
5499         if (strcmp((const char *)blob.data, "bar") != 0) {
5500                 d_printf("%s: gencache_get_data_blob() returned %s, expected %s\n",
5501                          __location__, (const char *)blob.data, "bar");
5502                 data_blob_free(&blob);
5503                 return False;
5504         }
5505 
5506         data_blob_free(&blob);
5507 
5508         if (!gencache_del("foo")) {
5509                 d_printf("%s: gencache_del() failed\n", __location__);
5510                 return False;
5511         }
5512         if (gencache_del("foo")) {
5513                 d_printf("%s: second gencache_del() succeeded\n",
5514                          __location__);
5515                 return False;
5516         }
5517 
5518         if (gencache_get_data_blob("foo", &blob, NULL)) {
5519                 d_printf("%s: gencache_get_data_blob() on deleted entry "
5520                          "succeeded\n", __location__);
5521                 return False;
5522         }
5523 
5524         if (!gencache_shutdown()) {
5525                 d_printf("%s: gencache_shutdown() failed\n", __location__);
5526                 return False;
5527         }
5528 
5529         if (gencache_shutdown()) {
5530                 d_printf("%s: second gencache_shutdown() succeeded\n",
5531                          __location__);
5532                 return False;
5533         }
5534 
5535         return True;
5536 }
5537 
5538 static bool rbt_testval(struct db_context *db, const char *key,
     /* [<][>][^][v][top][bottom][index][help] */
5539                         const char *value)
5540 {
5541         struct db_record *rec;
5542         TDB_DATA data = string_tdb_data(value);
5543         bool ret = false;
5544         NTSTATUS status;
5545 
5546         rec = db->fetch_locked(db, db, string_tdb_data(key));
5547         if (rec == NULL) {
5548                 d_fprintf(stderr, "fetch_locked failed\n");
5549                 goto done;
5550         }
5551         status = rec->store(rec, data, 0);
5552         if (!NT_STATUS_IS_OK(status)) {
5553                 d_fprintf(stderr, "store failed: %s\n", nt_errstr(status));
5554                 goto done;
5555         }
5556         TALLOC_FREE(rec);
5557 
5558         rec = db->fetch_locked(db, db, string_tdb_data(key));
5559         if (rec == NULL) {
5560                 d_fprintf(stderr, "second fetch_locked failed\n");
5561                 goto done;
5562         }
5563         if ((rec->value.dsize != data.dsize)
5564             || (memcmp(rec->value.dptr, data.dptr, data.dsize) != 0)) {
5565                 d_fprintf(stderr, "Got wrong data back\n");
5566                 goto done;
5567         }
5568 
5569         ret = true;
5570  done:
5571         TALLOC_FREE(rec);
5572         return ret;
5573 }
5574 
5575 static bool run_local_rbtree(int dummy)
     /* [<][>][^][v][top][bottom][index][help] */
5576 {
5577         struct db_context *db;
5578         bool ret = false;
5579         int i;
5580 
5581         db = db_open_rbt(NULL);
5582 
5583         if (db == NULL) {
5584                 d_fprintf(stderr, "db_open_rbt failed\n");
5585                 return false;
5586         }
5587 
5588         for (i=0; i<1000; i++) {
5589                 char *key, *value;
5590 
5591                 if (asprintf(&key, "key%ld", random()) == -1) {
5592                         goto done;
5593                 }
5594                 if (asprintf(&value, "value%ld", random()) == -1) {
5595                         SAFE_FREE(key);
5596                         goto done;
5597                 }
5598 
5599                 if (!rbt_testval(db, key, value)) {
5600                         SAFE_FREE(key);
5601                         SAFE_FREE(value);
5602                         goto done;
5603                 }
5604 
5605                 SAFE_FREE(value);
5606                 if (asprintf(&value, "value%ld", random()) == -1) {
5607                         SAFE_FREE(key);
5608                         goto done;
5609                 }
5610 
5611                 if (!rbt_testval(db, key, value)) {
5612                         SAFE_FREE(key);
5613                         SAFE_FREE(value);
5614                         goto done;
5615                 }
5616 
5617                 SAFE_FREE(key);
5618                 SAFE_FREE(value);
5619         }
5620 
5621         ret = true;
5622 
5623  done:
5624         TALLOC_FREE(db);
5625         return ret;
5626 }
5627 
5628 static bool test_stream_name(const char *fname, const char *expected_base,
     /* [<][>][^][v][top][bottom][index][help] */
5629                              const char *expected_stream,
5630                              NTSTATUS expected_status)
5631 {
5632         NTSTATUS status;
5633         char *base = NULL;
5634         char *stream = NULL;
5635 
5636         status = split_ntfs_stream_name(talloc_tos(), fname, &base, &stream);
5637         if (!NT_STATUS_EQUAL(status, expected_status)) {
5638                 goto error;
5639         }
5640 
5641         if (!NT_STATUS_IS_OK(status)) {
5642                 return true;
5643         }
5644 
5645         if (base == NULL) goto error;
5646 
5647         if (strcmp(expected_base, base) != 0) goto error;
5648 
5649         if ((expected_stream != NULL) && (stream == NULL)) goto error;
5650         if ((expected_stream == NULL) && (stream != NULL)) goto error;
5651 
5652         if ((stream != NULL) && (strcmp(expected_stream, stream) != 0))
5653                 goto error;
5654 
5655         TALLOC_FREE(base);
5656         TALLOC_FREE(stream);
5657         return true;
5658 
5659  error:
5660         d_fprintf(stderr, "test_stream(%s, %s, %s, %s)\n",
5661                   fname, expected_base ? expected_base : "<NULL>",
5662                   expected_stream ? expected_stream : "<NULL>",
5663                   nt_errstr(expected_status));
5664         d_fprintf(stderr, "-> base=%s, stream=%s, status=%s\n",
5665                   base ? base : "<NULL>", stream ? stream : "<NULL>",
5666                   nt_errstr(status));
5667         TALLOC_FREE(base);
5668         TALLOC_FREE(stream);
5669         return false;
5670 }
5671 
5672 static bool run_local_stream_name(int dummy)
     /* [<][>][^][v][top][bottom][index][help] */
5673 {
5674         bool ret = true;
5675 
5676         ret &= test_stream_name(
5677                 "bla", "bla", NULL, NT_STATUS_OK);
5678         ret &= test_stream_name(
5679                 "bla::$DATA", "bla", NULL, NT_STATUS_OK);
5680         ret &= test_stream_name(
5681                 "bla:blub:", "bla", NULL, NT_STATUS_OBJECT_NAME_INVALID);
5682         ret &= test_stream_name(
5683                 "bla::", NULL, NULL, NT_STATUS_OBJECT_NAME_INVALID);
5684         ret &= test_stream_name(
5685                 "bla::123", "bla", NULL, NT_STATUS_OBJECT_NAME_INVALID);
5686         ret &= test_stream_name(
5687                 "bla:$DATA", "bla", "$DATA:$DATA", NT_STATUS_OK);
5688         ret &= test_stream_name(
5689                 "bla:x:$DATA", "bla", "x:$DATA", NT_STATUS_OK);
5690         ret &= test_stream_name(
5691                 "bla:x", "bla", "x:$DATA", NT_STATUS_OK);
5692 
5693         return ret;
5694 }
5695 
5696 static bool data_blob_equal(DATA_BLOB a, DATA_BLOB b)
     /* [<][>][^][v][top][bottom][index][help] */
5697 {
5698         if (a.length != b.length) {
5699                 printf("a.length=%d != b.length=%d\n",
5700                        (int)a.length, (int)b.length);
5701                 return false;
5702         }
5703         if (memcmp(a.data, b.data, a.length) != 0) {
5704                 printf("a.data and b.data differ\n");
5705                 return false;
5706         }
5707         return true;
5708 }
5709 
5710 static bool run_local_memcache(int dummy)
     /* [<][>][^][v][top][bottom][index][help] */
5711 {
5712         struct memcache *cache;
5713         DATA_BLOB k1, k2;
5714         DATA_BLOB d1, d2, d3;
5715         DATA_BLOB v1, v2, v3;
5716 
5717         TALLOC_CTX *mem_ctx;
5718         char *str1, *str2;
5719         size_t size1, size2;
5720         bool ret = false;
5721 
5722         cache = memcache_init(NULL, 100);
5723 
5724         if (cache == NULL) {
5725                 printf("memcache_init failed\n");
5726                 return false;
5727         }
5728 
5729         d1 = data_blob_const("d1", 2);
5730         d2 = data_blob_const("d2", 2);
5731         d3 = data_blob_const("d3", 2);
5732 
5733         k1 = data_blob_const("d1", 2);
5734         k2 = data_blob_const("d2", 2);
5735 
5736         memcache_add(cache, STAT_CACHE, k1, d1);
5737         memcache_add(cache, GETWD_CACHE, k2, d2);
5738 
5739         if (!memcache_lookup(cache, STAT_CACHE, k1, &v1)) {
5740                 printf("could not find k1\n");
5741                 return false;
5742         }
5743         if (!data_blob_equal(d1, v1)) {
5744                 return false;
5745         }
5746 
5747         if (!memcache_lookup(cache, GETWD_CACHE, k2, &v2)) {
5748                 printf("could not find k2\n");
5749                 return false;
5750         }
5751         if (!data_blob_equal(d2, v2)) {
5752                 return false;
5753         }
5754 
5755         memcache_add(cache, STAT_CACHE, k1, d3);
5756 
5757         if (!memcache_lookup(cache, STAT_CACHE, k1, &v3)) {
5758                 printf("could not find replaced k1\n");
5759                 return false;
5760         }
5761         if (!data_blob_equal(d3, v3)) {
5762                 return false;
5763         }
5764 
5765         memcache_add(cache, GETWD_CACHE, k1, d1);
5766 
5767         if (memcache_lookup(cache, GETWD_CACHE, k2, &v2)) {
5768                 printf("Did find k2, should have been purged\n");
5769                 return false;
5770         }
5771 
5772         TALLOC_FREE(cache);
5773 
5774         cache = memcache_init(NULL, 0);
5775 
5776         mem_ctx = talloc_init("foo");
5777 
5778         str1 = talloc_strdup(mem_ctx, "string1");
5779         str2 = talloc_strdup(mem_ctx, "string2");
5780 
5781         memcache_add_talloc(cache, SINGLETON_CACHE_TALLOC,
5782                             data_blob_string_const("torture"), &str1);
5783         size1 = talloc_total_size(cache);
5784 
5785         memcache_add_talloc(cache, SINGLETON_CACHE_TALLOC,
5786                             data_blob_string_const("torture"), &str2);
5787         size2 = talloc_total_size(cache);
5788 
5789         printf("size1=%d, size2=%d\n", (int)size1, (int)size2);
5790 
5791         if (size2 > size1) {
5792                 printf("memcache leaks memory!\n");
5793                 goto fail;
5794         }
5795 
5796         ret = true;
5797  fail:
5798         TALLOC_FREE(cache);
5799         return ret;
5800 }
5801 
5802 static void wbclient_done(struct tevent_req *req)
     /* [<][>][^][v][top][bottom][index][help] */
5803 {
5804         wbcErr wbc_err;
5805         struct winbindd_response *wb_resp;
5806         int *i = (int *)tevent_req_callback_data_void(req);
5807 
5808         wbc_err = wb_trans_recv(req, req, &wb_resp);
5809         TALLOC_FREE(req);
5810         *i += 1;
5811         d_printf("wb_trans_recv %d returned %s\n", *i, wbcErrorString(wbc_err));
5812 }
5813 
5814 static bool run_local_wbclient(int dummy)
     /* [<][>][^][v][top][bottom][index][help] */
5815 {
5816         struct event_context *ev;
5817         struct wb_context **wb_ctx;
5818         struct winbindd_request wb_req;
5819         bool result = false;
5820         int i, j;
5821 
5822         BlockSignals(True, SIGPIPE);
5823 
5824         ev = event_context_init(talloc_tos());
5825         if (ev == NULL) {
5826                 goto fail;
5827         }
5828 
5829         wb_ctx = TALLOC_ARRAY(ev, struct wb_context *, torture_numops);
5830         if (wb_ctx == NULL) {
5831                 goto fail;
5832         }
5833 
5834         ZERO_STRUCT(wb_req);
5835         wb_req.cmd = WINBINDD_PING;
5836 
5837         for (i=0; i<torture_numops; i++) {
5838                 wb_ctx[i] = wb_context_init(ev);
5839                 if (wb_ctx[i] == NULL) {
5840                         goto fail;
5841                 }
5842                 for (j=0; j<5; j++) {
5843                         struct tevent_req *req;
5844                         req = wb_trans_send(ev, ev, wb_ctx[i],
5845                                             (j % 2) == 0, &wb_req);
5846                         if (req == NULL) {
5847                                 goto fail;
5848                         }
5849                         tevent_req_set_callback(req, wbclient_done, &i);
5850                 }
5851         }
5852 
5853         i = 0;
5854 
5855         while (i < 5 * torture_numops) {
5856                 event_loop_once(ev);
5857         }
5858 
5859         result = true;
5860  fail:
5861         TALLOC_FREE(ev);
5862         return result;
5863 }
5864 
5865 static double create_procs(bool (*fn)(int), bool *result)
     /* [<][>][^][v][top][bottom][index][help] */
5866 {
5867         int i, status;
5868         volatile pid_t *child_status;
5869         volatile bool *child_status_out;
5870         int synccount;
5871         int tries = 8;
5872 
5873         synccount = 0;
5874 
5875         child_status = (volatile pid_t *)shm_setup(sizeof(pid_t)*nprocs);
5876         if (!child_status) {
5877                 printf("Failed to setup shared memory\n");
5878                 return -1;
5879         }
5880 
5881         child_status_out = (volatile bool *)shm_setup(sizeof(bool)*nprocs);
5882         if (!child_status_out) {
5883                 printf("Failed to setup result status shared memory\n");
5884                 return -1;
5885         }
5886 
5887         for (i = 0; i < nprocs; i++) {
5888                 child_status[i] = 0;
5889                 child_status_out[i] = True;
5890         }
5891 
5892         start_timer();
5893 
5894         for (i=0;i<nprocs;i++) {
5895                 procnum = i;
5896                 if (fork() == 0) {
5897                         pid_t mypid = getpid();
5898                         sys_srandom(((int)mypid) ^ ((int)time(NULL)));
5899 
5900                         slprintf(myname,sizeof(myname),"CLIENT%d", i);
5901 
5902                         while (1) {
5903                                 if (torture_open_connection(&current_cli, i)) break;
5904                                 if (tries-- == 0) {
5905                                         printf("pid %d failed to start\n", (int)getpid());
5906                                         _exit(1);
5907                                 }
5908                                 smb_msleep(10); 
5909                         }
5910 
5911                         child_status[i] = getpid();
5912 
5913                         while (child_status[i] && end_timer() < 5) smb_msleep(2);
5914 
5915                         child_status_out[i] = fn(i);
5916                         _exit(0);
5917                 }
5918         }
5919 
5920         do {
5921                 synccount = 0;
5922                 for (i=0;i<nprocs;i++) {
5923                         if (child_status[i]) synccount++;
5924                 }
5925                 if (synccount == nprocs) break;
5926                 smb_msleep(10);
5927         } while (end_timer() < 30);
5928 
5929         if (synccount != nprocs) {
5930                 printf("FAILED TO START %d CLIENTS (started %d)\n", nprocs, synccount);
5931                 *result = False;
5932                 return end_timer();
5933         }
5934 
5935         /* start the client load */
5936         start_timer();
5937 
5938         for (i=0;i<nprocs;i++) {
5939                 child_status[i] = 0;
5940         }
5941 
5942         printf("%d clients started\n", nprocs);
5943 
5944         for (i=0;i<nprocs;i++) {
5945                 while (waitpid(0, &status, 0) == -1 && errno == EINTR) /* noop */ ;
5946         }
5947 
5948         printf("\n");
5949         
5950         for (i=0;i<nprocs;i++) {
5951                 if (!child_status_out[i]) {
5952                         *result = False;
5953                 }
5954         }
5955         return end_timer();
5956 }
5957 
5958 #define FLAG_MULTIPROC 1
5959 
5960 static struct {
5961         const char *name;
5962         bool (*fn)(int);
5963         unsigned flags;
5964 } torture_ops[] = {
5965         {"FDPASS", run_fdpasstest, 0},
5966         {"LOCK1",  run_locktest1,  0},
5967         {"LOCK2",  run_locktest2,  0},
5968         {"LOCK3",  run_locktest3,  0},
5969         {"LOCK4",  run_locktest4,  0},
5970         {"LOCK5",  run_locktest5,  0},
5971         {"LOCK6",  run_locktest6,  0},
5972         {"LOCK7",  run_locktest7,  0},
5973         {"UNLINK", run_unlinktest, 0},
5974         {"BROWSE", run_browsetest, 0},
5975         {"ATTR",   run_attrtest,   0},
5976         {"TRANS2", run_trans2test, 0},
5977         {"MAXFID", run_maxfidtest, FLAG_MULTIPROC},
5978         {"TORTURE",run_torture,    FLAG_MULTIPROC},
5979         {"RANDOMIPC", run_randomipc, 0},
5980         {"NEGNOWAIT", run_negprot_nowait, 0},
5981         {"NBENCH",  run_nbench, 0},
5982         {"OPLOCK1",  run_oplock1, 0},
5983         {"OPLOCK2",  run_oplock2, 0},
5984         {"OPLOCK3",  run_oplock3, 0},
5985         {"DIR",  run_dirtest, 0},
5986         {"DIR1",  run_dirtest1, 0},
5987         {"DENY1",  torture_denytest1, 0},
5988         {"DENY2",  torture_denytest2, 0},
5989         {"TCON",  run_tcon_test, 0},
5990         {"TCONDEV",  run_tcon_devtype_test, 0},
5991         {"RW1",  run_readwritetest, 0},
5992         {"RW2",  run_readwritemulti, FLAG_MULTIPROC},
5993         {"RW3",  run_readwritelarge, 0},
5994         {"OPEN", run_opentest, 0},
5995         {"POSIX", run_simple_posix_open_test, 0},
5996         { "UID-REGRESSION-TEST", run_uid_regression_test, 0},
5997         { "SHORTNAME-TEST", run_shortname_test, 0},
5998 #if 1
5999         {"OPENATTR", run_openattrtest, 0},
6000 #endif
6001         {"XCOPY", run_xcopy, 0},
6002         {"RENAME", run_rename, 0},
6003         {"DELETE", run_deletetest, 0},
6004         {"PROPERTIES", run_properties, 0},
6005         {"MANGLE", torture_mangle, 0},
6006         {"W2K", run_w2ktest, 0},
6007         {"TRANS2SCAN", torture_trans2_scan, 0},
6008         {"NTTRANSSCAN", torture_nttrans_scan, 0},
6009         {"UTABLE", torture_utable, 0},
6010         {"CASETABLE", torture_casetable, 0},
6011         {"ERRMAPEXTRACT", run_error_map_extract, 0},
6012         {"PIPE_NUMBER", run_pipe_number, 0},
6013         {"TCON2",  run_tcon2_test, 0},
6014         {"IOCTL",  torture_ioctl_test, 0},
6015         {"CHKPATH",  torture_chkpath_test, 0},
6016         {"FDSESS", run_fdsesstest, 0},
6017         { "EATEST", run_eatest, 0},
6018         { "SESSSETUP_BENCH", run_sesssetup_bench, 0},
6019         { "CHAIN1", run_chain1, 0},
6020         { "WINDOWS-WRITE", run_windows_write, 0},
6021         { "CLI_ECHO", run_cli_echo, 0},
6022         { "LOCAL-SUBSTITUTE", run_local_substitute, 0},
6023         { "LOCAL-GENCACHE", run_local_gencache, 0},
6024         { "LOCAL-RBTREE", run_local_rbtree, 0},
6025         { "LOCAL-MEMCACHE", run_local_memcache, 0},
6026         { "LOCAL-STREAM-NAME", run_local_stream_name, 0},
6027         { "LOCAL-WBCLIENT", run_local_wbclient, 0},
6028         {NULL, NULL, 0}};
6029 
6030 
6031 
6032 /****************************************************************************
6033 run a specified test or "ALL"
6034 ****************************************************************************/
6035 static bool run_test(const char *name)
     /* [<][>][^][v][top][bottom][index][help] */
6036 {
6037         bool ret = True;
6038         bool result = True;
6039         bool found = False;
6040         int i;
6041         double t;
6042         if (strequal(name,"ALL")) {
6043                 for (i=0;torture_ops[i].name;i++) {
6044                         run_test(torture_ops[i].name);
6045                 }
6046                 found = True;
6047         }
6048         
6049         for (i=0;torture_ops[i].name;i++) {
6050                 fstr_sprintf(randomfname, "\\XX%x", 
6051                          (unsigned)random());
6052 
6053                 if (strequal(name, torture_ops[i].name)) {
6054                         found = True;
6055                         printf("Running %s\n", name);
6056                         if (torture_ops[i].flags & FLAG_MULTIPROC) {
6057                                 t = create_procs(torture_ops[i].fn, &result);
6058                                 if (!result) { 
6059                                         ret = False;
6060                                         printf("TEST %s FAILED!\n", name);
6061                                 }
6062                                          
6063                         } else {
6064                                 start_timer();
6065                                 if (!torture_ops[i].fn(0)) {
6066                                         ret = False;
6067                                         printf("TEST %s FAILED!\n", name);
6068                                 }
6069                                 t = end_timer();
6070                         }
6071                         printf("%s took %g secs\n\n", name, t);
6072                 }
6073         }
6074 
6075         if (!found) {
6076                 printf("Did not find a test named %s\n", name);
6077                 ret = False;
6078         }
6079 
6080         return ret;
6081 }
6082 
6083 
6084 static void usage(void)
     /* [<][>][^][v][top][bottom][index][help] */
6085 {
6086         int i;
6087 
6088         printf("WARNING samba4 test suite is much more complete nowadays.\n");
6089         printf("Please use samba4 torture.\n\n");
6090 
6091         printf("Usage: smbtorture //server/share <options> TEST1 TEST2 ...\n");
6092 
6093         printf("\t-d debuglevel\n");
6094         printf("\t-U user%%pass\n");
6095         printf("\t-k               use kerberos\n");
6096         printf("\t-N numprocs\n");
6097         printf("\t-n my_netbios_name\n");
6098         printf("\t-W workgroup\n");
6099         printf("\t-o num_operations\n");
6100         printf("\t-O socket_options\n");
6101         printf("\t-m maximum protocol\n");
6102         printf("\t-L use oplocks\n");
6103         printf("\t-c CLIENT.TXT   specify client load file for NBENCH\n");
6104         printf("\t-A showall\n");
6105         printf("\t-p port\n");
6106         printf("\t-s seed\n");
6107         printf("\t-b unclist_filename   specify multiple shares for multiple connections\n");
6108         printf("\n\n");
6109 
6110         printf("tests are:");
6111         for (i=0;torture_ops[i].name;i++) {
6112                 printf(" %s", torture_ops[i].name);
6113         }
6114         printf("\n");
6115 
6116         printf("default test is ALL\n");
6117         
6118         exit(1);
6119 }
6120 
6121 /****************************************************************************
6122   main program
6123 ****************************************************************************/
6124  int main(int argc,char *argv[])
     /* [<][>][^][v][top][bottom][index][help] */
6125 {
6126         int opt, i;
6127         char *p;
6128         int gotuser = 0;
6129         int gotpass = 0;
6130         bool correct = True;
6131         TALLOC_CTX *frame = talloc_stackframe();
6132         int seed = time(NULL);
6133 
6134         dbf = x_stdout;
6135 
6136 #ifdef HAVE_SETBUFFER
6137         setbuffer(stdout, NULL, 0);
6138 #endif
6139 
6140         load_case_tables();
6141 
6142         if (is_default_dyn_CONFIGFILE()) {
6143                 if(getenv("SMB_CONF_PATH")) {
6144                         set_dyn_CONFIGFILE(getenv("SMB_CONF_PATH"));
6145                 }
6146         }
6147         lp_load(get_dyn_CONFIGFILE(),True,False,False,True);
6148         load_interfaces();
6149 
6150         if (argc < 2) {
6151                 usage();
6152         }
6153 
6154         for(p = argv[1]; *p; p++)
6155           if(*p == '\\')
6156             *p = '/';
6157  
6158         if (strncmp(argv[1], "//", 2)) {
6159                 usage();
6160         }
6161 
6162         fstrcpy(host, &argv[1][2]);
6163         p = strchr_m(&host[2],'/');
6164         if (!p) {
6165                 usage();
6166         }
6167         *p = 0;
6168         fstrcpy(share, p+1);
6169 
6170         fstrcpy(myname, get_myname(talloc_tos()));
6171         if (!*myname) {
6172                 fprintf(stderr, "Failed to get my hostname.\n");
6173                 return 1;
6174         }
6175 
6176         if (*username == 0 && getenv("LOGNAME")) {
6177           fstrcpy(username,getenv("LOGNAME"));
6178         }
6179 
6180         argc--;
6181         argv++;
6182 
6183         fstrcpy(workgroup, lp_workgroup());
6184 
6185         while ((opt = getopt(argc, argv, "p:hW:U:n:N:O:o:m:Ld:Aec:ks:b:B:")) != EOF) {
6186                 switch (opt) {
6187                 case 'p':
6188                         port_to_use = atoi(optarg);
6189                         break;
6190                 case 's':
6191                         seed = atoi(optarg);
6192                         break;
6193                 case 'W':
6194                         fstrcpy(workgroup,optarg);
6195                         break;
6196                 case 'm':
6197                         max_protocol = interpret_protocol(optarg, max_protocol);
6198                         break;
6199                 case 'N':
6200                         nprocs = atoi(optarg);
6201                         break;
6202                 case 'o':
6203                         torture_numops = atoi(optarg);
6204                         break;
6205                 case 'd':
6206                         DEBUGLEVEL = atoi(optarg);
6207                         break;
6208                 case 'O':
6209                         sockops = optarg;
6210                         break;
6211                 case 'L':
6212                         use_oplocks = True;
6213                         break;
6214                 case 'A':
6215                         torture_showall = True;
6216                         break;
6217                 case 'n':
6218                         fstrcpy(myname, optarg);
6219                         break;
6220                 case 'c':
6221                         client_txt = optarg;
6222                         break;
6223                 case 'e':
6224                         do_encrypt = true;
6225                         break;
6226                 case 'k':
6227 #ifdef HAVE_KRB5
6228                         use_kerberos = True;
6229 #else
6230                         d_printf("No kerberos support compiled in\n");
6231                         exit(1);
6232 #endif
6233                         break;
6234                 case 'U':
6235                         gotuser = 1;
6236                         fstrcpy(username,optarg);
6237                         p = strchr_m(username,'%');
6238                         if (p) {
6239                                 *p = 0;
6240                                 fstrcpy(password, p+1);
6241                                 gotpass = 1;
6242                         }
6243                         break;
6244                 case 'b':
6245                         fstrcpy(multishare_conn_fname, optarg);
6246                         use_multishare_conn = True;
6247                         break;
6248                 case 'B':
6249                         torture_blocksize = atoi(optarg);
6250                         break;
6251                 default:
6252                         printf("Unknown option %c (%d)\n", (char)opt, opt);
6253                         usage();
6254                 }
6255         }
6256 
6257         d_printf("using seed %d\n", seed);
6258 
6259         srandom(seed);
6260 
6261         if(use_kerberos && !gotuser) gotpass = True;
6262 
6263         while (!gotpass) {
6264                 p = getpass("Password:");
6265                 if (p) {
6266                         fstrcpy(password, p);
6267                         gotpass = 1;
6268                 }
6269         }
6270 
6271         printf("host=%s share=%s user=%s myname=%s\n", 
6272                host, share, username, myname);
6273 
6274         if (argc == optind) {
6275                 correct = run_test("ALL");
6276         } else {
6277                 for (i=optind;i<argc;i++) {
6278                         if (!run_test(argv[i])) {
6279                                 correct = False;
6280                         }
6281                 }
6282         }
6283 
6284         TALLOC_FREE(frame);
6285 
6286         if (correct) {
6287                 return(0);
6288         } else {
6289                 return(1);
6290         }
6291 }

/* [<][>][^][v][top][bottom][index][help] */