summaryrefslogtreecommitdiff
path: root/source4
diff options
context:
space:
mode:
Diffstat (limited to 'source4')
-rw-r--r--source4/include/ntvfs.h2
-rw-r--r--source4/include/smb.h6
-rw-r--r--source4/include/smb_interfaces.h35
-rw-r--r--source4/libcli/cliconnect.c15
-rw-r--r--source4/libcli/clifile.c9
-rw-r--r--source4/libcli/namequery.c2
-rw-r--r--source4/libcli/raw/rawfile.c27
-rw-r--r--source4/ntvfs/cifs/vfs_cifs.c2
-rw-r--r--source4/ntvfs/ipc/vfs_ipc.c2
-rw-r--r--source4/ntvfs/reference/vfs_ref.c2
-rw-r--r--source4/ntvfs/simple/vfs_simple.c10
-rw-r--r--source4/smbd/reply.c11
-rw-r--r--source4/torture/gentest.c43
-rw-r--r--source4/torture/raw/missing.txt1
-rw-r--r--source4/torture/raw/rename.c208
-rw-r--r--source4/torture/torture.c46
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
@@ -470,6 +470,18 @@ static BOOL gen_bool(void)
}
/*
+ 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
*/
static uint16 gen_lock_mode(void)
@@ -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");