/* tries the unusual lockingX locktype bits */ static bool torture_locktest6(struct torture_context *tctx, struct smbcli_state *cli) { const char *fname[1] = { "\\lock6.txt" }; int i; int fnum; NTSTATUS status; if (!torture_setup_dir(cli, BASEDIR)) { return false; } for (i=0;i<1;i++) { torture_comment(tctx, "Testing %s\n", fname[i]); smbcli_unlink(cli->tree, fname[i]); fnum = smbcli_open(cli->tree, fname[i], O_RDWR|O_CREAT|O_EXCL, DENY_NONE); status = smbcli_locktype(cli->tree, fnum, 0, 8, 0, LOCKING_ANDX_CHANGE_LOCKTYPE); smbcli_close(cli->tree, fnum); torture_comment(tctx, "CHANGE_LOCKTYPE gave %s\n", nt_errstr(status)); fnum = smbcli_open(cli->tree, fname[i], O_RDWR, DENY_NONE); status = smbcli_locktype(cli->tree, fnum, 0, 8, 0, LOCKING_ANDX_CANCEL_LOCK); smbcli_close(cli->tree, fnum); torture_comment(tctx, "CANCEL_LOCK gave %s\n", nt_errstr(status)); smbcli_unlink(cli->tree, fname[i]); } return true; }
bool torture_samba3_rootdirfid(struct torture_context *tctx, struct smbcli_state *cli) { uint16_t dnum; union smb_open io; const char *fname = "testfile"; bool ret = false; smbcli_unlink(cli->tree, fname); ZERO_STRUCT(io); io.generic.level = RAW_OPEN_NTCREATEX; io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED; io.ntcreatex.in.root_fid.fnum = 0; io.ntcreatex.in.security_flags = 0; io.ntcreatex.in.access_mask = SEC_STD_SYNCHRONIZE | SEC_FILE_EXECUTE; io.ntcreatex.in.alloc_size = 0; io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_DIRECTORY; io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_READ; io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN; io.ntcreatex.in.create_options = 0; io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS; io.ntcreatex.in.fname = "\\"; torture_assert_ntstatus_equal_goto(tctx, smb_raw_open(cli->tree, tctx, &io), NT_STATUS_OK, ret, done, "smb_open on the directory failed: %s\n"); dnum = io.ntcreatex.out.file.fnum; io.ntcreatex.in.flags = NTCREATEX_FLAGS_REQUEST_OPLOCK | NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK; io.ntcreatex.in.root_fid.fnum = dnum; io.ntcreatex.in.security_flags = 0; io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OVERWRITE_IF; io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL; io.ntcreatex.in.alloc_size = 0; io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL; io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE; io.ntcreatex.in.create_options = 0; io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS; io.ntcreatex.in.fname = fname; torture_assert_ntstatus_equal_goto(tctx, smb_raw_open(cli->tree, tctx, &io), NT_STATUS_OK, ret, done, "smb_open on the file failed"); smbcli_close(cli->tree, io.ntcreatex.out.file.fnum); smbcli_close(cli->tree, dnum); smbcli_unlink(cli->tree, fname); ret = true; done: return ret; }
static void reconnect(struct tevent_context *ev, struct loadparm_context *lp_ctx, TALLOC_CTX *mem_ctx, struct smbcli_state *cli[NSERVERS][NCONNECTIONS], int fnum[NSERVERS][NCONNECTIONS][NFILES], char *share[NSERVERS]) { int server, conn, f; for (server=0;server<NSERVERS;server++) for (conn=0;conn<NCONNECTIONS;conn++) { if (cli[server][conn]) { for (f=0;f<NFILES;f++) { if (fnum[server][conn][f] != -1) { smbcli_close(cli[server][conn]->tree, fnum[server][conn][f]); fnum[server][conn][f] = -1; } } talloc_free(cli[server][conn]); } cli[server][conn] = connect_one(ev, lp_ctx, mem_ctx, share[server], server, conn); if (!cli[server][conn]) { DEBUG(0,("Failed to connect to %s\n", share[server])); exit(1); } } }
static void reconnect(struct smbcli_state *cli[NSERVERS][NCONNECTIONS], char *nfs[NSERVERS], int fnum[NSERVERS][NUMFSTYPES][NCONNECTIONS][NFILES], char *share1, char *share2) { int server, conn, f, fstype; char *share[2]; share[0] = share1; share[1] = share2; fstype = FSTYPE_SMB; for (server=0;server<NSERVERS;server++) for (conn=0;conn<NCONNECTIONS;conn++) { if (cli[server][conn]) { for (f=0;f<NFILES;f++) { smbcli_close(cli[server][conn], fnum[server][fstype][conn][f]); } smbcli_ulogoff(cli[server][conn]); talloc_free(cli[server][conn]); } cli[server][conn] = connect_one(share[server]); if (!cli[server][conn]) { DEBUG(0,("Failed to connect to %s\n", share[server])); exit(1); } } }
/* look for the w2k3 setpathinfo STANDARD bug */ static bool torture_raw_sfileinfo_bug(struct torture_context *torture, struct smbcli_state *cli) { const char *fname = "\\bug3.txt"; union smb_setfileinfo sfinfo; NTSTATUS status; int fnum; if (!torture_setting_bool(torture, "dangerous", false)) torture_skip(torture, "torture_raw_sfileinfo_bug disabled - enable dangerous tests to use\n"); fnum = create_complex_file(cli, torture, fname); smbcli_close(cli->tree, fnum); sfinfo.generic.level = RAW_SFILEINFO_STANDARD; sfinfo.generic.in.file.path = fname; sfinfo.standard.in.create_time = 0; sfinfo.standard.in.access_time = 0; sfinfo.standard.in.write_time = 0; status = smb_raw_setpathinfo(cli->tree, &sfinfo); printf("%s - %s\n", fname, nt_errstr(status)); printf("now try and delete %s\n", fname); return true; }
static int /* O - 0 = success, non-0 = failure */ smb_print(struct smbcli_state *cli, /* I - SMB connection */ char *title, /* I - Title/job name */ FILE *fp) /* I - File to print */ { int fnum; /* File number */ int nbytes, /* Number of bytes read */ tbytes; /* Total bytes read */ char buffer[8192], /* Buffer for copy */ *ptr; /* Pointer into tile */ /* * Sanitize the title... */ for (ptr = title; *ptr; ptr ++) if (!isalnum((int)*ptr) && !isspace((int)*ptr)) *ptr = '_'; /* * Open the printer device... */ if ((fnum = smbcli_open(cli, title, O_RDWR | O_CREAT | O_TRUNC, DENY_NONE)) == -1) { fprintf(stderr, "ERROR: %s opening remote file %s\n", smbcli_errstr(cli), title); return (1); } /* * Copy the file to the printer... */ if (fp != stdin) rewind(fp); tbytes = 0; while ((nbytes = fread(buffer, 1, sizeof(buffer), fp)) > 0) { if (smbcli_write(cli, fnum, 0, buffer, tbytes, nbytes) != nbytes) { fprintf(stderr, "ERROR: Error writing file: %s\n", smbcli_errstr(cli)); break; } tbytes += nbytes; } if (!smbcli_close(cli, fnum)) { fprintf(stderr, "ERROR: %s closing remote file %s\n", smbcli_errstr(cli), title); return (1); } else return (0); }
static bool print_printjob(struct torture_context *tctx, struct smbcli_tree *tree) { int fnum; DATA_BLOB data; ssize_t size_written; const char *str; torture_comment(tctx, "creating printjob %s\n", TORTURE_PRINT_FILE); fnum = smbcli_open(tree, TORTURE_PRINT_FILE, O_RDWR|O_CREAT|O_TRUNC, DENY_NONE); if (fnum == -1) { torture_fail(tctx, "failed to open file"); } str = talloc_asprintf(tctx, "TortureTestPage: %d\nData\n",0); data = data_blob_string_const(str); size_written = smbcli_write(tree, fnum, 0, data.data, 0, data.length); if (size_written != data.length) { torture_fail(tctx, "failed to write file"); } torture_assert_ntstatus_ok(tctx, smbcli_close(tree, fnum), "failed to close file"); return true; }
/* basic testing of all RAW_FILEINFO_* calls for each call we test that it succeeds, and where possible test for consistency between the calls. */ BOOL torture_raw_qfileinfo(struct torture_context *torture) { struct smbcli_state *cli; BOOL ret = True; TALLOC_CTX *mem_ctx; int fnum; const char *fname = "\\torture_qfileinfo.txt"; if (!torture_open_connection(&cli, 0)) { return False; } mem_ctx = talloc_init("torture_qfileinfo"); fnum = create_complex_file(cli, mem_ctx, fname); if (fnum == -1) { printf("ERROR: open of %s failed (%s)\n", fname, smbcli_errstr(cli->tree)); ret = False; goto done; } ret = torture_raw_qfileinfo_internals(torture, mem_ctx, cli->tree, fnum, fname, False /* is_ipc */); smbcli_close(cli->tree, fnum); smbcli_unlink(cli->tree, fname); done: torture_close_connection(cli); talloc_free(mem_ctx); return ret; }
NTSTATUS svc_UploadService(const char *hostname, struct cli_credentials * credentials, int force) { struct smb_composite_savefile *io; struct smbcli_state *cli; NTSTATUS status; status = smbcli_full_connection(NULL, &cli, hostname, "ADMIN$", NULL, credentials, NULL); NT_ERR(status, 1, "Failed to open ADMIN$ share"); if (!force) { int fd = smbcli_open(cli->tree, "winexesvc.exe", O_RDONLY, DENY_NONE); if (fd >= 0) { smbcli_close(cli->tree, fd); return status; } } else { smbcli_unlink(cli->tree, "winexesvc.exe"); } io = talloc_zero(cli->tree, struct smb_composite_savefile); io->in.fname = "winexesvc.exe"; io->in.data = winexesvc_exe; io->in.size = winexesvc_exe_len; status = smb_composite_savefile(cli->tree, io); NT_ERR(status, 1, "Failed to save ADMIN$/%s", io->in.fname); talloc_free(io); smbcli_tdis(cli); return status; }
bool torture_samba3_caseinsensitive(struct torture_context *torture) { struct smbcli_state *cli; TALLOC_CTX *mem_ctx; NTSTATUS status; const char *dirname = "insensitive"; const char *ucase_dirname = "InSeNsItIvE"; const char *fname = "foo"; char *fpath; int fnum; int counter = 0; bool ret = true; if (!(mem_ctx = talloc_init("torture_samba3_caseinsensitive"))) { d_printf("talloc_init failed\n"); return false; } if (!torture_open_connection(&cli, torture, 0)) { goto done; } smbcli_deltree(cli->tree, dirname); status = smbcli_mkdir(cli->tree, dirname); if (!NT_STATUS_IS_OK(status)) { d_printf("smbcli_mkdir failed: %s\n", nt_errstr(status)); goto done; } if (!(fpath = talloc_asprintf(mem_ctx, "%s\\%s", dirname, fname))) { goto done; } fnum = smbcli_open(cli->tree, fpath, O_RDWR | O_CREAT, DENY_NONE); if (fnum == -1) { d_printf("Could not create file %s: %s\n", fpath, smbcli_errstr(cli->tree)); goto done; } smbcli_close(cli->tree, fnum); smbcli_list(cli->tree, talloc_asprintf( mem_ctx, "%s\\*", ucase_dirname), FILE_ATTRIBUTE_DIRECTORY|FILE_ATTRIBUTE_HIDDEN |FILE_ATTRIBUTE_SYSTEM, count_fn, (void *)&counter); if (counter == 3) { ret = true; } else { d_fprintf(stderr, "expected 3 entries, got %d\n", counter); ret = false; } done: talloc_free(mem_ctx); return ret; }
/* open a file N times on the server and just hold them open used for testing performance when there are N file handles alopenn */ bool torture_holdopen(struct torture_context *tctx, struct smbcli_state *cli) { int i, fnum; const char *fname = "\\holdopen.dat"; NTSTATUS status; smbcli_unlink(cli->tree, fname); fnum = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE); if (fnum == -1) { torture_comment(tctx, "open of %s failed (%s)\n", fname, smbcli_errstr(cli->tree)); return false; } smbcli_close(cli->tree, fnum); for (i=0;i<torture_numops;i++) { union smb_open op; op.generic.level = RAW_OPEN_NTCREATEX; op.ntcreatex.in.root_fid.fnum = 0; op.ntcreatex.in.flags = 0; op.ntcreatex.in.access_mask = SEC_FILE_WRITE_DATA; op.ntcreatex.in.create_options = 0; op.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL; op.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_MASK; op.ntcreatex.in.alloc_size = 0; op.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN; op.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS; op.ntcreatex.in.security_flags = 0; op.ntcreatex.in.fname = fname; status = smb_raw_open(cli->tree, tctx, &op); if (!NT_STATUS_IS_OK(status)) { torture_warning(tctx, "open %d failed\n", i); continue; } if (torture_setting_bool(tctx, "progress", true)) { torture_comment(tctx, "opened %d file\r", i); fflush(stdout); } } torture_comment(tctx, "\nStarting pings\n"); while (1) { struct smb_echo ec; status = smb_raw_echo(cli->transport, &ec); torture_comment(tctx, "."); fflush(stdout); sleep(15); } return true; }
static bool test_session_reauth1(struct torture_context *tctx, struct smbcli_state *cli) { NTSTATUS status; struct smb_composite_sesssetup io; int fnum, num; const int dlen = 255; char *data; char fname[256]; char buf[dlen+1]; bool ok = true; uint16_t vuid1 = cli->session->vuid; data = generate_random_str(tctx, dlen); torture_assert(tctx, (data != NULL), "memory allocation failed"); snprintf(fname, sizeof(fname), "raw_session_reconnect_%.8s.dat", data); fnum = smbcli_nt_create_full(cli->tree, fname, 0, SEC_RIGHTS_FILE_ALL, FILE_ATTRIBUTE_NORMAL, NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OPEN_IF, NTCREATEX_OPTIONS_DELETE_ON_CLOSE, 0); torture_assert_ntstatus_ok_goto(tctx, smbcli_nt_error(cli->tree), ok, done, "create file"); torture_assert_goto(tctx, fnum > 0, ok, done, "create file"); num = smbcli_smbwrite(cli->tree, fnum, data, 0, dlen); torture_assert_int_equal_goto(tctx, num, dlen, ok, done, "write file"); ZERO_STRUCT(io); io.in.sesskey = cli->transport->negotiate.sesskey; io.in.capabilities = cli->transport->negotiate.capabilities; io.in.credentials = cmdline_credentials; io.in.workgroup = lpcfg_workgroup(tctx->lp_ctx); io.in.gensec_settings = lpcfg_gensec_settings(tctx, tctx->lp_ctx); status = smb_composite_sesssetup(cli->session, &io); torture_assert_ntstatus_ok_goto(tctx, status, ok, done, "setup2"); torture_assert_int_equal_goto(tctx, io.out.vuid, vuid1, ok, done, "setup2"); buf[dlen] = '\0'; num = smbcli_read(cli->tree, fnum, &buf, 0, dlen); torture_assert_int_equal_goto(tctx, num, dlen, ok, done, "read file"); torture_assert_str_equal_goto(tctx, buf, data, ok, done, "read file"); done: talloc_free(data); if (fnum > 0) { status = smbcli_close(cli->tree, fnum); torture_assert_ntstatus_ok(tctx, status, "close"); } return ok; }
static bool is_readable(struct smbcli_tree *tree, const char *fname) { int fnum; fnum = smbcli_open(tree, fname, O_RDONLY, DENY_NONE); if (fnum < 0) { return false; } smbcli_close(tree, fnum); return true; }
NTSTATUS gpo_copy_file(TALLOC_CTX *mem_ctx, struct smbcli_state *cli, const char *nt_path, const char *unix_path) { NTSTATUS result; int fnum; int fd = 0; char *data = NULL; static int io_bufsize = 64512; int read_size = io_bufsize; off_t nread = 0; if ((fnum = smbcli_open(cli->tree, nt_path, O_RDONLY, DENY_NONE)) == -1) { result = NT_STATUS_NO_SUCH_FILE; goto out; } if ((fd = open(unix_path, O_WRONLY|O_CREAT|O_TRUNC, 0644)) == -1) { result = map_nt_error_from_unix(errno); goto out; } if ((data = talloc_size(mem_ctx, read_size)) == NULL) { result = NT_STATUS_NO_MEMORY; goto out; } while (1) { int n = smbcli_read(cli->tree, fnum, data, nread, read_size); if (n <= 0) break; if (write(fd, data, n) != n) { break; } nread += n; } result = NT_STATUS_OK; out: SAFE_FREE(data); if (fnum) { smbcli_close(cli->tree, fnum); } if (fd) { close(fd); } return result; }
/* This test checks that 1) the server does not allow an unlink on a file that is open */ BOOL torture_unlinktest(struct torture_context *tctx, struct smbcli_state *cli) { const char *fname = BASEDIR "\\unlink.tst"; int fnum; BOOL correct = True; union smb_open io; NTSTATUS status; torture_assert(tctx, torture_setup_dir(cli, BASEDIR), talloc_asprintf(tctx, "Failed setting up %s", BASEDIR)); cli->session->pid = 1; torture_comment(tctx, "Opening a file\n"); fnum = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE); torture_assert(tctx, fnum != -1, talloc_asprintf(tctx, "open of %s failed (%s)", fname, smbcli_errstr(cli->tree))); torture_comment(tctx, "Unlinking a open file\n"); torture_assert(tctx, !NT_STATUS_IS_OK(smbcli_unlink(cli->tree, fname)), "server allowed unlink on an open file"); correct = check_error(__location__, cli, ERRDOS, ERRbadshare, NT_STATUS_SHARING_VIOLATION); smbcli_close(cli->tree, fnum); smbcli_unlink(cli->tree, fname); torture_comment(tctx, "testing unlink after ntcreatex with DELETE access\n"); io.ntcreatex.level = RAW_OPEN_NTCREATEX; io.ntcreatex.in.root_fid = 0; io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED; io.ntcreatex.in.create_options = NTCREATEX_OPTIONS_NON_DIRECTORY_FILE; io.ntcreatex.in.file_attr = 0; io.ntcreatex.in.alloc_size = 0; io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE; io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_IMPERSONATION; io.ntcreatex.in.security_flags = 0; io.ntcreatex.in.fname = fname; io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_DELETE; io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL; status = smb_raw_open(cli->tree, cli, &io); torture_assert_ntstatus_ok(tctx, status, talloc_asprintf(tctx, "failed to open %s", fname)); torture_assert(tctx, !NT_STATUS_IS_OK(smbcli_unlink(cli->tree, fname)), "server allowed unlink on an open file"); correct = check_error(__location__, cli, ERRDOS, ERRbadshare, NT_STATUS_SHARING_VIOLATION); return correct; }
static bool is_writeable(TALLOC_CTX *mem_ctx, struct smbcli_tree *tree, const char *fname) { int fnum; fnum = smbcli_open(tree, fname, O_WRONLY, DENY_NONE); if (fnum < 0) { return false; } smbcli_close(tree, fnum); return true; }
static BOOL try_close(struct smbcli_state *c, int fstype, int fd) { switch (fstype) { case FSTYPE_SMB: return smbcli_close(c, fd); case FSTYPE_NFS: return close(fd) == 0; } return False; }
static NTSTATUS svc_UploadService(struct tevent_context *ev_ctx, const char *hostname, const char *service_filename, unsigned char *svc32_exe, unsigned int svc32_exe_len, unsigned char *svc64_exe, unsigned int svc64_exe_len, struct cli_credentials *credentials, struct loadparm_context *cllp_ctx, int flags) { struct smb_composite_savefile *io; struct smbcli_state *cli; NTSTATUS status; struct smbcli_options options; struct smbcli_session_options session_options; lpcfg_smbcli_options(cllp_ctx, &options); lpcfg_smbcli_session_options(cllp_ctx, &session_options); status = smbcli_full_connection(NULL, &cli, hostname, lpcfg_smb_ports(cllp_ctx), "ADMIN$", NULL, lpcfg_socket_options(cllp_ctx), credentials, lpcfg_resolve_context(cllp_ctx), ev_ctx, &options, &session_options, lpcfg_gensec_settings(NULL, cllp_ctx)); NT_ERR(status, 1, "Failed to open ADMIN$ share"); if (flags & SVC_FORCE_UPLOAD) { smbcli_unlink(cli->tree, service_filename); } else { int fd = smbcli_open(cli->tree, service_filename, O_RDONLY, DENY_NONE); if (fd >= 0) { smbcli_close(cli->tree, fd); return status; } } io = talloc_zero(cli->tree, struct smb_composite_savefile); io->in.fname = service_filename; if (flags & SVC_OSCHOOSE) { status = smbcli_chkpath(cli->tree, "SysWoW64"); } if (((flags & SVC_OSCHOOSE) && NT_STATUS_IS_OK(status)) || (flags & SVC_OS64BIT)) { DEBUG(1, ("svc_UploadService: Installing 64bit %s\n", service_filename)); io->in.data = svc64_exe; io->in.size = svc64_exe_len; } else { DEBUG(1, ("svc_UploadService: Installing 32bit %s\n", service_filename)); io->in.data = svc32_exe; io->in.size = svc32_exe_len; } status = smb_composite_savefile(cli->tree, io); NT_ERR(status, 1, "Failed to save ADMIN$/%s", io->in.fname); talloc_free(io); smbcli_tdis(cli); return status; }
/* test a write that hits a byte range lock and send the close after the write */ static bool test_mux_write(struct smbcli_state *cli, TALLOC_CTX *mem_ctx) { union smb_write io; NTSTATUS status; int fnum; bool ret = true; struct smbcli_request *req; printf("Testing multiplexed lock/write/close\n"); fnum = smbcli_open(cli->tree, BASEDIR "\\write.dat", O_RDWR | O_CREAT, DENY_NONE); if (fnum == -1) { printf("open failed in mux_write - %s\n", smbcli_errstr(cli->tree)); ret = false; goto done; } cli->session->pid = 1; /* lock a range */ if (NT_STATUS_IS_ERR(smbcli_lock(cli->tree, fnum, 0, 4, 0, WRITE_LOCK))) { printf("lock failed in mux_write - %s\n", smbcli_errstr(cli->tree)); ret = false; goto done; } cli->session->pid = 2; /* send an async write */ io.generic.level = RAW_WRITE_WRITEX; io.writex.in.file.fnum = fnum; io.writex.in.offset = 0; io.writex.in.wmode = 0; io.writex.in.remaining = 0; io.writex.in.count = 4; io.writex.in.data = (const uint8_t *)&fnum; req = smb_raw_write_send(cli->tree, &io); /* unlock the range */ cli->session->pid = 1; smbcli_unlock(cli->tree, fnum, 0, 4); /* and recv the async write reply */ status = smb_raw_write_recv(req, &io); CHECK_STATUS(status, NT_STATUS_FILE_LOCK_CONFLICT); smbcli_close(cli->tree, fnum); done: return ret; }
bool torture_samba3_caseinsensitive(struct torture_context *torture, struct smbcli_state *cli) { TALLOC_CTX *mem_ctx; const char *dirname = "insensitive"; const char *ucase_dirname = "InSeNsItIvE"; const char *fname = "foo"; char *fpath; int fnum; int counter = 0; bool ret = false; if (!(mem_ctx = talloc_init("torture_samba3_caseinsensitive"))) { torture_result(torture, TORTURE_FAIL, "talloc_init failed\n"); return false; } torture_assert(torture, torture_setup_dir(cli, dirname), "creating test directory"); if (!(fpath = talloc_asprintf(mem_ctx, "%s\\%s", dirname, fname))) { goto done; } fnum = smbcli_open(cli->tree, fpath, O_RDWR | O_CREAT, DENY_NONE); if (fnum == -1) { torture_result(torture, TORTURE_FAIL, "Could not create file %s: %s", fpath, smbcli_errstr(cli->tree)); goto done; } smbcli_close(cli->tree, fnum); smbcli_list(cli->tree, talloc_asprintf( mem_ctx, "%s\\*", ucase_dirname), FILE_ATTRIBUTE_DIRECTORY|FILE_ATTRIBUTE_HIDDEN |FILE_ATTRIBUTE_SYSTEM, count_fn, (void *)&counter); if (counter == 3) { ret = true; } else { torture_result(torture, TORTURE_FAIL, "expected 3 entries, got %d", counter); ret = false; } done: talloc_free(mem_ctx); return ret; }
static void testpair(TALLOC_CTX *mem_ctx, struct smbcli_state *cli, char *mask, char *file) { int fnum; char res1[256]; char *res2; static int count; char *short_name = NULL; char *long_name = NULL; struct masktest_state state; count++; safe_strcpy(res1, "---", sizeof(res1)); state.mem_ctx = mem_ctx; fnum = smbcli_open(cli->tree, file, O_CREAT|O_TRUNC|O_RDWR, 0); if (fnum == -1) { DEBUG(0,("Can't create %s\n", file)); return; } smbcli_close(cli->tree, fnum); resultp = res1; short_name = talloc_strdup(mem_ctx, ""); get_real_name(mem_ctx, cli, &long_name, &short_name); safe_strcpy(res1, "---", sizeof(res1)); smbcli_list_new(cli->tree, mask, FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_DIRECTORY, RAW_SEARCH_DATA_BOTH_DIRECTORY_INFO, listfn, &state); res2 = reg_test(cli, mem_ctx, mask, long_name, short_name); if (showall || strcmp(res1, res2)) { d_printf("%s %s %d mask=[%s] file=[%s] rfile=[%s/%s]\n", res1, res2, count, mask, file, long_name, short_name); if (die_on_error) exit(1); } smbcli_unlink(cli->tree, file); if (count % 100 == 0) DEBUG(0,("%d\n", count)); resultp = NULL; }
static void close_files(struct smbcli_state *cli[NSERVERS][NCONNECTIONS], int fnum[NSERVERS][NCONNECTIONS][NFILES]) { int server, conn, f; for (server=0;server<NSERVERS;server++) for (conn=0;conn<NCONNECTIONS;conn++) for (f=0;f<NFILES;f++) { if (fnum[server][conn][f] != -1) { smbcli_close(cli[server][conn]->tree, fnum[server][conn][f]); fnum[server][conn][f] = -1; } } for (server=0;server<NSERVERS;server++) { smbcli_unlink(cli[server][0]->tree, FILENAME); } }
/* check that a stream has the right contents */ static BOOL check_stream(struct smbcli_state *cli, TALLOC_CTX *mem_ctx, const char *fname, const char *sname, const char *value) { int fnum; const char *full_name; uint8_t *buf; ssize_t ret; full_name = talloc_asprintf(mem_ctx, "%s:%s", fname, sname); fnum = smbcli_open(cli->tree, full_name, O_RDONLY, DENY_NONE); if (value == NULL) { if (fnum != -1) { printf("should have failed stream open of %s\n", full_name); return False; } return True; } if (fnum == -1) { printf("Failed to open stream '%s' - %s\n", full_name, smbcli_errstr(cli->tree)); return False; } buf = talloc_size(mem_ctx, strlen(value)+11); ret = smbcli_read(cli->tree, fnum, buf, 0, strlen(value)+11); if (ret != strlen(value)) { printf("Failed to read %lu bytes from stream '%s' - got %d\n", (long)strlen(value), full_name, (int)ret); return False; } if (memcmp(buf, value, strlen(value)) != 0) { printf("Bad data in stream\n"); return False; } smbcli_close(cli->tree, fnum); return True; }
bool torture_raw_qfileinfo_pipe(struct torture_context *torture, struct smbcli_state *cli) { bool ret = true; int fnum; const char *fname = "\\lsass"; union smb_open op; NTSTATUS status; op.ntcreatex.level = RAW_OPEN_NTCREATEX; op.ntcreatex.in.flags = 0; op.ntcreatex.in.root_fid.fnum = 0; op.ntcreatex.in.access_mask = SEC_STD_READ_CONTROL | SEC_FILE_WRITE_ATTRIBUTE | SEC_FILE_WRITE_EA | SEC_FILE_READ_DATA | SEC_FILE_WRITE_DATA; op.ntcreatex.in.file_attr = 0; op.ntcreatex.in.alloc_size = 0; op.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE; op.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN; op.ntcreatex.in.create_options = 0; op.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_IMPERSONATION; op.ntcreatex.in.security_flags = 0; op.ntcreatex.in.fname = fname; status = smb_raw_open(cli->tree, torture, &op); torture_assert_ntstatus_ok(torture, status, "smb_raw_open failed"); fnum = op.ntcreatex.out.file.fnum; ret = torture_raw_qfileinfo_internals(torture, torture, cli->tree, fnum, fname, true /* is_ipc */); smbcli_close(cli->tree, fnum); return ret; }
/* test directory listing speed */ bool torture_dirtest1(struct torture_context *tctx, struct smbcli_state *cli) { int i; int fnum; bool correct = true; extern int torture_numops; struct timeval tv; torture_comment(tctx, "Creating %d random filenames\n", torture_numops); srandom(0); tv = timeval_current(); for (i=0;i<torture_numops;i++) { char *fname; asprintf(&fname, "\\%x", (int)random()); fnum = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT, DENY_NONE); if (fnum == -1) { fprintf(stderr,"(%s) Failed to open %s\n", __location__, fname); return false; } smbcli_close(cli->tree, fnum); free(fname); } torture_comment(tctx, "Matched %d\n", smbcli_list(cli->tree, "a*.*", 0, list_fn, NULL)); torture_comment(tctx, "Matched %d\n", smbcli_list(cli->tree, "b*.*", 0, list_fn, NULL)); torture_comment(tctx, "Matched %d\n", smbcli_list(cli->tree, "xyzabc", 0, list_fn, NULL)); torture_comment(tctx, "dirtest core %g seconds\n", timeval_elapsed(&tv)); srandom(0); for (i=0;i<torture_numops;i++) { char *fname; asprintf(&fname, "\\%x", (int)random()); smbcli_unlink(cli->tree, fname); free(fname); } return correct; }
/* basic testing of all RAW_FILEINFO_* calls for each call we test that it succeeds, and where possible test for consistency between the calls. */ bool torture_raw_qfileinfo(struct torture_context *torture, struct smbcli_state *cli) { int fnum; bool ret; const char *fname = "\\torture_qfileinfo.txt"; fnum = create_complex_file(cli, torture, fname); if (fnum == -1) { printf("ERROR: open of %s failed (%s)\n", fname, smbcli_errstr(cli->tree)); return false; } ret = torture_raw_qfileinfo_internals(torture, torture, cli->tree, fnum, fname, false /* is_ipc */); smbcli_close(cli->tree, fnum); smbcli_unlink(cli->tree, fname); return ret; }
/* test the delayed reply to a open that leads to a sharing violation */ static bool test_mux_open(struct smbcli_state *cli, TALLOC_CTX *mem_ctx) { union smb_open io; NTSTATUS status; int fnum1, fnum2; bool ret = true; struct smbcli_request *req1, *req2; struct timeval tv; double d; printf("Testing multiplexed open/open/close\n"); printf("send first open\n"); io.generic.level = RAW_OPEN_NTCREATEX; io.ntcreatex.in.root_fid.fnum = 0; io.ntcreatex.in.flags = 0; io.ntcreatex.in.access_mask = SEC_FILE_READ_DATA; io.ntcreatex.in.create_options = 0; io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL; io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ; io.ntcreatex.in.alloc_size = 0; io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE; io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS; io.ntcreatex.in.security_flags = 0; io.ntcreatex.in.fname = BASEDIR "\\open.dat"; status = smb_raw_open(cli->tree, mem_ctx, &io); CHECK_STATUS(status, NT_STATUS_OK); fnum1 = io.ntcreatex.out.file.fnum; printf("send 2nd open, non-conflicting\n"); io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN; status = smb_raw_open(cli->tree, mem_ctx, &io); CHECK_STATUS(status, NT_STATUS_OK); fnum2 = io.ntcreatex.out.file.fnum; tv = timeval_current(); printf("send 3rd open, conflicting\n"); io.ntcreatex.in.share_access = 0; status = smb_raw_open(cli->tree, mem_ctx, &io); CHECK_STATUS(status, NT_STATUS_SHARING_VIOLATION); d = timeval_elapsed(&tv); if (d < 0.5 || d > 1.5) { printf("bad timeout for conflict - %.2f should be 1.0\n", d); } else { printf("open delay %.2f\n", d); } printf("send async open, conflicting\n"); tv = timeval_current(); req1 = smb_raw_open_send(cli->tree, &io); printf("send 2nd async open, conflicting\n"); tv = timeval_current(); req2 = smb_raw_open_send(cli->tree, &io); printf("close first sync open\n"); smbcli_close(cli->tree, fnum1); printf("cancel 2nd async open (should be ignored)\n"); smb_raw_ntcancel(req2); d = timeval_elapsed(&tv); if (d > 0.25) { printf("bad timeout after cancel - %.2f should be <0.25\n", d); ret = false; } printf("close the 2nd sync open\n"); smbcli_close(cli->tree, fnum2); printf("see if the 1st async open now succeeded\n"); status = smb_raw_open_recv(req1, mem_ctx, &io); CHECK_STATUS(status, NT_STATUS_OK); d = timeval_elapsed(&tv); if (d > 0.25) { printf("bad timeout for async conflict - %.2f should be <0.25\n", d); ret = false; } else { printf("async open delay %.2f\n", d); } printf("2nd async open should have timed out\n"); status = smb_raw_open_recv(req2, mem_ctx, &io); CHECK_STATUS(status, NT_STATUS_SHARING_VIOLATION); d = timeval_elapsed(&tv); if (d < 0.8) { printf("bad timeout for async conflict - %.2f should be 1.0\n", d); } printf("close the 1st async open\n"); smbcli_close(cli->tree, io.ntcreatex.out.file.fnum); done: return ret; }
/* test dir rename. */ static bool test_dir_rename(struct torture_context *tctx, struct smbcli_state *cli) { union smb_open io; union smb_rename ren_io; NTSTATUS status; const char *dname1 = BASEDIR "\\dir_for_rename"; const char *dname2 = BASEDIR "\\renamed_dir"; const char *dname1_long = BASEDIR "\\dir_for_rename_long"; const char *fname = BASEDIR "\\dir_for_rename\\file.txt"; const char *sname = BASEDIR "\\renamed_dir:a stream:$DATA"; bool ret = true; int fnum = -1; torture_comment(tctx, "Checking rename on a directory containing an open file.\n"); if (!torture_setup_dir(cli, BASEDIR)) { return false; } /* create a directory */ smbcli_rmdir(cli->tree, dname1); smbcli_rmdir(cli->tree, dname2); smbcli_rmdir(cli->tree, dname1_long); smbcli_unlink(cli->tree, dname1); smbcli_unlink(cli->tree, dname2); smbcli_unlink(cli->tree, dname1_long); ZERO_STRUCT(io); io.generic.level = RAW_OPEN_NTCREATEX; io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE; io.ntcreatex.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED; io.ntcreatex.in.alloc_size = 0; io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL; io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE; io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE; io.ntcreatex.in.create_options = NTCREATEX_OPTIONS_DIRECTORY; io.ntcreatex.in.fname = dname1; status = smb_raw_open(cli->tree, tctx, &io); CHECK_STATUS(status, NT_STATUS_OK); fnum = io.ntcreatex.out.file.fnum; smbcli_close(cli->tree, fnum); /* create the longname directory */ io.ntcreatex.in.fname = dname1_long; status = smb_raw_open(cli->tree, tctx, &io); CHECK_STATUS(status, NT_STATUS_OK); fnum = io.ntcreatex.out.file.fnum; smbcli_close(cli->tree, fnum); /* Now create and hold open a file. */ ZERO_STRUCT(io); io.generic.level = RAW_OPEN_NTCREATEX; io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED; io.ntcreatex.in.root_fid.fnum = 0; io.ntcreatex.in.alloc_size = 0; io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL; io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL; io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE | NTCREATEX_SHARE_ACCESS_DELETE; io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE; io.ntcreatex.in.create_options = 0; io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS; io.ntcreatex.in.security_flags = 0; io.ntcreatex.in.fname = fname; /* Create the file. */ status = smb_raw_open(cli->tree, tctx, &io); CHECK_STATUS(status, NT_STATUS_OK); fnum = io.ntcreatex.out.file.fnum; /* Now try and rename the directory. */ ZERO_STRUCT(ren_io); ren_io.generic.level = RAW_RENAME_RENAME; ren_io.rename.in.pattern1 = dname1; ren_io.rename.in.pattern2 = dname2; ren_io.rename.in.attrib = 0; status = smb_raw_rename(cli->tree, &ren_io); CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED); /* Close the file and try the rename. */ smbcli_close(cli->tree, fnum); status = smb_raw_rename(cli->tree, &ren_io); CHECK_STATUS(status, NT_STATUS_OK); /* * Now try just holding a second handle on the directory and holding * it open across a rename. This should be allowed. */ io.ntcreatex.in.fname = dname2; io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF; io.ntcreatex.in.access_mask = SEC_STD_READ_CONTROL | SEC_FILE_READ_ATTRIBUTE | SEC_FILE_READ_EA | SEC_FILE_READ_DATA; status = smb_raw_open(cli->tree, tctx, &io); CHECK_STATUS(status, NT_STATUS_OK); fnum = io.ntcreatex.out.file.fnum; ren_io.generic.level = RAW_RENAME_RENAME; ren_io.rename.in.pattern1 = dname2; ren_io.rename.in.pattern2 = dname1; ren_io.rename.in.attrib = 0; status = smb_raw_rename(cli->tree, &ren_io); CHECK_STATUS(status, NT_STATUS_OK); /* close our handle to the directory. */ smbcli_close(cli->tree, fnum); /* Open a handle on the long name, and then * try a rename. This would catch a regression * in bug #6781. */ io.ntcreatex.in.fname = dname1_long; io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF; io.ntcreatex.in.access_mask = SEC_STD_READ_CONTROL | SEC_FILE_READ_ATTRIBUTE | SEC_FILE_READ_EA | SEC_FILE_READ_DATA; status = smb_raw_open(cli->tree, tctx, &io); CHECK_STATUS(status, NT_STATUS_OK); fnum = io.ntcreatex.out.file.fnum; ren_io.generic.level = RAW_RENAME_RENAME; ren_io.rename.in.pattern1 = dname1; ren_io.rename.in.pattern2 = dname2; ren_io.rename.in.attrib = 0; status = smb_raw_rename(cli->tree, &ren_io); CHECK_STATUS(status, NT_STATUS_OK); /* close our handle to the longname directory. */ smbcli_close(cli->tree, fnum); /* * Now try opening a stream on the directory and holding it open * across a rename. This should be allowed. */ io.ntcreatex.in.fname = sname; status = smb_raw_open(cli->tree, tctx, &io); CHECK_STATUS(status, NT_STATUS_OK); fnum = io.ntcreatex.out.file.fnum; ren_io.generic.level = RAW_RENAME_RENAME; ren_io.rename.in.pattern1 = dname2; ren_io.rename.in.pattern2 = dname1; ren_io.rename.in.attrib = 0; status = smb_raw_rename(cli->tree, &ren_io); CHECK_STATUS(status, NT_STATUS_OK); done: if (fnum != -1) { smbcli_close(cli->tree, fnum); } smb_raw_exit(cli->session); smbcli_deltree(cli->tree, BASEDIR); return ret; }
/* test SMBntrename ops */ static bool test_ntrename(struct torture_context *tctx, struct smbcli_state *cli) { union smb_rename io; NTSTATUS status; bool ret = true; int fnum, i; const char *fname1 = BASEDIR "\\test1.txt"; const char *fname2 = BASEDIR "\\test2.txt"; union smb_fileinfo finfo; torture_comment(tctx, "Testing SMBntrename\n"); if (!torture_setup_dir(cli, BASEDIR)) { return false; } torture_comment(tctx, "Trying simple rename\n"); fnum = create_complex_file(cli, tctx, fname1); io.generic.level = RAW_RENAME_NTRENAME; io.ntrename.in.old_name = fname1; io.ntrename.in.new_name = fname2; io.ntrename.in.attrib = 0; io.ntrename.in.cluster_size = 0; io.ntrename.in.flags = RENAME_FLAG_RENAME; status = smb_raw_rename(cli->tree, &io); CHECK_STATUS(status, NT_STATUS_SHARING_VIOLATION); smbcli_close(cli->tree, fnum); status = smb_raw_rename(cli->tree, &io); CHECK_STATUS(status, NT_STATUS_OK); torture_comment(tctx, "Trying self rename\n"); io.ntrename.in.old_name = fname2; io.ntrename.in.new_name = fname2; status = smb_raw_rename(cli->tree, &io); CHECK_STATUS(status, NT_STATUS_OK); io.ntrename.in.old_name = fname1; io.ntrename.in.new_name = fname1; status = smb_raw_rename(cli->tree, &io); CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_NOT_FOUND); torture_comment(tctx, "trying wildcard rename\n"); io.ntrename.in.old_name = BASEDIR "\\*.txt"; io.ntrename.in.new_name = fname1; status = smb_raw_rename(cli->tree, &io); CHECK_STATUS(status, NT_STATUS_OBJECT_PATH_SYNTAX_BAD); torture_comment(tctx, "Checking attrib handling\n"); torture_set_file_attribute(cli->tree, fname2, FILE_ATTRIBUTE_HIDDEN); io.ntrename.in.old_name = fname2; io.ntrename.in.new_name = fname1; io.ntrename.in.attrib = 0; status = smb_raw_rename(cli->tree, &io); CHECK_STATUS(status, NT_STATUS_NO_SUCH_FILE); io.ntrename.in.attrib = FILE_ATTRIBUTE_HIDDEN; status = smb_raw_rename(cli->tree, &io); CHECK_STATUS(status, NT_STATUS_OK); torture_set_file_attribute(cli->tree, fname1, FILE_ATTRIBUTE_NORMAL); torture_comment(tctx, "Checking hard link\n"); io.ntrename.in.old_name = fname1; io.ntrename.in.new_name = fname2; io.ntrename.in.attrib = 0; io.ntrename.in.flags = RENAME_FLAG_HARD_LINK; status = smb_raw_rename(cli->tree, &io); CHECK_STATUS(status, NT_STATUS_OK); torture_set_file_attribute(cli->tree, fname1, FILE_ATTRIBUTE_SYSTEM); finfo.generic.level = RAW_FILEINFO_ALL_INFO; finfo.generic.in.file.path = fname2; status = smb_raw_pathinfo(cli->tree, tctx, &finfo); CHECK_STATUS(status, NT_STATUS_OK); CHECK_VALUE(finfo.all_info.out.nlink, 2); CHECK_VALUE(finfo.all_info.out.attrib, FILE_ATTRIBUTE_SYSTEM); finfo.generic.in.file.path = fname1; status = smb_raw_pathinfo(cli->tree, tctx, &finfo); CHECK_STATUS(status, NT_STATUS_OK); CHECK_VALUE(finfo.all_info.out.nlink, 2); CHECK_VALUE(finfo.all_info.out.attrib, FILE_ATTRIBUTE_SYSTEM); torture_set_file_attribute(cli->tree, fname1, FILE_ATTRIBUTE_NORMAL); smbcli_unlink(cli->tree, fname2); finfo.generic.in.file.path = fname1; status = smb_raw_pathinfo(cli->tree, tctx, &finfo); CHECK_STATUS(status, NT_STATUS_OK); CHECK_VALUE(finfo.all_info.out.nlink, 1); CHECK_VALUE(finfo.all_info.out.attrib, FILE_ATTRIBUTE_NORMAL); torture_comment(tctx, "Checking copy\n"); io.ntrename.in.old_name = fname1; io.ntrename.in.new_name = fname2; io.ntrename.in.attrib = 0; io.ntrename.in.flags = RENAME_FLAG_COPY; status = smb_raw_rename(cli->tree, &io); CHECK_STATUS(status, NT_STATUS_OK); finfo.generic.level = RAW_FILEINFO_ALL_INFO; finfo.generic.in.file.path = fname1; status = smb_raw_pathinfo(cli->tree, tctx, &finfo); CHECK_STATUS(status, NT_STATUS_OK); CHECK_VALUE(finfo.all_info.out.nlink, 1); CHECK_VALUE(finfo.all_info.out.attrib, FILE_ATTRIBUTE_NORMAL); finfo.generic.level = RAW_FILEINFO_ALL_INFO; finfo.generic.in.file.path = fname2; status = smb_raw_pathinfo(cli->tree, tctx, &finfo); CHECK_STATUS(status, NT_STATUS_OK); CHECK_VALUE(finfo.all_info.out.nlink, 1); CHECK_VALUE(finfo.all_info.out.attrib, FILE_ATTRIBUTE_NORMAL); torture_set_file_attribute(cli->tree, fname1, FILE_ATTRIBUTE_SYSTEM); finfo.generic.level = RAW_FILEINFO_ALL_INFO; finfo.generic.in.file.path = fname2; status = smb_raw_pathinfo(cli->tree, tctx, &finfo); CHECK_STATUS(status, NT_STATUS_OK); CHECK_VALUE(finfo.all_info.out.nlink, 1); CHECK_VALUE(finfo.all_info.out.attrib, FILE_ATTRIBUTE_NORMAL); finfo.generic.in.file.path = fname1; status = smb_raw_pathinfo(cli->tree, tctx, &finfo); CHECK_STATUS(status, NT_STATUS_OK); CHECK_VALUE(finfo.all_info.out.nlink, 1); CHECK_VALUE(finfo.all_info.out.attrib, FILE_ATTRIBUTE_SYSTEM); torture_set_file_attribute(cli->tree, fname1, FILE_ATTRIBUTE_NORMAL); smbcli_unlink(cli->tree, fname2); finfo.generic.in.file.path = fname1; status = smb_raw_pathinfo(cli->tree, tctx, &finfo); CHECK_STATUS(status, NT_STATUS_OK); CHECK_VALUE(finfo.all_info.out.nlink, 1); torture_comment(tctx, "Checking invalid flags\n"); io.ntrename.in.old_name = fname1; io.ntrename.in.new_name = fname2; io.ntrename.in.attrib = 0; io.ntrename.in.flags = 0; status = smb_raw_rename(cli->tree, &io); if (TARGET_IS_WIN7(tctx)) { CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER); } else { CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED); } io.ntrename.in.flags = 300; status = smb_raw_rename(cli->tree, &io); if (TARGET_IS_WIN7(tctx)) { CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER); } else { CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED); } io.ntrename.in.flags = 0x106; status = smb_raw_rename(cli->tree, &io); if (TARGET_IS_WIN7(tctx)) { CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER); } else { CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED); } torture_comment(tctx, "Checking unknown field\n"); io.ntrename.in.old_name = fname1; io.ntrename.in.new_name = fname2; io.ntrename.in.attrib = 0; io.ntrename.in.flags = RENAME_FLAG_RENAME; io.ntrename.in.cluster_size = 0xff; status = smb_raw_rename(cli->tree, &io); CHECK_STATUS(status, NT_STATUS_OK); torture_comment(tctx, "Trying RENAME_FLAG_MOVE_CLUSTER_INFORMATION\n"); io.ntrename.in.old_name = fname2; io.ntrename.in.new_name = fname1; io.ntrename.in.attrib = 0; io.ntrename.in.flags = RENAME_FLAG_MOVE_CLUSTER_INFORMATION; io.ntrename.in.cluster_size = 1; status = smb_raw_rename(cli->tree, &io); CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER); io.ntrename.in.flags = RENAME_FLAG_COPY; status = smb_raw_rename(cli->tree, &io); CHECK_STATUS(status, NT_STATUS_OK); #if 0 { char buf[16384]; fnum = smbcli_open(cli->tree, fname1, O_RDWR, DENY_NONE); memset(buf, 1, sizeof(buf)); smbcli_write(cli->tree, fnum, 0, buf, 0, sizeof(buf)); smbcli_close(cli->tree, fnum); fnum = smbcli_open(cli->tree, fname2, O_RDWR, DENY_NONE); memset(buf, 1, sizeof(buf)); smbcli_write(cli->tree, fnum, 0, buf, 0, sizeof(buf)-1); smbcli_close(cli->tree, fnum); torture_all_info(cli->tree, fname1); torture_all_info(cli->tree, fname2); } io.ntrename.in.flags = RENAME_FLAG_MOVE_CLUSTER_INFORMATION; status = smb_raw_rename(cli->tree, &io); CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER); for (i=0; i<20000; i++) { io.ntrename.in.cluster_size = i; status = smb_raw_rename(cli->tree, &io); if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) { torture_warning(tctx, "i=%d status=%s\n", i, nt_errstr(status)); } } #endif torture_comment(tctx, "Checking other flags\n"); for (i=0; i<0xFFF; i++) { if (i == RENAME_FLAG_RENAME || i == RENAME_FLAG_HARD_LINK || i == RENAME_FLAG_COPY) { continue; } io.ntrename.in.old_name = fname2; io.ntrename.in.new_name = fname1; io.ntrename.in.flags = i; io.ntrename.in.attrib = 0; io.ntrename.in.cluster_size = 0; status = smb_raw_rename(cli->tree, &io); if (TARGET_IS_WIN7(tctx)) { if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) { torture_warning(tctx, "flags=0x%x status=%s\n", i, nt_errstr(status)); } } else { if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) { torture_warning(tctx, "flags=0x%x status=%s\n", i, nt_errstr(status)); } } } done: smb_raw_exit(cli->session); smbcli_deltree(cli->tree, BASEDIR); return ret; }
/* test SMBmv ops */ static bool test_mv(struct torture_context *tctx, struct smbcli_state *cli) { union smb_rename io; NTSTATUS status; bool ret = true; int fnum = -1; const char *fname1 = BASEDIR "\\test1.txt"; const char *fname2 = BASEDIR "\\test2.txt"; const char *Fname1 = BASEDIR "\\Test1.txt"; union smb_fileinfo finfo; union smb_open op; torture_comment(tctx, "Testing SMBmv\n"); if (!torture_setup_dir(cli, BASEDIR)) { return false; } torture_comment(tctx, "Trying simple rename\n"); op.generic.level = RAW_OPEN_NTCREATEX; op.ntcreatex.in.root_fid.fnum = 0; op.ntcreatex.in.flags = 0; op.ntcreatex.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED; op.ntcreatex.in.create_options = 0; op.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL; op.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE; op.ntcreatex.in.alloc_size = 0; op.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF; op.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS; op.ntcreatex.in.security_flags = 0; op.ntcreatex.in.fname = fname1; status = smb_raw_open(cli->tree, tctx, &op); CHECK_STATUS(status, NT_STATUS_OK); fnum = op.ntcreatex.out.file.fnum; io.generic.level = RAW_RENAME_RENAME; io.rename.in.pattern1 = fname1; io.rename.in.pattern2 = fname2; io.rename.in.attrib = 0; torture_comment(tctx, "trying rename while first file open\n"); status = smb_raw_rename(cli->tree, &io); CHECK_STATUS(status, NT_STATUS_SHARING_VIOLATION); smbcli_close(cli->tree, fnum); op.ntcreatex.in.access_mask = SEC_FILE_READ_DATA; op.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_DELETE | NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE; status = smb_raw_open(cli->tree, tctx, &op); CHECK_STATUS(status, NT_STATUS_OK); fnum = op.ntcreatex.out.file.fnum; torture_comment(tctx, "trying rename while first file open with SHARE_ACCESS_DELETE\n"); status = smb_raw_rename(cli->tree, &io); CHECK_STATUS(status, NT_STATUS_OK); io.rename.in.pattern1 = fname2; io.rename.in.pattern2 = fname1; status = smb_raw_rename(cli->tree, &io); CHECK_STATUS(status, NT_STATUS_OK); torture_comment(tctx, "Trying case-changing rename\n"); io.rename.in.pattern1 = fname1; io.rename.in.pattern2 = Fname1; status = smb_raw_rename(cli->tree, &io); CHECK_STATUS(status, NT_STATUS_OK); finfo.generic.level = RAW_FILEINFO_ALL_INFO; finfo.all_info.in.file.path = fname1; status = smb_raw_pathinfo(cli->tree, tctx, &finfo); CHECK_STATUS(status, NT_STATUS_OK); if (strcmp(finfo.all_info.out.fname.s, Fname1) != 0) { torture_warning(tctx, "(%s) Incorrect filename [%s] after case-changing " "rename, should be [%s]\n", __location__, finfo.all_info.out.fname.s, Fname1); } io.rename.in.pattern1 = fname1; io.rename.in.pattern2 = fname2; torture_comment(tctx, "trying rename while not open\n"); smb_raw_exit(cli->session); status = smb_raw_rename(cli->tree, &io); CHECK_STATUS(status, NT_STATUS_OK); torture_comment(tctx, "Trying self rename\n"); io.rename.in.pattern1 = fname2; io.rename.in.pattern2 = fname2; status = smb_raw_rename(cli->tree, &io); CHECK_STATUS(status, NT_STATUS_OK); io.rename.in.pattern1 = fname1; io.rename.in.pattern2 = fname1; status = smb_raw_rename(cli->tree, &io); CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_NOT_FOUND); torture_comment(tctx, "trying wildcard rename\n"); io.rename.in.pattern1 = BASEDIR "\\*.txt"; io.rename.in.pattern2 = fname1; status = smb_raw_rename(cli->tree, &io); CHECK_STATUS(status, NT_STATUS_OK); torture_comment(tctx, "and again\n"); status = smb_raw_rename(cli->tree, &io); CHECK_STATUS(status, NT_STATUS_OK); torture_comment(tctx, "Trying extension change\n"); io.rename.in.pattern1 = BASEDIR "\\*.txt"; io.rename.in.pattern2 = BASEDIR "\\*.bak"; status = smb_raw_rename(cli->tree, &io); CHECK_STATUS(status, NT_STATUS_OK); status = smb_raw_rename(cli->tree, &io); CHECK_STATUS(status, NT_STATUS_NO_SUCH_FILE); torture_comment(tctx, "Checking attrib handling\n"); torture_set_file_attribute(cli->tree, BASEDIR "\\test1.bak", FILE_ATTRIBUTE_HIDDEN); io.rename.in.pattern1 = BASEDIR "\\test1.bak"; io.rename.in.pattern2 = BASEDIR "\\*.txt"; io.rename.in.attrib = 0; status = smb_raw_rename(cli->tree, &io); CHECK_STATUS(status, NT_STATUS_NO_SUCH_FILE); io.rename.in.attrib = FILE_ATTRIBUTE_HIDDEN; status = smb_raw_rename(cli->tree, &io); CHECK_STATUS(status, NT_STATUS_OK); done: smbcli_close(cli->tree, fnum); smb_raw_exit(cli->session); smbcli_deltree(cli->tree, BASEDIR); return ret; }