1
0
mirror of https://github.com/samba-team/samba.git synced 2025-03-01 04:58:35 +03:00

r204: Turns out that the string in the SEARCH unix_info level is that

rare thing, a non-length string (ie. not a WIRE_STRING) but a null
terminated char string. There wasn't a good interface to pull that
out of a blob (all the string interfaces assumed WIRE_STRINGS). Added
a new one, only used for this call. Sucks, I know - but the alternatives
suck more. Added tests for some of the unix info returned.
Jeremy.
(This used to be commit 4d0ed04c54b105789ffd32334c3b0e544f02418c)
This commit is contained in:
Jeremy Allison 2004-04-14 01:09:41 +00:00 committed by Gerald (Jerry) Carter
parent 6f47ce8b6c
commit 763c4bc9ac
4 changed files with 65 additions and 6 deletions

View File

@ -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;
};

View File

@ -1007,6 +1007,52 @@ size_t cli_blob_pull_string(struct cli_session *session,
blob->data+str_offset, dest->private_length, flags);
}
/*
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
*/

View File

@ -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;

View File

@ -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);