diff options
Diffstat (limited to 'source4')
-rw-r--r-- | source4/include/smb.h | 7 | ||||
-rw-r--r-- | source4/include/smb_interfaces.h | 2 | ||||
-rw-r--r-- | source4/libcli/raw/rawfile.c | 2 | ||||
-rw-r--r-- | source4/libcli/raw/rawrequest.c | 23 | ||||
-rw-r--r-- | source4/libcli/raw/rawsearch.c | 8 | ||||
-rw-r--r-- | source4/smbd/trans2.c | 29 | ||||
-rw-r--r-- | source4/torture/raw/rename.c | 47 | ||||
-rw-r--r-- | source4/torture/raw/search.c | 42 |
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; |