summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source4/include/smb_interfaces.h2
-rw-r--r--source4/libcli/raw/rawrequest.c46
-rw-r--r--source4/libcli/raw/rawsearch.c9
-rw-r--r--source4/torture/raw/search.c14
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);