summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Tridgell <tridge@samba.org>2003-08-31 03:16:52 +0000
committerAndrew Tridgell <tridge@samba.org>2003-08-31 03:16:52 +0000
commit11c5869a450d5f78a9395889ec03f77732cc8be5 (patch)
treed3fd5854dd61dc36f3d83064fdf04dc34c81234e
parenta8a5ac2bd218d5bc3985ffbe118111c9b4649860 (diff)
downloadsamba-11c5869a450d5f78a9395889ec03f77732cc8be5.tar.gz
samba-11c5869a450d5f78a9395889ec03f77732cc8be5.tar.bz2
samba-11c5869a450d5f78a9395889ec03f77732cc8be5.zip
I think I've finally got the ascii/unicode issues right in trans2 find
first Also expanded the rename test a little (This used to be commit 723af7f097a8c7f23dac23039e479811559ac3cb)
-rw-r--r--source4/include/smb.h7
-rw-r--r--source4/include/smb_interfaces.h2
-rw-r--r--source4/libcli/raw/rawfile.c2
-rw-r--r--source4/libcli/raw/rawrequest.c23
-rw-r--r--source4/libcli/raw/rawsearch.c8
-rw-r--r--source4/smbd/trans2.c29
-rw-r--r--source4/torture/raw/rename.c47
-rw-r--r--source4/torture/raw/search.c42
8 files changed, 125 insertions, 35 deletions
diff --git a/source4/include/smb.h b/source4/include/smb.h
index 14af5b5ea1..b791182aa6 100644
--- a/source4/include/smb.h
+++ b/source4/include/smb.h
@@ -972,9 +972,10 @@ struct bitmap {
#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
+#define RENAME_FLAG_MOVE_CLUSTER_INFORMATION 0x102 /* ???? */
+#define RENAME_FLAG_HARD_LINK 0x103
+#define RENAME_FLAG_RENAME 0x104
+#define RENAME_FLAG_COPY 0x105
/* Filesystem Attributes. */
#define FILE_CASE_SENSITIVE_SEARCH 0x01
diff --git a/source4/include/smb_interfaces.h b/source4/include/smb_interfaces.h
index 8a5819ff89..d087d2642e 100644
--- a/source4/include/smb_interfaces.h
+++ b/source4/include/smb_interfaces.h
@@ -151,7 +151,7 @@ union smb_rename {
struct {
uint16 attrib;
uint16 flags; /* see RENAME_FLAG_* */
- uint32 unknown;
+ uint32 cluster_size;
const char *old_name;
const char *new_name;
} in;
diff --git a/source4/libcli/raw/rawfile.c b/source4/libcli/raw/rawfile.c
index e9d3a8305d..0dc2a15c11 100644
--- a/source4/libcli/raw/rawfile.c
+++ b/source4/libcli/raw/rawfile.c
@@ -48,7 +48,7 @@ struct cli_request *smb_raw_rename_send(struct cli_tree *tree,
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.unknown);
+ SIVAL(req->out.vwv, VWV(2), parms->ntrename.in.cluster_size);
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;
diff --git a/source4/libcli/raw/rawrequest.c b/source4/libcli/raw/rawrequest.c
index fa3b3ab627..139f031178 100644
--- a/source4/libcli/raw/rawrequest.c
+++ b/source4/libcli/raw/rawrequest.c
@@ -963,8 +963,9 @@ size_t cli_blob_pull_string(struct cli_session *session,
uint16 len_offset, uint16 str_offset,
unsigned flags)
{
+ int extra;
dest->s = NULL;
-
+
if (len_offset > blob->length-4) {
return 0;
}
@@ -973,19 +974,29 @@ size_t cli_blob_pull_string(struct cli_session *session,
} else {
dest->private_length = IVAL(blob->data, len_offset);
}
+ extra = 0;
dest->s = NULL;
if (!(flags & STR_ASCII) &&
((flags & STR_UNICODE) ||
(session->transport->negotiate.capabilities & CAP_UNICODE))) {
+ int align = 0;
if ((str_offset&1) && !(flags & STR_NOALIGN)) {
- str_offset++;
+ align = 1;
+ }
+ if (flags & STR_LEN_NOTERM) {
+ extra = 2;
}
- return cli_blob_pull_ucs2(mem_ctx, blob, &dest->s,
- blob->data+str_offset, dest->private_length, flags);
+ return align + extra + cli_blob_pull_ucs2(mem_ctx, blob, &dest->s,
+ blob->data+str_offset+align,
+ dest->private_length, flags);
+ }
+
+ if (flags & STR_LEN_NOTERM) {
+ extra = 1;
}
- return cli_blob_pull_ascii(mem_ctx, blob, &dest->s,
- blob->data+str_offset, dest->private_length, flags);
+ return extra + cli_blob_pull_ascii(mem_ctx, blob, &dest->s,
+ blob->data+str_offset, dest->private_length, flags);
}
/*
diff --git a/source4/libcli/raw/rawsearch.c b/source4/libcli/raw/rawsearch.c
index bdc39bb68c..222bf53623 100644
--- a/source4/libcli/raw/rawsearch.c
+++ b/source4/libcli/raw/rawsearch.c
@@ -263,8 +263,8 @@ static int parse_trans2_search(struct cli_tree *tree,
data->standard.attrib = SVAL(blob->data, 20);
len = cli_blob_pull_string(tree->session, mem_ctx, blob,
&data->standard.name,
- 22, 23, STR_LEN8BIT);
- return (len + 23 + 3) & ~3;
+ 22, 23, STR_LEN8BIT | STR_TERMINATE | STR_LEN_NOTERM);
+ return len + 23;
case RAW_SEARCH_EA_SIZE:
if (flags & FLAG_TRANS2_FIND_REQUIRE_RESUME) {
@@ -283,8 +283,8 @@ static int parse_trans2_search(struct cli_tree *tree,
data->ea_size.ea_size = IVAL(blob->data, 22);
len = cli_blob_pull_string(tree->session, mem_ctx, blob,
&data->ea_size.name,
- 26, 27, STR_LEN8BIT | STR_NOALIGN);
- return len + 27;
+ 26, 27, STR_LEN8BIT | STR_TERMINATE | STR_NOALIGN);
+ return len + 27 + 1;
case RAW_SEARCH_DIRECTORY_INFO:
if (blob->length < 65) return -1;
diff --git a/source4/smbd/trans2.c b/source4/smbd/trans2.c
index c870e2996c..25f4aaed19 100644
--- a/source4/smbd/trans2.c
+++ b/source4/smbd/trans2.c
@@ -757,7 +757,7 @@ static NTSTATUS trans2_parse_sfileinfo(struct request_context *req,
blob2.data = blob->data+12;
blob2.length = MIN(blob->length, len);
trans2_pull_blob_string(req, &blob2, 0,
- &st->rename_information.in.new_name, 0);
+ &st->rename_information.in.new_name, STR_UNICODE);
return NT_STATUS_OK;
}
@@ -859,6 +859,7 @@ struct find_state {
struct smb_trans2 *trans;
enum search_level level;
uint16 last_entry_offset;
+ uint16 flags;
};
/*
@@ -866,20 +867,26 @@ struct find_state {
*/
static void find_fill_info(struct request_context *req,
struct smb_trans2 *trans,
- enum search_level level,
+ struct find_state *state,
union smb_search_data *file)
{
char *data;
uint_t ofs = trans->out.data.length;
- switch (level) {
+ switch (state->level) {
case RAW_SEARCH_SEARCH:
case RAW_SEARCH_GENERIC:
/* handled elsewhere */
break;
case RAW_SEARCH_STANDARD:
- trans2_grow_data(req, trans, ofs + 23);
+ if (state->flags & FLAG_TRANS2_FIND_REQUIRE_RESUME) {
+ trans2_grow_data(req, trans, ofs + 27);
+ SIVAL(trans->out.data.data, ofs, file->standard.resume_key);
+ ofs += 4;
+ } else {
+ trans2_grow_data(req, trans, ofs + 23);
+ }
data = trans->out.data.data + ofs;
put_dos_date2(data, 0, file->standard.create_time);
put_dos_date2(data, 4, file->standard.access_time);
@@ -892,7 +899,13 @@ static void find_fill_info(struct request_context *req,
break;
case RAW_SEARCH_EA_SIZE:
- trans2_grow_data(req, trans, ofs + 27);
+ if (state->flags & FLAG_TRANS2_FIND_REQUIRE_RESUME) {
+ trans2_grow_data(req, trans, ofs + 31);
+ SIVAL(trans->out.data.data, ofs, file->ea_size.resume_key);
+ ofs += 4;
+ } else {
+ trans2_grow_data(req, trans, ofs + 27);
+ }
data = trans->out.data.data + ofs;
put_dos_date2(data, 0, file->ea_size.create_time);
put_dos_date2(data, 4, file->ea_size.access_time);
@@ -902,7 +915,7 @@ static void find_fill_info(struct request_context *req,
SSVAL(data, 20, file->ea_size.attrib);
SIVAL(data, 22, file->ea_size.ea_size);
trans2_append_data_string(req, trans, &file->ea_size.name,
- ofs + 26, STR_LEN8BIT | STR_NOALIGN);
+ ofs + 26, STR_LEN8BIT | STR_TERMINATE | STR_NOALIGN);
break;
case RAW_SEARCH_DIRECTORY_INFO:
@@ -1033,7 +1046,7 @@ static BOOL find_callback(void *private, union smb_search_data *file)
old_length = trans->out.data.length;
- find_fill_info(state->req, trans, state->level, file);
+ find_fill_info(state->req, trans, state, file);
/* see if we have gone beyond the user specified maximum */
if (trans->out.data.length > trans->in.max_data) {
@@ -1084,6 +1097,7 @@ static NTSTATUS trans2_findfirst(struct request_context *req, struct smb_trans2
state.trans = trans;
state.level = search.t2ffirst.level;
state.last_entry_offset = 0;
+ state.flags = search.t2ffirst.in.flags;
/* setup for just a header in the reply */
trans2_setup_reply(req, trans, 10, 0, 0);
@@ -1143,6 +1157,7 @@ static NTSTATUS trans2_findnext(struct request_context *req, struct smb_trans2 *
state.trans = trans;
state.level = search.t2fnext.level;
state.last_entry_offset = 0;
+ state.flags = search.t2fnext.in.flags;
/* setup for just a header in the reply */
trans2_setup_reply(req, trans, 8, 0, 0);
diff --git a/source4/torture/raw/rename.c b/source4/torture/raw/rename.c
index b536b0fe1a..b997c2f310 100644
--- a/source4/torture/raw/rename.c
+++ b/source4/torture/raw/rename.c
@@ -155,7 +155,7 @@ static BOOL test_ntrename(struct cli_state *cli, TALLOC_CTX *mem_ctx)
io.ntrename.in.old_name = fname1;
io.ntrename.in.new_name = fname2;
io.ntrename.in.attrib = 0;
- io.ntrename.in.unknown = 0;
+ io.ntrename.in.cluster_size = 0;
io.ntrename.in.flags = RENAME_FLAG_RENAME;
status = smb_raw_rename(cli->tree, &io);
@@ -282,29 +282,54 @@ static BOOL test_ntrename(struct cli_state *cli, TALLOC_CTX *mem_ctx)
io.ntrename.in.new_name = fname2;
io.ntrename.in.attrib = 0;
io.ntrename.in.flags = RENAME_FLAG_RENAME;
- io.ntrename.in.unknown = 0xff;
+ io.ntrename.in.cluster_size = 0xff;
status = smb_raw_rename(cli->tree, &io);
CHECK_STATUS(status, NT_STATUS_OK);
- fnum = create_directory_handle(cli, BASEDIR "\\testdir");
- printf("Trying flags 0x102 fnum=%d\n", fnum);
+ printf("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 = 0x102;
- io.ntrename.in.unknown = fnum;
+ 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);
- for (i=0;i<32;i++) {
- io.ntrename.in.unknown = (1<<i);
+ 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 = cli_open(cli, fname1, O_RDWR, DENY_NONE);
+ memset(buf, 1, sizeof(buf));
+ cli_write(cli, fnum, 0, buf, 0, sizeof(buf));
+ cli_close(cli, fnum);
+
+ fnum = cli_open(cli, fname2, O_RDWR, DENY_NONE);
+ memset(buf, 1, sizeof(buf));
+ cli_write(cli, fnum, 0, buf, 0, sizeof(buf)-1);
+ cli_close(cli, 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)) {
- printf("i=0x%x status=%s\n", i, nt_errstr(status));
+ printf("i=%d status=%s\n", i, nt_errstr(status));
}
- CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER);
}
+#endif
printf("Checking other flags\n");
@@ -319,7 +344,7 @@ static BOOL test_ntrename(struct cli_state *cli, TALLOC_CTX *mem_ctx)
io.ntrename.in.new_name = fname1;
io.ntrename.in.flags = i;
io.ntrename.in.attrib = 0;
- io.ntrename.in.unknown = 0;
+ io.ntrename.in.cluster_size = 0;
status = smb_raw_rename(cli->tree, &io);
if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
printf("flags=0x%x status=%s\n", i, nt_errstr(status));
diff --git a/source4/torture/raw/search.c b/source4/torture/raw/search.c
index c9fa5d6a11..ab69b5af42 100644
--- a/source4/torture/raw/search.c
+++ b/source4/torture/raw/search.c
@@ -412,6 +412,12 @@ static NTSTATUS multiple_search(struct cli_state *cli,
if (level == RAW_SEARCH_STANDARD) {
io2.t2fnext.in.resume_key =
result->list[result->count-1].standard.resume_key;
+ } else if (level == RAW_SEARCH_EA_SIZE) {
+ io2.t2fnext.in.resume_key =
+ result->list[result->count-1].ea_size.resume_key;
+ } else if (level == RAW_SEARCH_DIRECTORY_INFO) {
+ io2.t2fnext.in.resume_key =
+ result->list[result->count-1].directory_info.file_index;
} else {
io2.t2fnext.in.resume_key =
result->list[result->count-1].both_directory_info.file_index;
@@ -423,6 +429,12 @@ static NTSTATUS multiple_search(struct cli_state *cli,
if (level == RAW_SEARCH_STANDARD) {
io2.t2fnext.in.last_name =
result->list[result->count-1].standard.name.s;
+ } else if (level == RAW_SEARCH_EA_SIZE) {
+ io2.t2fnext.in.last_name =
+ result->list[result->count-1].ea_size.name.s;
+ } else if (level == RAW_SEARCH_DIRECTORY_INFO) {
+ io2.t2fnext.in.last_name =
+ result->list[result->count-1].directory_info.name.s;
} else {
io2.t2fnext.in.last_name =
result->list[result->count-1].both_directory_info.name.s;
@@ -478,6 +490,16 @@ static int search_standard_compare(union smb_search_data *d1, union smb_search_d
return strcmp(d1->standard.name.s, d2->standard.name.s);
}
+static int search_ea_size_compare(union smb_search_data *d1, union smb_search_data *d2)
+{
+ return strcmp(d1->ea_size.name.s, d2->ea_size.name.s);
+}
+
+static int search_directory_info_compare(union smb_search_data *d1, union smb_search_data *d2)
+{
+ return strcmp(d1->directory_info.name.s, d2->directory_info.name.s);
+}
+
static int search_old_compare(union smb_search_data *d1, union smb_search_data *d2)
{
return strcmp(d1->search.name, d2->search.name);
@@ -507,6 +529,12 @@ static BOOL test_many_files(struct cli_state *cli, TALLOC_CTX *mem_ctx)
{"STANDARD", "FLAGS", RAW_SEARCH_STANDARD, CONT_FLAGS},
{"STANDARD", "KEY", RAW_SEARCH_STANDARD, CONT_RESUME_KEY},
{"STANDARD", "NAME", RAW_SEARCH_STANDARD, CONT_NAME},
+ {"EA_SIZE", "FLAGS", RAW_SEARCH_EA_SIZE, CONT_FLAGS},
+ {"EA_SIZE", "KEY", RAW_SEARCH_EA_SIZE, CONT_RESUME_KEY},
+ {"EA_SIZE", "NAME", RAW_SEARCH_EA_SIZE, CONT_NAME},
+ {"DIRECTORY_INFO", "FLAGS", RAW_SEARCH_DIRECTORY_INFO, CONT_FLAGS},
+ {"DIRECTORY_INFO", "KEY", RAW_SEARCH_DIRECTORY_INFO, CONT_RESUME_KEY},
+ {"DIRECTORY_INFO", "NAME", RAW_SEARCH_DIRECTORY_INFO, CONT_NAME},
{"SEARCH", "ID", RAW_SEARCH_SEARCH, CONT_RESUME_KEY}
};
@@ -519,7 +547,7 @@ static BOOL test_many_files(struct cli_state *cli, TALLOC_CTX *mem_ctx)
printf("Creating %d files\n", num_files);
for (i=0;i<num_files;i++) {
- asprintf(&fname, BASEDIR "\\test%03d.txt", i);
+ asprintf(&fname, BASEDIR "\\t%03d-%d.txt", i, i);
fnum = cli_open(cli, fname, O_CREAT|O_RDWR, DENY_NONE);
if (fnum == -1) {
printf("Failed to create %s - %s\n", fname, cli_errstr(cli));
@@ -551,6 +579,12 @@ static BOOL test_many_files(struct cli_state *cli, TALLOC_CTX *mem_ctx)
} else if (search_types[t].level == RAW_SEARCH_STANDARD) {
qsort(result.list, result.count, sizeof(result.list[0]),
QSORT_CAST search_standard_compare);
+ } else if (search_types[t].level == RAW_SEARCH_EA_SIZE) {
+ qsort(result.list, result.count, sizeof(result.list[0]),
+ QSORT_CAST search_ea_size_compare);
+ } else if (search_types[t].level == RAW_SEARCH_DIRECTORY_INFO) {
+ qsort(result.list, result.count, sizeof(result.list[0]),
+ QSORT_CAST search_directory_info_compare);
} else {
qsort(result.list, result.count, sizeof(result.list[0]),
QSORT_CAST search_old_compare);
@@ -562,10 +596,14 @@ static BOOL test_many_files(struct cli_state *cli, TALLOC_CTX *mem_ctx)
s = result.list[i].both_directory_info.name.s;
} else if (search_types[t].level == RAW_SEARCH_STANDARD) {
s = result.list[i].standard.name.s;
+ } else if (search_types[t].level == RAW_SEARCH_EA_SIZE) {
+ s = result.list[i].ea_size.name.s;
+ } else if (search_types[t].level == RAW_SEARCH_DIRECTORY_INFO) {
+ s = result.list[i].directory_info.name.s;
} else {
s = result.list[i].search.name;
}
- asprintf(&fname, "test%03d.txt", i);
+ asprintf(&fname, "t%03d-%d.txt", i, i);
if (strcmp(fname, s)) {
printf("Incorrect name %s at entry %d\n", s, i);
ret = False;