diff options
-rw-r--r-- | source4/include/smb_interfaces.h | 2 | ||||
-rw-r--r-- | source4/libcli/raw/rawrequest.c | 46 | ||||
-rw-r--r-- | source4/libcli/raw/rawsearch.c | 9 | ||||
-rw-r--r-- | source4/torture/raw/search.c | 14 |
4 files changed, 65 insertions, 6 deletions
diff --git a/source4/include/smb_interfaces.h b/source4/include/smb_interfaces.h index 6f6213931c..1f6208cdb5 100644 --- a/source4/include/smb_interfaces.h +++ b/source4/include/smb_interfaces.h @@ -1919,7 +1919,7 @@ union smb_search_data { large_t unique_id; large_t permissions; large_t nlink; - WIRE_STRING name; + const char *name; } unix_info; }; diff --git a/source4/libcli/raw/rawrequest.c b/source4/libcli/raw/rawrequest.c index f03cc5cf16..321d43f220 100644 --- a/source4/libcli/raw/rawrequest.c +++ b/source4/libcli/raw/rawrequest.c @@ -1008,6 +1008,52 @@ size_t cli_blob_pull_string(struct cli_session *session, } /* + pull a string from a blob, returning a talloced char * + + Currently only used by the UNIX search info level. + + the string length is limited by 2 things: + - the data size in the blob + - the end of string (null termination) + + on failure zero is returned and dest->s is set to NULL, otherwise the number + of bytes consumed in the blob is returned +*/ +size_t cli_blob_pull_unix_string(struct cli_session *session, + TALLOC_CTX *mem_ctx, + DATA_BLOB *blob, + const char **dest, + uint16 str_offset, + unsigned flags) +{ + int extra = 0; + *dest = NULL; + + if (!(flags & STR_ASCII) && + ((flags & STR_UNICODE) || + (session->transport->negotiate.capabilities & CAP_UNICODE))) { + int align = 0; + if ((str_offset&1) && !(flags & STR_NOALIGN)) { + align = 1; + } + if (flags & STR_LEN_NOTERM) { + extra = 2; + } + return align + extra + cli_blob_pull_ucs2(mem_ctx, blob, dest, + blob->data+str_offset+align, + -1, flags); + } + + if (flags & STR_LEN_NOTERM) { + extra = 1; + } + + return extra + cli_blob_pull_ascii(mem_ctx, blob, dest, + blob->data+str_offset, -1, flags); +} + + +/* append a string into a blob */ size_t cli_blob_append_string(struct cli_session *session, diff --git a/source4/libcli/raw/rawsearch.c b/source4/libcli/raw/rawsearch.c index ef854679dc..8b60633fe8 100644 --- a/source4/libcli/raw/rawsearch.c +++ b/source4/libcli/raw/rawsearch.c @@ -415,7 +415,7 @@ static int parse_trans2_search(struct cli_tree *tree, return ofs; case RAW_SEARCH_UNIX_INFO: - if (blob->length < 105) return -1; + if (blob->length < 109) return -1; ofs = IVAL(blob->data, 0); data->unix_info.file_index = IVAL(blob->data, 4); data->unix_info.size = BVAL(blob->data, 8); @@ -432,10 +432,9 @@ static int parse_trans2_search(struct cli_tree *tree, data->unix_info.permissions = IVAL(blob->data, 92); data->unix_info.nlink = IVAL(blob->data, 100); /* There is no length field for this name but we know it's null terminated. */ - len = cli_blob_pull_string(tree->session, mem_ctx, blob, - &data->unix_info.name, - 0, 104, 0); - if (ofs != 0 && ofs < 104+len) { + len = cli_blob_pull_unix_string(tree->session, mem_ctx, blob, + &data->unix_info.name, 108, 0); + if (ofs != 0 && ofs < 108+len) { return -1; } return ofs; diff --git a/source4/torture/raw/search.c b/source4/torture/raw/search.c index 7308533fda..57c6eb2bb9 100644 --- a/source4/torture/raw/search.c +++ b/source4/torture/raw/search.c @@ -257,6 +257,19 @@ static BOOL test_one_file(struct cli_state *cli, TALLOC_CTX *mem_ctx) ret = False; \ } \ }} while (0) + +#define CHECK_UNIX_NAME(name, sname1, field1, fname, flags) do { \ + s = find(name); \ + if (s) { \ + if (!s->sname1.field1 || \ + strcmp(s->sname1.field1, fname)) { \ + printf("(%d) %s/%s [%s] != %s\n", \ + __LINE__, \ + #sname1, #field1, s->sname1.field1, \ + fname); \ + ret = False; \ + } \ + }} while (0) /* check that all the results are as expected */ CHECK_VAL("SEARCH", search, attrib, all_info, all_info, attrib); @@ -336,6 +349,7 @@ static BOOL test_one_file(struct cli_state *cli, TALLOC_CTX *mem_ctx) CHECK_NAME("BOTH_DIRECTORY_INFO", both_directory_info, name, fname+1, STR_TERMINATE_ASCII); CHECK_NAME("ID_FULL_DIRECTORY_INFO", id_full_directory_info, name, fname+1, STR_TERMINATE_ASCII); CHECK_NAME("ID_BOTH_DIRECTORY_INFO", id_both_directory_info, name, fname+1, STR_TERMINATE_ASCII); + CHECK_UNIX_NAME("UNIX_INFO", unix_info, name, fname+1, STR_TERMINATE_ASCII); CHECK_VAL("ID_FULL_DIRECTORY_INFO", id_full_directory_info, file_id, internal_info, internal_information, file_id); CHECK_VAL("ID_BOTH_DIRECTORY_INFO", id_both_directory_info, file_id, internal_info, internal_information, file_id); |