From 75c0125fb71b0562e7bdd85c391764796b5f12f6 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 13 Aug 2003 16:04:21 +0000 Subject: - added SMBntrename test suite - allow username of form DOMAIN\username or DOMAIN/username - added ntrename to gentest (This used to be commit 2b464472c17b791eb5b117f89d5aaea2bf60f6ad) --- source4/include/ntvfs.h | 2 +- source4/include/smb.h | 6 ++ source4/include/smb_interfaces.h | 35 ++++++- source4/libcli/cliconnect.c | 15 ++- source4/libcli/clifile.c | 9 +- source4/libcli/namequery.c | 2 +- source4/libcli/raw/rawfile.c | 27 +++-- source4/ntvfs/cifs/vfs_cifs.c | 2 +- source4/ntvfs/ipc/vfs_ipc.c | 2 +- source4/ntvfs/reference/vfs_ref.c | 2 +- source4/ntvfs/simple/vfs_simple.c | 10 +- source4/smbd/reply.c | 11 +- source4/torture/gentest.c | 43 +++++++- source4/torture/raw/missing.txt | 1 + source4/torture/raw/rename.c | 208 +++++++++++++++++++++++++++++++++++--- source4/torture/torture.c | 46 +++++---- 16 files changed, 352 insertions(+), 69 deletions(-) diff --git a/source4/include/ntvfs.h b/source4/include/ntvfs.h index edec2a7e53..2b1f519b32 100644 --- a/source4/include/ntvfs.h +++ b/source4/include/ntvfs.h @@ -44,7 +44,7 @@ struct ntvfs_ops { NTSTATUS (*open)(struct request_context *req, union smb_open *oi); NTSTATUS (*mkdir)(struct request_context *req, union smb_mkdir *md); NTSTATUS (*rmdir)(struct request_context *req, struct smb_rmdir *rd); - NTSTATUS (*rename)(struct request_context *req, struct smb_rename *ren); + NTSTATUS (*rename)(struct request_context *req, union smb_rename *ren); NTSTATUS (*copy)(struct request_context *req, struct smb_copy *cp); /* directory search */ diff --git a/source4/include/smb.h b/source4/include/smb.h index 682d392c0f..931f4793c9 100644 --- a/source4/include/smb.h +++ b/source4/include/smb.h @@ -883,6 +883,7 @@ struct bitmap { #define SMBnttranss 0xA1 /* NT transact secondary */ #define SMBntcreateX 0xA2 /* NT create and X */ #define SMBntcancel 0xA4 /* NT cancel */ +#define SMBntrename 0xA5 /* NT rename */ /* used to indicate end of chain */ #define SMB_CHAIN_NONE 0xFF @@ -968,6 +969,11 @@ struct bitmap { /* Flag for NT transact rename call. */ #define RENAME_REPLACE_IF_EXISTS 1 +/* flags for SMBntrename call */ +#define RENAME_FLAG_HARD_LINK 0x103 +#define RENAME_FLAG_RENAME 0x104 +#define RENAME_FLAG_COPY 0x105 + /* Filesystem Attributes. */ #define FILE_CASE_SENSITIVE_SEARCH 0x01 #define FILE_CASE_PRESERVED_NAMES 0x02 diff --git a/source4/include/smb_interfaces.h b/source4/include/smb_interfaces.h index 70cff11395..f010883f18 100644 --- a/source4/include/smb_interfaces.h +++ b/source4/include/smb_interfaces.h @@ -125,12 +125,37 @@ struct smb_rmdir { }; /* struct used in rename() call */ -struct smb_rename { +enum rename_level {RAW_RENAME_RENAME, RAW_RENAME_NTRENAME}; + +union smb_rename { struct { - const char *pattern1; - const char *pattern2; - uint16 attrib; - } in; + enum rename_level level; + } generic; + + /* SMBrename interface */ + struct { + enum rename_level level; + + struct { + const char *pattern1; + const char *pattern2; + uint16 attrib; + } in; + } rename; + + + /* SMBntrename interface */ + struct { + enum rename_level level; + + struct { + uint16 attrib; + uint16 flags; /* see RENAME_FLAG_* */ + uint32 root_fid; /* is it? */ + const char *old_name; + const char *new_name; + } in; + } ntrename; }; enum tcon_level {RAW_TCON_TCON, RAW_TCON_TCONX}; diff --git a/source4/libcli/cliconnect.c b/source4/libcli/cliconnect.c index da8a842dae..03112176d4 100644 --- a/source4/libcli/cliconnect.c +++ b/source4/libcli/cliconnect.c @@ -146,13 +146,24 @@ NTSTATUS cli_full_connection(struct cli_state **ret_cli, { struct cli_tree *tree; NTSTATUS status; + char *p; + TALLOC_CTX *mem_ctx; + + mem_ctx = talloc_init("cli_full_connection"); *ret_cli = NULL; + /* if the username is of the form DOMAIN\username then split out the domain */ + p = strpbrk(username, "\\/"); + if (p) { + domain = talloc_strndup(mem_ctx, username, PTR_DIFF(p, username)); + username = talloc_strdup(mem_ctx, p+1); + } + status = cli_tree_full_connection(&tree, myname, host, 0, sharename, devtype, username, domain, password); if (!NT_STATUS_IS_OK(status)) { - return status; + goto done; } (*ret_cli) = cli_state_init(); @@ -162,6 +173,8 @@ NTSTATUS cli_full_connection(struct cli_state **ret_cli, (*ret_cli)->transport = tree->session->transport; tree->reference_count++; +done: + talloc_destroy(mem_ctx); return status; } diff --git a/source4/libcli/clifile.c b/source4/libcli/clifile.c index c203e4633d..cd01d51017 100644 --- a/source4/libcli/clifile.c +++ b/source4/libcli/clifile.c @@ -137,11 +137,12 @@ BOOL cli_unix_chown(struct cli_state *cli, const char *fname, uid_t uid, gid_t g ****************************************************************************/ BOOL cli_rename(struct cli_state *cli, const char *fname_src, const char *fname_dst) { - struct smb_rename parms; + union smb_rename parms; - parms.in.attrib = FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_DIRECTORY; - parms.in.pattern1 = fname_src; - parms.in.pattern2 = fname_dst; + parms.generic.level = RAW_RENAME_RENAME; + parms.rename.in.attrib = FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_DIRECTORY; + parms.rename.in.pattern1 = fname_src; + parms.rename.in.pattern2 = fname_dst; return NT_STATUS_IS_OK(smb_raw_rename(cli->tree, &parms)); } diff --git a/source4/libcli/namequery.c b/source4/libcli/namequery.c index 2f6343dcaf..a04e883138 100644 --- a/source4/libcli/namequery.c +++ b/source4/libcli/namequery.c @@ -801,7 +801,7 @@ static BOOL internal_resolve_name(TALLOC_CTX *mem_ctx, const char *name, int nam } } else if(strequal( tok, "lmhosts")) { /* REWRITE: add back in? */ - DEBUG(0,("resolve_name: REWRITE: add lmhosts back?? %s\n", tok)); + DEBUG(2,("resolve_name: REWRITE: add lmhosts back?? %s\n", tok)); } else if(strequal( tok, "wins")) { /* don't resolve 1D via WINS */ if (name_type != 0x1D && diff --git a/source4/libcli/raw/rawfile.c b/source4/libcli/raw/rawfile.c index 279dfcf0c1..57b6ded66f 100644 --- a/source4/libcli/raw/rawfile.c +++ b/source4/libcli/raw/rawfile.c @@ -32,16 +32,27 @@ Rename a file - async interface ****************************************************************************/ struct cli_request *smb_raw_rename_send(struct cli_tree *tree, - struct smb_rename *parms) + union smb_rename *parms) { struct cli_request *req; - SETUP_REQUEST(SMBmv, 1, 0); - - SSVAL(req->out.vwv, VWV(0), parms->in.attrib); - - cli_req_append_ascii4(req, parms->in.pattern1, STR_TERMINATE); - cli_req_append_ascii4(req, parms->in.pattern2, STR_TERMINATE); + switch (parms->generic.level) { + case RAW_RENAME_RENAME: + SETUP_REQUEST(SMBmv, 1, 0); + SSVAL(req->out.vwv, VWV(0), parms->rename.in.attrib); + cli_req_append_ascii4(req, parms->rename.in.pattern1, STR_TERMINATE); + cli_req_append_ascii4(req, parms->rename.in.pattern2, STR_TERMINATE); + break; + + case RAW_RENAME_NTRENAME: + SETUP_REQUEST(SMBntrename, 4, 0); + SSVAL(req->out.vwv, VWV(0), parms->ntrename.in.attrib); + SSVAL(req->out.vwv, VWV(1), parms->ntrename.in.flags); + SIVAL(req->out.vwv, VWV(2), parms->ntrename.in.root_fid); + cli_req_append_ascii4(req, parms->ntrename.in.old_name, STR_TERMINATE); + cli_req_append_ascii4(req, parms->ntrename.in.new_name, STR_TERMINATE); + break; + } if (!cli_request_send(req)) { cli_request_destroy(req); @@ -55,7 +66,7 @@ struct cli_request *smb_raw_rename_send(struct cli_tree *tree, Rename a file - sync interface ****************************************************************************/ NTSTATUS smb_raw_rename(struct cli_tree *tree, - struct smb_rename *parms) + union smb_rename *parms) { struct cli_request *req = smb_raw_rename_send(tree, parms); return cli_request_simple_recv(req); diff --git a/source4/ntvfs/cifs/vfs_cifs.c b/source4/ntvfs/cifs/vfs_cifs.c index 9a17336519..1afdb66a1c 100644 --- a/source4/ntvfs/cifs/vfs_cifs.c +++ b/source4/ntvfs/cifs/vfs_cifs.c @@ -424,7 +424,7 @@ static NTSTATUS cvfs_rmdir(struct request_context *req, struct smb_rmdir *rd) /* rename a set of files */ -static NTSTATUS cvfs_rename(struct request_context *req, struct smb_rename *ren) +static NTSTATUS cvfs_rename(struct request_context *req, union smb_rename *ren) { struct cvfs_private *private = req->conn->ntvfs_private; struct cli_request *c_req; diff --git a/source4/ntvfs/ipc/vfs_ipc.c b/source4/ntvfs/ipc/vfs_ipc.c index fe310d104e..b13c358dd5 100644 --- a/source4/ntvfs/ipc/vfs_ipc.c +++ b/source4/ntvfs/ipc/vfs_ipc.c @@ -114,7 +114,7 @@ static NTSTATUS ipc_rmdir(struct request_context *req, struct smb_rmdir *rd) /* rename a set of files */ -static NTSTATUS ipc_rename(struct request_context *req, struct smb_rename *ren) +static NTSTATUS ipc_rename(struct request_context *req, union smb_rename *ren) { return NT_STATUS_ACCESS_DENIED; } diff --git a/source4/ntvfs/reference/vfs_ref.c b/source4/ntvfs/reference/vfs_ref.c index b4fa2e61ff..13b4eb5fbc 100644 --- a/source4/ntvfs/reference/vfs_ref.c +++ b/source4/ntvfs/reference/vfs_ref.c @@ -378,7 +378,7 @@ static NTSTATUS svfs_rmdir(struct request_context *req, struct smb_rmdir *rd) /* rename a set of files */ -static NTSTATUS svfs_rename(struct request_context *req, struct smb_rename *ren) +static NTSTATUS svfs_rename(struct request_context *req, union smb_rename *ren) { char *unix_path1, *unix_path2; diff --git a/source4/ntvfs/simple/vfs_simple.c b/source4/ntvfs/simple/vfs_simple.c index caf7732ac7..52e772af74 100644 --- a/source4/ntvfs/simple/vfs_simple.c +++ b/source4/ntvfs/simple/vfs_simple.c @@ -340,12 +340,16 @@ static NTSTATUS svfs_rmdir(struct request_context *req, struct smb_rmdir *rd) /* rename a set of files */ -static NTSTATUS svfs_rename(struct request_context *req, struct smb_rename *ren) +static NTSTATUS svfs_rename(struct request_context *req, union smb_rename *ren) { char *unix_path1, *unix_path2; - unix_path1 = svfs_unix_path(req, ren->in.pattern1); - unix_path2 = svfs_unix_path(req, ren->in.pattern2); + if (ren->generic.level != RAW_RENAME_RENAME) { + return NT_STATUS_INVALID_LEVEL; + } + + unix_path1 = svfs_unix_path(req, ren->rename.in.pattern1); + unix_path2 = svfs_unix_path(req, ren->rename.in.pattern2); if (rename(unix_path1, unix_path2) != 0) { return map_nt_error_from_unix(errno); diff --git a/source4/smbd/reply.c b/source4/smbd/reply.c index bc9a3b6a06..f4dd4cb50a 100644 --- a/source4/smbd/reply.c +++ b/source4/smbd/reply.c @@ -1600,20 +1600,21 @@ void reply_rmdir(struct request_context *req) ****************************************************************************/ void reply_mv(struct request_context *req) { - struct smb_rename *io; + union smb_rename *io; char *p; /* parse the request */ REQ_CHECK_WCT(req, 1); REQ_TALLOC(io, sizeof(*io)); - io->in.attrib = SVAL(req->in.vwv, VWV(0)); + io->generic.level = RAW_RENAME_RENAME; + io->rename.in.attrib = SVAL(req->in.vwv, VWV(0)); p = req->in.data; - p += req_pull_ascii4(req, &io->in.pattern1, p, STR_TERMINATE); - p += req_pull_ascii4(req, &io->in.pattern2, p, STR_TERMINATE); + p += req_pull_ascii4(req, &io->rename.in.pattern1, p, STR_TERMINATE); + p += req_pull_ascii4(req, &io->rename.in.pattern2, p, STR_TERMINATE); - if (!io->in.pattern1 || !io->in.pattern2) { + if (!io->rename.in.pattern1 || !io->rename.in.pattern2) { req_reply_error(req, NT_STATUS_FOOBAR); return; } diff --git a/source4/torture/gentest.c b/source4/torture/gentest.c index 3519b51f14..72b8e8d404 100644 --- a/source4/torture/gentest.c +++ b/source4/torture/gentest.c @@ -469,6 +469,18 @@ static BOOL gen_bool(void) return gen_bits_mask2(0x1, 0xFF); } +/* + generate ntrename flags +*/ +static uint16 gen_rename_flags(void) +{ + if (gen_chance(30)) return RENAME_FLAG_RENAME; + if (gen_chance(30)) return RENAME_FLAG_HARD_LINK; + if (gen_chance(30)) return RENAME_FLAG_COPY; + return gen_bits_mask(0xFFFF); +} + + /* return a lockingx lock mode */ @@ -1218,12 +1230,34 @@ static BOOL handler_rmdir(int instance) */ static BOOL handler_rename(int instance) { - struct smb_rename parm[NSERVERS]; + union smb_rename parm[NSERVERS]; NTSTATUS status[NSERVERS]; - parm[0].in.pattern1 = gen_pattern(); - parm[0].in.pattern2 = gen_pattern(); - parm[0].in.attrib = gen_attrib(); + parm[0].generic.level = RAW_RENAME_RENAME; + parm[0].rename.in.pattern1 = gen_pattern(); + parm[0].rename.in.pattern2 = gen_pattern(); + parm[0].rename.in.attrib = gen_attrib(); + + GEN_COPY_PARM; + GEN_CALL(smb_raw_rename(tree, &parm[i])); + + return True; +} + +/* + generate ntrename operations +*/ +static BOOL handler_ntrename(int instance) +{ + union smb_rename parm[NSERVERS]; + NTSTATUS status[NSERVERS]; + + parm[0].generic.level = RAW_RENAME_NTRENAME; + parm[0].ntrename.in.old_name = gen_fname(); + parm[0].ntrename.in.new_name = gen_fname(); + parm[0].ntrename.in.attrib = gen_attrib(); + parm[0].ntrename.in.root_fid = gen_root_fid(instance); + parm[0].ntrename.in.flags = gen_rename_flags(); GEN_COPY_PARM; GEN_CALL(smb_raw_rename(tree, &parm[i])); @@ -1771,6 +1805,7 @@ static struct { {"MKDIR", handler_mkdir}, {"RMDIR", handler_rmdir}, {"RENAME", handler_rename}, + {"NTRENAME", handler_ntrename}, {"READX", handler_readx}, {"WRITEX", handler_writex}, {"CHKPATH", handler_chkpath}, diff --git a/source4/torture/raw/missing.txt b/source4/torture/raw/missing.txt index 8e026b78ff..9a33e7ed6f 100644 --- a/source4/torture/raw/missing.txt +++ b/source4/torture/raw/missing.txt @@ -92,6 +92,7 @@ trans2_setfileinfo trans2_fsctl trans2_mkdir trans2_findnext +NTrename SMB_QFS_ALLOCATION SMB_QFS_VOLUME SMB_QFS_VOLUME_INFO diff --git a/source4/torture/raw/rename.c b/source4/torture/raw/rename.c index 4cfa1c95c2..0e411299d0 100644 --- a/source4/torture/raw/rename.c +++ b/source4/torture/raw/rename.c @@ -28,6 +28,13 @@ goto done; \ }} while (0) +#define CHECK_VALUE(v, correct) do { \ + if ((v) != (correct)) { \ + printf("(%d) Incorrect %s %d - should be %d\n", \ + __LINE__, #v, (int)v, (int)correct); \ + ret = False; \ + }} while (0) + #define BASEDIR "\\testrename" /* @@ -35,13 +42,15 @@ */ static BOOL test_mv(struct cli_state *cli, TALLOC_CTX *mem_ctx) { - struct smb_rename io; + union smb_rename io; NTSTATUS status; BOOL ret = True; int fnum; const char *fname1 = BASEDIR "\\test1.txt"; const char *fname2 = BASEDIR "\\test2.txt"; + printf("Testing SMBmv\n"); + if (cli_deltree(cli, BASEDIR) == -1 || !cli_mkdir(cli, BASEDIR)) { printf("Unable to setup %s - %s\n", BASEDIR, cli_errstr(cli)); @@ -52,9 +61,10 @@ static BOOL test_mv(struct cli_state *cli, TALLOC_CTX *mem_ctx) fnum = create_complex_file(cli, mem_ctx, fname1); - io.in.pattern1 = fname1; - io.in.pattern2 = fname2; - io.in.attrib = 0; + io.generic.level = RAW_RENAME_RENAME; + io.rename.in.pattern1 = fname1; + io.rename.in.pattern2 = fname2; + io.rename.in.attrib = 0; status = smb_raw_rename(cli->tree, &io); CHECK_STATUS(status, NT_STATUS_SHARING_VIOLATION); @@ -62,11 +72,22 @@ static BOOL test_mv(struct cli_state *cli, TALLOC_CTX *mem_ctx) smb_raw_exit(cli->session); status = smb_raw_rename(cli->tree, &io); CHECK_STATUS(status, NT_STATUS_OK); + + printf("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); printf("trying wildcard rename\n"); - io.in.pattern1 = BASEDIR "\\*.txt"; - io.in.pattern2 = fname1; + io.rename.in.pattern1 = BASEDIR "\\*.txt"; + io.rename.in.pattern2 = fname1; status = smb_raw_rename(cli->tree, &io); CHECK_STATUS(status, NT_STATUS_OK); @@ -76,8 +97,8 @@ static BOOL test_mv(struct cli_state *cli, TALLOC_CTX *mem_ctx) CHECK_STATUS(status, NT_STATUS_OK); printf("Trying extension change\n"); - io.in.pattern1 = BASEDIR "\\*.txt"; - io.in.pattern2 = BASEDIR "\\*.bak"; + 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); @@ -86,13 +107,13 @@ static BOOL test_mv(struct cli_state *cli, TALLOC_CTX *mem_ctx) printf("Checking attrib handling\n"); torture_set_file_attribute(cli->tree, BASEDIR "\\test1.bak", FILE_ATTRIBUTE_HIDDEN); - io.in.pattern1 = BASEDIR "\\test1.bak"; - io.in.pattern2 = BASEDIR "\\*.txt"; - io.in.attrib = 0; + 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.in.attrib = FILE_ATTRIBUTE_HIDDEN; + io.rename.in.attrib = FILE_ATTRIBUTE_HIDDEN; status = smb_raw_rename(cli->tree, &io); CHECK_STATUS(status, NT_STATUS_OK); @@ -103,6 +124,165 @@ done: } + +/* + test SMBntrename ops +*/ +static BOOL test_ntrename(struct cli_state *cli, TALLOC_CTX *mem_ctx) +{ + union smb_rename io; + NTSTATUS status; + BOOL ret = True; + int fnum; + const char *fname1 = BASEDIR "\\test1.txt"; + const char *fname2 = BASEDIR "\\test2.txt"; + union smb_fileinfo finfo; + + printf("Testing SMBntrename\n"); + + if (cli_deltree(cli, BASEDIR) == -1 || + !cli_mkdir(cli, BASEDIR)) { + printf("Unable to setup %s - %s\n", BASEDIR, cli_errstr(cli)); + return False; + } + + printf("Trying simple rename\n"); + + fnum = create_complex_file(cli, mem_ctx, 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.root_fid = 0; + io.ntrename.in.flags = RENAME_FLAG_RENAME; + + status = smb_raw_rename(cli->tree, &io); + CHECK_STATUS(status, NT_STATUS_SHARING_VIOLATION); + + smb_raw_exit(cli->session); + status = smb_raw_rename(cli->tree, &io); + CHECK_STATUS(status, NT_STATUS_OK); + + printf("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); + + printf("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); + + printf("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); + + printf("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.fname = fname2; + status = smb_raw_pathinfo(cli->tree, mem_ctx, &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.fname = fname1; + status = smb_raw_pathinfo(cli->tree, mem_ctx, &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); + + cli_unlink(cli, fname2); + + finfo.generic.in.fname = fname1; + status = smb_raw_pathinfo(cli->tree, mem_ctx, &finfo); + CHECK_STATUS(status, NT_STATUS_OK); + CHECK_VALUE(finfo.all_info.out.nlink, 1); + + printf("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); + + torture_set_file_attribute(cli->tree, fname1, FILE_ATTRIBUTE_SYSTEM); + + finfo.generic.level = RAW_FILEINFO_ALL_INFO; + finfo.generic.in.fname = fname2; + status = smb_raw_pathinfo(cli->tree, mem_ctx, &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.fname = fname1; + status = smb_raw_pathinfo(cli->tree, mem_ctx, &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); + + cli_unlink(cli, fname2); + + finfo.generic.in.fname = fname1; + status = smb_raw_pathinfo(cli->tree, mem_ctx, &finfo); + CHECK_STATUS(status, NT_STATUS_OK); + CHECK_VALUE(finfo.all_info.out.nlink, 1); + + printf("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); + CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED); + + io.ntrename.in.flags = 300; + status = smb_raw_rename(cli->tree, &io); + CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED); + + io.ntrename.in.flags = 0x106; + status = smb_raw_rename(cli->tree, &io); + CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED); + +done: + smb_raw_exit(cli->session); + cli_deltree(cli, BASEDIR); + return ret; +} + + /* basic testing of rename calls */ @@ -122,6 +302,10 @@ BOOL torture_raw_rename(int dummy) ret = False; } + if (!test_ntrename(cli, mem_ctx)) { + ret = False; + } + torture_close_connection(cli); talloc_destroy(mem_ctx); return ret; diff --git a/source4/torture/torture.c b/source4/torture/torture.c index 05a2979dd1..a43db896e0 100644 --- a/source4/torture/torture.c +++ b/source4/torture/torture.c @@ -106,6 +106,7 @@ BOOL torture_open_connection(struct cli_state **c) username, lp_workgroup(), password, flags, &retry); if (!NT_STATUS_IS_OK(status)) { + printf("Failed to open connection - %s\n", nt_errstr(status)); return False; } @@ -3986,6 +3987,25 @@ static BOOL run_test(const char *name) } +/* + parse a username%password +*/ +static void parse_user(const char *user) +{ + char *username, *password, *p; + + username = strdup(user); + p = strchr_m(username,'%'); + if (p) { + *p = 0; + password = strdup(p+1); + } + + lp_set_cmdline("torture:username", username); + lp_set_cmdline("torture:password", password); +} + + static void usage(void) { int i; @@ -4030,9 +4050,8 @@ static void usage(void) int opt, i; char *p; int gotuser = 0; - int gotpass = 0; BOOL correct = True; - char *host, *share, *username, *password; + char *host, *share, *username; setup_logging("smbtorture", DEBUG_STDOUT); @@ -4129,15 +4148,7 @@ static void usage(void) break; case 'U': gotuser = 1; - username = strdup(optarg); - p = strchr_m(username,'%'); - if (p) { - *p = 0; - password = strdup(p+1); - gotpass = 1; - } - lp_set_cmdline("torture:username", username); - lp_set_cmdline("torture:password", password); + parse_user(optarg); break; case 'f': torture_failures = atoi(optarg); @@ -4152,18 +4163,9 @@ static void usage(void) } } - if(use_kerberos && !gotuser) gotpass = True; - - while (!gotpass) { - p = getpass("Password:"); - if (p) { - lp_set_cmdline("torture:password", p); - gotpass = 1; - } - } - printf("host=%s share=%s user=%s myname=%s\n", - host, share, username, lp_netbios_name()); + host, share, lp_parm_string(-1, "torture", "username"), + lp_netbios_name()); if (argc == optind) { printf("You must specify a test to run, or 'ALL'\n"); -- cgit