root/source4/torture/raw/samba3misc.c

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

DEFINITIONS

This source file includes following definitions.
  1. torture_samba3_checkfsp
  2. raw_smbcli_open
  3. raw_smbcli_t2open
  4. raw_smbcli_ntcreate
  5. torture_samba3_badpath
  6. count_fn
  7. torture_samba3_caseinsensitive
  8. torture_samba3_posixtimedlock
  9. torture_samba3_rootdirfid
  10. torture_samba3_oplock_logoff

   1 /* 
   2    Unix SMB/CIFS implementation.
   3    Test some misc Samba3 code paths
   4    Copyright (C) Volker Lendecke 2006
   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 "torture/torture.h"
  22 #include "libcli/raw/libcliraw.h"
  23 #include "libcli/raw/raw_proto.h"
  24 #include "system/time.h"
  25 #include "system/filesys.h"
  26 #include "libcli/libcli.h"
  27 #include "torture/util.h"
  28 #include "lib/events/events.h"
  29 #include "param/param.h"
  30 
  31 #define CHECK_STATUS(status, correct) do { \
  32         if (!NT_STATUS_EQUAL(status, correct)) { \
  33                 printf("(%s) Incorrect status %s - should be %s\n", \
  34                        __location__, nt_errstr(status), nt_errstr(correct)); \
  35                 ret = false; \
  36         } \
  37 } while (0)
  38 
  39 bool torture_samba3_checkfsp(struct torture_context *torture)
     /* [<][>][^][v][top][bottom][index][help] */
  40 {
  41         struct smbcli_state *cli;
  42         const char *fname = "test.txt";
  43         const char *dirname = "testdir";
  44         int fnum;
  45         NTSTATUS status;
  46         bool ret = true;
  47         TALLOC_CTX *mem_ctx;
  48         ssize_t nread;
  49         char buf[16];
  50         struct smbcli_tree *tree2;
  51 
  52         if ((mem_ctx = talloc_init("torture_samba3_checkfsp")) == NULL) {
  53                 d_printf("talloc_init failed\n");
  54                 return false;
  55         }
  56 
  57         if (!torture_open_connection_share(
  58                     torture, &cli, torture, torture_setting_string(torture, "host", NULL),
  59                     torture_setting_string(torture, "share", NULL), torture->ev)) {
  60                 d_printf("torture_open_connection_share failed\n");
  61                 ret = false;
  62                 goto done;
  63         }
  64 
  65         smbcli_deltree(cli->tree, dirname);
  66 
  67         status = torture_second_tcon(torture, cli->session,
  68                                      torture_setting_string(torture, "share", NULL),
  69                                      &tree2);
  70         CHECK_STATUS(status, NT_STATUS_OK);
  71         if (!NT_STATUS_IS_OK(status))
  72                 goto done;
  73 
  74         /* Try a read on an invalid FID */
  75 
  76         nread = smbcli_read(cli->tree, 4711, buf, 0, sizeof(buf));
  77         CHECK_STATUS(smbcli_nt_error(cli->tree), NT_STATUS_INVALID_HANDLE);
  78 
  79         /* Try a read on a directory handle */
  80 
  81         status = smbcli_mkdir(cli->tree, dirname);
  82         if (!NT_STATUS_IS_OK(status)) {
  83                 d_printf("smbcli_mkdir failed: %s\n", nt_errstr(status));
  84                 ret = false;
  85                 goto done;
  86         }
  87 
  88         /* Open the directory */
  89         {
  90                 union smb_open io;
  91                 io.generic.level = RAW_OPEN_NTCREATEX;
  92                 io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED;
  93                 io.ntcreatex.in.root_fid = 0;
  94                 io.ntcreatex.in.security_flags = 0;
  95                 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
  96                 io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
  97                 io.ntcreatex.in.alloc_size = 0;
  98                 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_DIRECTORY;
  99                 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
 100                 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
 101                 io.ntcreatex.in.create_options = 0;
 102                 io.ntcreatex.in.fname = dirname;
 103                 status = smb_raw_open(cli->tree, mem_ctx, &io);
 104                 if (!NT_STATUS_IS_OK(status)) {
 105                         d_printf("smb_open on the directory failed: %s\n",
 106                                  nt_errstr(status));
 107                         ret = false;
 108                         goto done;
 109                 }
 110                 fnum = io.ntcreatex.out.file.fnum;
 111         }
 112 
 113         /* Try a read on the directory */
 114 
 115         nread = smbcli_read(cli->tree, fnum, buf, 0, sizeof(buf));
 116         if (nread >= 0) {
 117                 d_printf("smbcli_read on a directory succeeded, expected "
 118                          "failure\n");
 119                 ret = false;
 120         }
 121 
 122         CHECK_STATUS(smbcli_nt_error(cli->tree),
 123                      NT_STATUS_INVALID_DEVICE_REQUEST);
 124 
 125         /* Same test on the second tcon */
 126 
 127         nread = smbcli_read(tree2, fnum, buf, 0, sizeof(buf));
 128         if (nread >= 0) {
 129                 d_printf("smbcli_read on a directory succeeded, expected "
 130                          "failure\n");
 131                 ret = false;
 132         }
 133 
 134         CHECK_STATUS(smbcli_nt_error(tree2), NT_STATUS_INVALID_HANDLE);
 135 
 136         smbcli_close(cli->tree, fnum);
 137 
 138         /* Try a normal file read on a second tcon */
 139 
 140         fnum = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT, DENY_NONE);
 141         if (fnum == -1) {
 142                 d_printf("Failed to create %s - %s\n", fname,
 143                          smbcli_errstr(cli->tree));
 144                 ret = false;
 145                 goto done;
 146         }
 147 
 148         nread = smbcli_read(tree2, fnum, buf, 0, sizeof(buf));
 149         CHECK_STATUS(smbcli_nt_error(tree2), NT_STATUS_INVALID_HANDLE);
 150 
 151         smbcli_close(cli->tree, fnum);
 152 
 153  done:
 154         smbcli_deltree(cli->tree, dirname);
 155         torture_close_connection(cli);
 156         talloc_free(mem_ctx);
 157 
 158         return ret;
 159 }
 160 
 161 static NTSTATUS raw_smbcli_open(struct smbcli_tree *tree, const char *fname, int flags, int share_mode, int *fnum)
     /* [<][>][^][v][top][bottom][index][help] */
 162 {
 163         union smb_open open_parms;
 164         uint_t openfn=0;
 165         uint_t accessmode=0;
 166         TALLOC_CTX *mem_ctx;
 167         NTSTATUS status;
 168 
 169         mem_ctx = talloc_init("raw_open");
 170         if (!mem_ctx) return NT_STATUS_NO_MEMORY;
 171 
 172         if (flags & O_CREAT) {
 173                 openfn |= OPENX_OPEN_FUNC_CREATE;
 174         }
 175         if (!(flags & O_EXCL)) {
 176                 if (flags & O_TRUNC) {
 177                         openfn |= OPENX_OPEN_FUNC_TRUNC;
 178                 } else {
 179                         openfn |= OPENX_OPEN_FUNC_OPEN;
 180                 }
 181         }
 182 
 183         accessmode = (share_mode<<OPENX_MODE_DENY_SHIFT);
 184 
 185         if ((flags & O_ACCMODE) == O_RDWR) {
 186                 accessmode |= OPENX_MODE_ACCESS_RDWR;
 187         } else if ((flags & O_ACCMODE) == O_WRONLY) {
 188                 accessmode |= OPENX_MODE_ACCESS_WRITE;
 189         } else if ((flags & O_ACCMODE) == O_RDONLY) {
 190                 accessmode |= OPENX_MODE_ACCESS_READ;
 191         }
 192 
 193 #if defined(O_SYNC)
 194         if ((flags & O_SYNC) == O_SYNC) {
 195                 accessmode |= OPENX_MODE_WRITE_THRU;
 196         }
 197 #endif
 198 
 199         if (share_mode == DENY_FCB) {
 200                 accessmode = OPENX_MODE_ACCESS_FCB | OPENX_MODE_DENY_FCB;
 201         }
 202 
 203         open_parms.openx.level = RAW_OPEN_OPENX;
 204         open_parms.openx.in.flags = 0;
 205         open_parms.openx.in.open_mode = accessmode;
 206         open_parms.openx.in.search_attrs = FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN;
 207         open_parms.openx.in.file_attrs = 0;
 208         open_parms.openx.in.write_time = 0;
 209         open_parms.openx.in.open_func = openfn;
 210         open_parms.openx.in.size = 0;
 211         open_parms.openx.in.timeout = 0;
 212         open_parms.openx.in.fname = fname;
 213 
 214         status = smb_raw_open(tree, mem_ctx, &open_parms);
 215         talloc_free(mem_ctx);
 216 
 217         if (fnum && NT_STATUS_IS_OK(status)) {
 218                 *fnum = open_parms.openx.out.file.fnum;
 219         }
 220 
 221         return status;
 222 }
 223 
 224 static NTSTATUS raw_smbcli_t2open(struct smbcli_tree *tree, const char *fname, int flags, int share_mode, int *fnum)
     /* [<][>][^][v][top][bottom][index][help] */
 225 {
 226         union smb_open io;
 227         uint_t openfn=0;
 228         uint_t accessmode=0;
 229         TALLOC_CTX *mem_ctx;
 230         NTSTATUS status;
 231 
 232         mem_ctx = talloc_init("raw_t2open");
 233         if (!mem_ctx) return NT_STATUS_NO_MEMORY;
 234 
 235         if (flags & O_CREAT) {
 236                 openfn |= OPENX_OPEN_FUNC_CREATE;
 237         }
 238         if (!(flags & O_EXCL)) {
 239                 if (flags & O_TRUNC) {
 240                         openfn |= OPENX_OPEN_FUNC_TRUNC;
 241                 } else {
 242                         openfn |= OPENX_OPEN_FUNC_OPEN;
 243                 }
 244         }
 245 
 246         accessmode = (share_mode<<OPENX_MODE_DENY_SHIFT);
 247 
 248         if ((flags & O_ACCMODE) == O_RDWR) {
 249                 accessmode |= OPENX_MODE_ACCESS_RDWR;
 250         } else if ((flags & O_ACCMODE) == O_WRONLY) {
 251                 accessmode |= OPENX_MODE_ACCESS_WRITE;
 252         } else if ((flags & O_ACCMODE) == O_RDONLY) {
 253                 accessmode |= OPENX_MODE_ACCESS_READ;
 254         }
 255 
 256 #if defined(O_SYNC)
 257         if ((flags & O_SYNC) == O_SYNC) {
 258                 accessmode |= OPENX_MODE_WRITE_THRU;
 259         }
 260 #endif
 261 
 262         if (share_mode == DENY_FCB) {
 263                 accessmode = OPENX_MODE_ACCESS_FCB | OPENX_MODE_DENY_FCB;
 264         }
 265 
 266         memset(&io, '\0', sizeof(io));
 267         io.t2open.level = RAW_OPEN_T2OPEN;
 268         io.t2open.in.flags = 0;
 269         io.t2open.in.open_mode = accessmode;
 270         io.t2open.in.search_attrs = FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN;
 271         io.t2open.in.file_attrs = 0;
 272         io.t2open.in.write_time = 0;
 273         io.t2open.in.open_func = openfn;
 274         io.t2open.in.size = 0;
 275         io.t2open.in.timeout = 0;
 276         io.t2open.in.fname = fname;
 277 
 278         io.t2open.in.num_eas = 1;
 279         io.t2open.in.eas = talloc_array(mem_ctx, struct ea_struct, io.t2open.in.num_eas);
 280         io.t2open.in.eas[0].flags = 0;
 281         io.t2open.in.eas[0].name.s = ".CLASSINFO";
 282         io.t2open.in.eas[0].value = data_blob_talloc(mem_ctx, "first value", 11);
 283 
 284         status = smb_raw_open(tree, mem_ctx, &io);
 285         talloc_free(mem_ctx);
 286 
 287         if (fnum && NT_STATUS_IS_OK(status)) {
 288                 *fnum = io.openx.out.file.fnum;
 289         }
 290 
 291         return status;
 292 }
 293 
 294 static NTSTATUS raw_smbcli_ntcreate(struct smbcli_tree *tree, const char *fname, int *fnum)
     /* [<][>][^][v][top][bottom][index][help] */
 295 {
 296         union smb_open io;
 297         TALLOC_CTX *mem_ctx;
 298         NTSTATUS status;
 299 
 300         mem_ctx = talloc_init("raw_t2open");
 301         if (!mem_ctx) return NT_STATUS_NO_MEMORY;
 302 
 303         memset(&io, '\0', sizeof(io));
 304         io.generic.level = RAW_OPEN_NTCREATEX;
 305         io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED;
 306         io.ntcreatex.in.root_fid = 0;
 307         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
 308         io.ntcreatex.in.alloc_size = 0;
 309         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
 310         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE;
 311         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
 312         io.ntcreatex.in.create_options = 0;
 313         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
 314         io.ntcreatex.in.security_flags = 0;
 315         io.ntcreatex.in.fname = fname;
 316 
 317         status = smb_raw_open(tree, mem_ctx, &io);
 318         talloc_free(mem_ctx);
 319 
 320         if (fnum && NT_STATUS_IS_OK(status)) {
 321                 *fnum = io.openx.out.file.fnum;
 322         }
 323 
 324         return status;
 325 }
 326 
 327 
 328 bool torture_samba3_badpath(struct torture_context *torture)
     /* [<][>][^][v][top][bottom][index][help] */
 329 {
 330         struct smbcli_state *cli_nt;
 331         struct smbcli_state *cli_dos;
 332         const char *fname = "test.txt";
 333         const char *fname1 = "test1.txt";
 334         const char *dirname = "testdir";
 335         char *fpath;
 336         char *fpath1;
 337         int fnum;
 338         NTSTATUS status;
 339         bool ret = true;
 340         TALLOC_CTX *mem_ctx;
 341         bool nt_status_support;
 342 
 343         if (!(mem_ctx = talloc_init("torture_samba3_badpath"))) {
 344                 d_printf("talloc_init failed\n");
 345                 return false;
 346         }
 347 
 348         nt_status_support = lp_nt_status_support(torture->lp_ctx);
 349 
 350         if (!lp_set_cmdline(torture->lp_ctx, "nt status support", "yes")) {
 351                 printf("Could not set 'nt status support = yes'\n");
 352                 goto fail;
 353         }
 354 
 355         if (!torture_open_connection(&cli_nt, torture, 0)) {
 356                 goto fail;
 357         }
 358 
 359         if (!lp_set_cmdline(torture->lp_ctx, "nt status support", "no")) {
 360                 printf("Could not set 'nt status support = yes'\n");
 361                 goto fail;
 362         }
 363 
 364         if (!torture_open_connection(&cli_dos, torture, 1)) {
 365                 goto fail;
 366         }
 367 
 368         if (!lp_set_cmdline(torture->lp_ctx, "nt status support",
 369                             nt_status_support ? "yes":"no")) {
 370                 printf("Could not reset 'nt status support = yes'");
 371                 goto fail;
 372         }
 373 
 374         smbcli_deltree(cli_nt->tree, dirname);
 375 
 376         status = smbcli_mkdir(cli_nt->tree, dirname);
 377         if (!NT_STATUS_IS_OK(status)) {
 378                 d_printf("smbcli_mkdir failed: %s\n", nt_errstr(status));
 379                 ret = false;
 380                 goto done;
 381         }
 382 
 383         status = smbcli_chkpath(cli_nt->tree, dirname);
 384         CHECK_STATUS(status, NT_STATUS_OK);
 385 
 386         status = smbcli_chkpath(cli_nt->tree,
 387                                 talloc_asprintf(mem_ctx, "%s\\bla", dirname));
 388         CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_NOT_FOUND);
 389 
 390         status = smbcli_chkpath(cli_dos->tree,
 391                                 talloc_asprintf(mem_ctx, "%s\\bla", dirname));
 392         CHECK_STATUS(status, NT_STATUS_DOS(ERRDOS, ERRbadpath));
 393 
 394         status = smbcli_chkpath(cli_nt->tree,
 395                                 talloc_asprintf(mem_ctx, "%s\\bla\\blub",
 396                                                 dirname));
 397         CHECK_STATUS(status, NT_STATUS_OBJECT_PATH_NOT_FOUND);
 398         status = smbcli_chkpath(cli_dos->tree,
 399                                 talloc_asprintf(mem_ctx, "%s\\bla\\blub",
 400                                                 dirname));
 401         CHECK_STATUS(status, NT_STATUS_DOS(ERRDOS, ERRbadpath));
 402 
 403         if (!(fpath = talloc_asprintf(mem_ctx, "%s\\%s", dirname, fname))) {
 404                 goto fail;
 405         }
 406         fnum = smbcli_open(cli_nt->tree, fpath, O_RDWR | O_CREAT, DENY_NONE);
 407         if (fnum == -1) {
 408                 d_printf("Could not create file %s: %s\n", fpath,
 409                          smbcli_errstr(cli_nt->tree));
 410                 goto fail;
 411         }
 412         smbcli_close(cli_nt->tree, fnum);
 413 
 414         if (!(fpath1 = talloc_asprintf(mem_ctx, "%s\\%s", dirname, fname1))) {
 415                 goto fail;
 416         }
 417         fnum = smbcli_open(cli_nt->tree, fpath1, O_RDWR | O_CREAT, DENY_NONE);
 418         if (fnum == -1) {
 419                 d_printf("Could not create file %s: %s\n", fpath1,
 420                          smbcli_errstr(cli_nt->tree));
 421                 goto fail;
 422         }
 423         smbcli_close(cli_nt->tree, fnum);
 424 
 425         /*
 426          * Do a whole bunch of error code checks on chkpath
 427          */
 428 
 429         status = smbcli_chkpath(cli_nt->tree, fpath);
 430         CHECK_STATUS(status, NT_STATUS_NOT_A_DIRECTORY);
 431         status = smbcli_chkpath(cli_dos->tree, fpath);
 432         CHECK_STATUS(status, NT_STATUS_DOS(ERRDOS, ERRbadpath));
 433 
 434         status = smbcli_chkpath(cli_nt->tree, "..");
 435         CHECK_STATUS(status, NT_STATUS_OBJECT_PATH_SYNTAX_BAD);
 436         status = smbcli_chkpath(cli_dos->tree, "..");
 437         CHECK_STATUS(status, NT_STATUS_DOS(ERRDOS, ERRinvalidpath));
 438 
 439         status = smbcli_chkpath(cli_nt->tree, ".");
 440         CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_INVALID);
 441         status = smbcli_chkpath(cli_dos->tree, ".");
 442         CHECK_STATUS(status, NT_STATUS_DOS(ERRDOS, ERRbadpath));
 443 
 444         status = smbcli_chkpath(cli_nt->tree, "\t");
 445         CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_INVALID);
 446         status = smbcli_chkpath(cli_dos->tree, "\t");
 447         CHECK_STATUS(status, NT_STATUS_DOS(ERRDOS, ERRbadpath));
 448 
 449         status = smbcli_chkpath(cli_nt->tree, "\t\\bla");
 450         CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_INVALID);
 451         status = smbcli_chkpath(cli_dos->tree, "\t\\bla");
 452         CHECK_STATUS(status, NT_STATUS_DOS(ERRDOS, ERRbadpath));
 453 
 454         status = smbcli_chkpath(cli_nt->tree, "<");
 455         CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_INVALID);
 456         status = smbcli_chkpath(cli_dos->tree, "<");
 457         CHECK_STATUS(status, NT_STATUS_DOS(ERRDOS, ERRbadpath));
 458 
 459         status = smbcli_chkpath(cli_nt->tree, "<\\bla");
 460         CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_INVALID);
 461         status = smbcli_chkpath(cli_dos->tree, "<\\bla");
 462         CHECK_STATUS(status, NT_STATUS_DOS(ERRDOS, ERRbadpath));
 463 
 464         /*
 465          * .... And the same gang against getatr. Note that the DOS error codes
 466          * differ....
 467          */
 468 
 469         status = smbcli_getatr(cli_nt->tree, fpath, NULL, NULL, NULL);
 470         CHECK_STATUS(status, NT_STATUS_OK);
 471         status = smbcli_getatr(cli_dos->tree, fpath, NULL, NULL, NULL);
 472         CHECK_STATUS(status, NT_STATUS_OK);
 473 
 474         status = smbcli_getatr(cli_nt->tree, "..", NULL, NULL, NULL);
 475         CHECK_STATUS(status, NT_STATUS_OBJECT_PATH_SYNTAX_BAD);
 476         status = smbcli_getatr(cli_dos->tree, "..", NULL, NULL, NULL);
 477         CHECK_STATUS(status, NT_STATUS_DOS(ERRDOS, ERRinvalidpath));
 478 
 479         status = smbcli_getatr(cli_nt->tree, ".", NULL, NULL, NULL);
 480         CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_INVALID);
 481         status = smbcli_getatr(cli_dos->tree, ".", NULL, NULL, NULL);
 482         CHECK_STATUS(status, NT_STATUS_DOS(ERRDOS, ERRinvalidname));
 483 
 484         status = smbcli_getatr(cli_nt->tree, "\t", NULL, NULL, NULL);
 485         CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_INVALID);
 486         status = smbcli_getatr(cli_dos->tree, "\t", NULL, NULL, NULL);
 487         CHECK_STATUS(status, NT_STATUS_DOS(ERRDOS, ERRinvalidname));
 488 
 489         status = smbcli_getatr(cli_nt->tree, "\t\\bla", NULL, NULL, NULL);
 490         CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_INVALID);
 491         status = smbcli_getatr(cli_dos->tree, "\t\\bla", NULL, NULL, NULL);
 492         CHECK_STATUS(status, NT_STATUS_DOS(ERRDOS, ERRinvalidname));
 493 
 494         status = smbcli_getatr(cli_nt->tree, "<", NULL, NULL, NULL);
 495         CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_INVALID);
 496         status = smbcli_getatr(cli_dos->tree, "<", NULL, NULL, NULL);
 497         CHECK_STATUS(status, NT_STATUS_DOS(ERRDOS, ERRinvalidname));
 498 
 499         status = smbcli_getatr(cli_nt->tree, "<\\bla", NULL, NULL, NULL);
 500         CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_INVALID);
 501         status = smbcli_getatr(cli_dos->tree, "<\\bla", NULL, NULL, NULL);
 502         CHECK_STATUS(status, NT_STATUS_DOS(ERRDOS, ERRinvalidname));
 503 
 504         /* Try the same set with openX. */
 505 
 506         status = raw_smbcli_open(cli_nt->tree, "..", O_RDONLY, DENY_NONE, NULL);
 507         CHECK_STATUS(status, NT_STATUS_OBJECT_PATH_SYNTAX_BAD);
 508         status = raw_smbcli_open(cli_dos->tree, "..", O_RDONLY, DENY_NONE, NULL);
 509         CHECK_STATUS(status, NT_STATUS_DOS(ERRDOS, ERRinvalidpath));
 510 
 511         status = raw_smbcli_open(cli_nt->tree, ".", O_RDONLY, DENY_NONE, NULL);
 512         CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_INVALID);
 513         status = raw_smbcli_open(cli_dos->tree, ".", O_RDONLY, DENY_NONE, NULL);
 514         CHECK_STATUS(status, NT_STATUS_DOS(ERRDOS, ERRinvalidname));
 515 
 516         status = raw_smbcli_open(cli_nt->tree, "\t", O_RDONLY, DENY_NONE, NULL);
 517         CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_INVALID);
 518         status = raw_smbcli_open(cli_dos->tree, "\t", O_RDONLY, DENY_NONE, NULL);
 519         CHECK_STATUS(status, NT_STATUS_DOS(ERRDOS, ERRinvalidname));
 520 
 521         status = raw_smbcli_open(cli_nt->tree, "\t\\bla", O_RDONLY, DENY_NONE, NULL);
 522         CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_INVALID);
 523         status = raw_smbcli_open(cli_dos->tree, "\t\\bla", O_RDONLY, DENY_NONE, NULL);
 524         CHECK_STATUS(status, NT_STATUS_DOS(ERRDOS, ERRinvalidname));
 525 
 526         status = raw_smbcli_open(cli_nt->tree, "<", O_RDONLY, DENY_NONE, NULL);
 527         CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_INVALID);
 528         status = raw_smbcli_open(cli_dos->tree, "<", O_RDONLY, DENY_NONE, NULL);
 529         CHECK_STATUS(status, NT_STATUS_DOS(ERRDOS, ERRinvalidname));
 530 
 531         status = raw_smbcli_open(cli_nt->tree, "<\\bla", O_RDONLY, DENY_NONE, NULL);
 532         CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_INVALID);
 533         status = raw_smbcli_open(cli_dos->tree, "<\\bla", O_RDONLY, DENY_NONE, NULL);
 534         CHECK_STATUS(status, NT_STATUS_DOS(ERRDOS, ERRinvalidname));
 535 
 536         /* Let's test EEXIST error code mapping. */
 537         status = raw_smbcli_open(cli_nt->tree, fpath, O_RDONLY | O_CREAT| O_EXCL, DENY_NONE, NULL);
 538         CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_COLLISION);
 539         status = raw_smbcli_open(cli_dos->tree, fpath, O_RDONLY | O_CREAT| O_EXCL, DENY_NONE, NULL);
 540         CHECK_STATUS(status, NT_STATUS_DOS(ERRDOS,ERRfilexists));
 541 
 542         status = raw_smbcli_t2open(cli_nt->tree, fpath, O_RDONLY | O_CREAT| O_EXCL, DENY_NONE, NULL);
 543         if (!NT_STATUS_EQUAL(status, NT_STATUS_EAS_NOT_SUPPORTED)
 544             || !torture_setting_bool(torture, "samba3", false)) {
 545                 /* Against samba3, treat EAS_NOT_SUPPORTED as acceptable */
 546                 CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_COLLISION);
 547         }
 548         status = raw_smbcli_t2open(cli_dos->tree, fpath, O_RDONLY | O_CREAT| O_EXCL, DENY_NONE, NULL);
 549         if (!NT_STATUS_EQUAL(status, NT_STATUS_DOS(ERRDOS,ERReasnotsupported))
 550             || !torture_setting_bool(torture, "samba3", false)) {
 551                 /* Against samba3, treat EAS_NOT_SUPPORTED as acceptable */
 552                 CHECK_STATUS(status, NT_STATUS_DOS(ERRDOS,ERRfilexists));
 553         }
 554 
 555         status = raw_smbcli_ntcreate(cli_nt->tree, fpath, NULL);
 556         CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_COLLISION);
 557         status = raw_smbcli_ntcreate(cli_dos->tree, fpath, NULL);
 558         CHECK_STATUS(status, NT_STATUS_DOS(ERRDOS,ERRfilexists));
 559 
 560         /* Try the rename test. */
 561         {
 562                 union smb_rename io;
 563                 memset(&io, '\0', sizeof(io));
 564                 io.rename.in.pattern1 = fpath1;
 565                 io.rename.in.pattern2 = fpath;
 566 
 567                 /* Try with SMBmv rename. */
 568                 status = smb_raw_rename(cli_nt->tree, &io);
 569                 CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_COLLISION);
 570                 status = smb_raw_rename(cli_dos->tree, &io);
 571                 CHECK_STATUS(status, NT_STATUS_DOS(ERRDOS,ERRrename));
 572 
 573                 /* Try with NT rename. */
 574                 io.generic.level = RAW_RENAME_NTRENAME;
 575                 io.ntrename.in.old_name = fpath1;
 576                 io.ntrename.in.new_name = fpath;
 577                 io.ntrename.in.attrib = 0;
 578                 io.ntrename.in.cluster_size = 0;
 579                 io.ntrename.in.flags = RENAME_FLAG_RENAME;
 580 
 581                 status = smb_raw_rename(cli_nt->tree, &io);
 582                 CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_COLLISION);
 583                 status = smb_raw_rename(cli_dos->tree, &io);
 584                 CHECK_STATUS(status, NT_STATUS_DOS(ERRDOS,ERRrename));
 585         }
 586 
 587         goto done;
 588 
 589  fail:
 590         ret = false;
 591 
 592  done:
 593         if (cli_nt != NULL) {
 594                 smbcli_deltree(cli_nt->tree, dirname);
 595                 torture_close_connection(cli_nt);
 596         }
 597         if (cli_dos != NULL) {
 598                 torture_close_connection(cli_dos);
 599         }
 600         talloc_free(mem_ctx);
 601 
 602         return ret;
 603 }
 604 
 605 static void count_fn(struct clilist_file_info *info, const char *name,
     /* [<][>][^][v][top][bottom][index][help] */
 606                      void *private_data)
 607 {
 608         int *counter = (int *)private_data;
 609         *counter += 1;
 610 }
 611 
 612 bool torture_samba3_caseinsensitive(struct torture_context *torture)
     /* [<][>][^][v][top][bottom][index][help] */
 613 {
 614         struct smbcli_state *cli;
 615         TALLOC_CTX *mem_ctx;
 616         NTSTATUS status;
 617         const char *dirname = "insensitive";
 618         const char *ucase_dirname = "InSeNsItIvE";
 619         const char *fname = "foo";
 620         char *fpath;
 621         int fnum;
 622         int counter = 0;
 623         bool ret = true;
 624 
 625         if (!(mem_ctx = talloc_init("torture_samba3_caseinsensitive"))) {
 626                 d_printf("talloc_init failed\n");
 627                 return false;
 628         }
 629 
 630         if (!torture_open_connection(&cli, torture, 0)) {
 631                 goto done;
 632         }
 633 
 634         smbcli_deltree(cli->tree, dirname);
 635 
 636         status = smbcli_mkdir(cli->tree, dirname);
 637         if (!NT_STATUS_IS_OK(status)) {
 638                 d_printf("smbcli_mkdir failed: %s\n", nt_errstr(status));
 639                 goto done;
 640         }
 641 
 642         if (!(fpath = talloc_asprintf(mem_ctx, "%s\\%s", dirname, fname))) {
 643                 goto done;
 644         }
 645         fnum = smbcli_open(cli->tree, fpath, O_RDWR | O_CREAT, DENY_NONE);
 646         if (fnum == -1) {
 647                 d_printf("Could not create file %s: %s\n", fpath,
 648                          smbcli_errstr(cli->tree));
 649                 goto done;
 650         }
 651         smbcli_close(cli->tree, fnum);
 652 
 653         smbcli_list(cli->tree, talloc_asprintf(
 654                             mem_ctx, "%s\\*", ucase_dirname),
 655                     FILE_ATTRIBUTE_DIRECTORY|FILE_ATTRIBUTE_HIDDEN
 656                     |FILE_ATTRIBUTE_SYSTEM,
 657                     count_fn, (void *)&counter);
 658 
 659         if (counter == 3) {
 660                 ret = true;
 661         }
 662         else {
 663                 d_fprintf(stderr, "expected 3 entries, got %d\n", counter);
 664                 ret = false;
 665         }
 666 
 667  done:
 668         talloc_free(mem_ctx);
 669         return ret;
 670 }
 671 
 672 /*
 673  * Check that Samba3 correctly deals with conflicting posix byte range locks
 674  * on an underlying file
 675  *
 676  * Note: This test depends on "posix locking = yes".
 677  * Note: To run this test, use "--option=torture:localdir=<LOCALDIR>"
 678  */
 679 
 680 bool torture_samba3_posixtimedlock(struct torture_context *tctx)
     /* [<][>][^][v][top][bottom][index][help] */
 681 {
 682         struct smbcli_state *cli;
 683         NTSTATUS status;
 684         bool ret = true;
 685         const char *dirname = "posixlock";
 686         const char *fname = "locked";
 687         const char *fpath;
 688         const char *localdir;
 689         const char *localname;
 690         int fnum = -1;
 691 
 692         int fd = -1;
 693         struct flock posix_lock;
 694 
 695         union smb_lock io;
 696         struct smb_lock_entry lock_entry;
 697         struct smbcli_request *req;
 698 
 699         if (!torture_open_connection(&cli, tctx, 0)) {
 700                 ret = false;
 701                 goto done;
 702         }
 703 
 704         smbcli_deltree(cli->tree, dirname);
 705 
 706         status = smbcli_mkdir(cli->tree, dirname);
 707         if (!NT_STATUS_IS_OK(status)) {
 708                 torture_warning(tctx, "smbcli_mkdir failed: %s\n",
 709                                 nt_errstr(status));
 710                 ret = false;
 711                 goto done;
 712         }
 713 
 714         if (!(fpath = talloc_asprintf(tctx, "%s\\%s", dirname, fname))) {
 715                 torture_warning(tctx, "talloc failed\n");
 716                 ret = false;
 717                 goto done;
 718         }
 719         fnum = smbcli_open(cli->tree, fpath, O_RDWR | O_CREAT, DENY_NONE);
 720         if (fnum == -1) {
 721                 torture_warning(tctx, "Could not create file %s: %s\n", fpath,
 722                                 smbcli_errstr(cli->tree));
 723                 ret = false;
 724                 goto done;
 725         }
 726 
 727         if (!(localdir = torture_setting_string(tctx, "localdir", NULL))) {
 728                 torture_warning(tctx, "Need 'localdir' setting\n");
 729                 ret = false;
 730                 goto done;
 731         }
 732 
 733         if (!(localname = talloc_asprintf(tctx, "%s/%s/%s", localdir, dirname,
 734                                           fname))) {
 735                 torture_warning(tctx, "talloc failed\n");
 736                 ret = false;
 737                 goto done;
 738         }
 739 
 740         /*
 741          * Lock a byte range from posix
 742          */
 743 
 744         fd = open(localname, O_RDWR);
 745         if (fd == -1) {
 746                 torture_warning(tctx, "open(%s) failed: %s\n",
 747                                 localname, strerror(errno));
 748                 goto done;
 749         }
 750 
 751         posix_lock.l_type = F_WRLCK;
 752         posix_lock.l_whence = SEEK_SET;
 753         posix_lock.l_start = 0;
 754         posix_lock.l_len = 1;
 755 
 756         if (fcntl(fd, F_SETLK, &posix_lock) == -1) {
 757                 torture_warning(tctx, "fcntl failed: %s\n", strerror(errno));
 758                 ret = false;
 759                 goto done;
 760         }
 761 
 762         /*
 763          * Try a cifs brlock without timeout to see if posix locking = yes
 764          */
 765 
 766         io.lockx.in.ulock_cnt = 0;
 767         io.lockx.in.lock_cnt = 1;
 768 
 769         lock_entry.count = 1;
 770         lock_entry.offset = 0;
 771         lock_entry.pid = cli->tree->session->pid;
 772 
 773         io.lockx.level = RAW_LOCK_LOCKX;
 774         io.lockx.in.mode = LOCKING_ANDX_LARGE_FILES;
 775         io.lockx.in.timeout = 0;
 776         io.lockx.in.locks = &lock_entry;
 777         io.lockx.in.file.fnum = fnum;
 778 
 779         status = smb_raw_lock(cli->tree, &io);
 780 
 781         ret = true;
 782         CHECK_STATUS(status, NT_STATUS_FILE_LOCK_CONFLICT);
 783 
 784         if (!ret) {
 785                 goto done;
 786         }
 787 
 788         /*
 789          * Now fire off a timed brlock, unlock the posix lock and see if the
 790          * timed lock gets through.
 791          */
 792 
 793         io.lockx.in.timeout = 5000;
 794 
 795         req = smb_raw_lock_send(cli->tree, &io);
 796         if (req == NULL) {
 797                 torture_warning(tctx, "smb_raw_lock_send failed\n");
 798                 ret = false;
 799                 goto done;
 800         }
 801 
 802         /*
 803          * Ship the async timed request to the server
 804          */
 805         event_loop_once(req->transport->socket->event.ctx);
 806         msleep(500);
 807 
 808         close(fd);
 809 
 810         status = smbcli_request_simple_recv(req);
 811 
 812         CHECK_STATUS(status, NT_STATUS_OK);
 813 
 814  done:
 815         if (fnum != -1) {
 816                 smbcli_close(cli->tree, fnum);
 817         }
 818         if (fd != -1) {
 819                 close(fd);
 820         }
 821         smbcli_deltree(cli->tree, dirname);
 822         return ret;
 823 }
 824 
 825 bool torture_samba3_rootdirfid(struct torture_context *tctx)
     /* [<][>][^][v][top][bottom][index][help] */
 826 {
 827         struct smbcli_state *cli;
 828         NTSTATUS status;
 829         uint16_t dnum;
 830         union smb_open io;
 831         const char *fname = "testfile";
 832         bool ret = false;
 833 
 834         if (!torture_open_connection(&cli, tctx, 0)) {
 835                 ret = false;
 836                 goto done;
 837         }
 838 
 839         smbcli_unlink(cli->tree, fname);
 840 
 841         ZERO_STRUCT(io);
 842         io.generic.level = RAW_OPEN_NTCREATEX;
 843         io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED;
 844         io.ntcreatex.in.root_fid = 0;
 845         io.ntcreatex.in.security_flags = 0;
 846         io.ntcreatex.in.access_mask =
 847                 SEC_STD_SYNCHRONIZE | SEC_FILE_EXECUTE;
 848         io.ntcreatex.in.alloc_size = 0;
 849         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_DIRECTORY;
 850         io.ntcreatex.in.share_access =
 851                 NTCREATEX_SHARE_ACCESS_READ
 852                 | NTCREATEX_SHARE_ACCESS_READ;
 853         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
 854         io.ntcreatex.in.create_options = 0;
 855         io.ntcreatex.in.fname = "\\";
 856         status = smb_raw_open(cli->tree, tctx, &io);
 857         if (!NT_STATUS_IS_OK(status)) {
 858                 d_printf("smb_open on the directory failed: %s\n",
 859                          nt_errstr(status));
 860                 ret = false;
 861                 goto done;
 862         }
 863         dnum = io.ntcreatex.out.file.fnum;
 864 
 865         io.ntcreatex.in.flags =
 866                 NTCREATEX_FLAGS_REQUEST_OPLOCK
 867                 | NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
 868         io.ntcreatex.in.root_fid = dnum;
 869         io.ntcreatex.in.security_flags = 0;
 870         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OVERWRITE_IF;
 871         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
 872         io.ntcreatex.in.alloc_size = 0;
 873         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
 874         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
 875         io.ntcreatex.in.create_options = 0;
 876         io.ntcreatex.in.fname = fname;
 877 
 878         status = smb_raw_open(cli->tree, tctx, &io);
 879         if (!NT_STATUS_IS_OK(status)) {
 880                 d_printf("smb_open on the file %s failed: %s\n",
 881                          fname, nt_errstr(status));
 882                 ret = false;
 883                 goto done;
 884         }
 885 
 886         smbcli_close(cli->tree, io.ntcreatex.out.file.fnum);
 887         smbcli_close(cli->tree, dnum);
 888         smbcli_unlink(cli->tree, fname);
 889 
 890         ret = true;
 891  done:
 892         return ret;
 893 }
 894 
 895 bool torture_samba3_oplock_logoff(struct torture_context *tctx)
     /* [<][>][^][v][top][bottom][index][help] */
 896 {
 897         struct smbcli_state *cli;
 898         NTSTATUS status;
 899         uint16_t fnum1;
 900         union smb_open io;
 901         const char *fname = "testfile";
 902         bool ret = false;
 903         struct smbcli_request *req;
 904         struct smb_echo echo_req;
 905 
 906         if (!torture_open_connection(&cli, tctx, 0)) {
 907                 ret = false;
 908                 goto done;
 909         }
 910 
 911         smbcli_unlink(cli->tree, fname);
 912 
 913         ZERO_STRUCT(io);
 914         io.generic.level = RAW_OPEN_NTCREATEX;
 915         io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED;
 916         io.ntcreatex.in.root_fid = 0;
 917         io.ntcreatex.in.security_flags = 0;
 918         io.ntcreatex.in.access_mask =
 919                 SEC_STD_SYNCHRONIZE | SEC_FILE_EXECUTE;
 920         io.ntcreatex.in.alloc_size = 0;
 921         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
 922         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
 923         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
 924         io.ntcreatex.in.create_options = 0;
 925         io.ntcreatex.in.fname = "testfile";
 926         status = smb_raw_open(cli->tree, tctx, &io);
 927         if (!NT_STATUS_IS_OK(status)) {
 928                 d_printf("first smb_open failed: %s\n", nt_errstr(status));
 929                 ret = false;
 930                 goto done;
 931         }
 932         fnum1 = io.ntcreatex.out.file.fnum;
 933 
 934         /*
 935          * Create a conflicting open, causing the one-second delay
 936          */
 937 
 938         req = smb_raw_open_send(cli->tree, &io);
 939         if (req == NULL) {
 940                 d_printf("smb_raw_open_send failed\n");
 941                 ret = false;
 942                 goto done;
 943         }
 944 
 945         /*
 946          * Pull the VUID from under that request. As of Nov 3, 2008 all Samba3
 947          * versions (3.0, 3.2 and master) would spin sending ERRinvuid errors
 948          * as long as the client is still connected.
 949          */
 950 
 951         status = smb_raw_ulogoff(cli->session);
 952 
 953         if (!NT_STATUS_IS_OK(status)) {
 954                 d_printf("ulogoff failed: %s\n", nt_errstr(status));
 955                 ret = false;
 956                 goto done;
 957         }
 958 
 959         echo_req.in.repeat_count = 1;
 960         echo_req.in.size = 1;
 961         echo_req.in.data = (uint8_t *)"";
 962 
 963         status = smb_raw_echo(cli->session->transport, &echo_req);
 964         if (!NT_STATUS_IS_OK(status)) {
 965                 d_printf("smb_raw_echo returned %s\n",
 966                          nt_errstr(status));
 967                 ret = false;
 968                 goto done;
 969         }
 970 
 971         ret = true;
 972  done:
 973         return ret;
 974 }

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