1
0
mirror of https://github.com/samba-team/samba.git synced 2024-12-22 13:34:15 +03:00

libcli/smb: make smb2cli_ioctl_parse_buffer() available as smb2cli_parse_dyn_buffer()

It will be used in smb2cli_read.c soon...

BUG: https://bugzilla.samba.org/show_bug.cgi?id=14607

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>
This commit is contained in:
Stefan Metzmacher 2021-06-29 15:24:13 +02:00 committed by Jeremy Allison
parent ef57fba5db
commit 1faf15b3d0
3 changed files with 116 additions and 107 deletions

View File

@ -160,97 +160,6 @@ struct tevent_req *smb2cli_ioctl_send(TALLOC_CTX *mem_ctx,
return req; return req;
} }
static NTSTATUS smb2cli_ioctl_parse_buffer(uint32_t dyn_offset,
const DATA_BLOB dyn_buffer,
uint32_t min_offset,
uint32_t buffer_offset,
uint32_t buffer_length,
uint32_t max_length,
uint32_t *next_offset,
DATA_BLOB *buffer)
{
uint32_t offset;
bool oob;
*buffer = data_blob_null;
*next_offset = dyn_offset;
if (buffer_offset == 0) {
/*
* If the offset is 0, we better ignore
* the buffer_length field.
*/
return NT_STATUS_OK;
}
if (buffer_length == 0) {
/*
* If the length is 0, we better ignore
* the buffer_offset field.
*/
return NT_STATUS_OK;
}
if ((buffer_offset % 8) != 0) {
/*
* The offset needs to be 8 byte aligned.
*/
return NT_STATUS_INVALID_NETWORK_RESPONSE;
}
/*
* We used to enforce buffer_offset to be
* an exact match of the expected minimum,
* but the NetApp Ontap 7.3.7 SMB server
* gets the padding wrong and aligns the
* input_buffer_offset by a value of 8.
*
* So we just enforce that the offset is
* not lower than the expected value.
*/
SMB_ASSERT(min_offset >= dyn_offset);
if (buffer_offset < min_offset) {
return NT_STATUS_INVALID_NETWORK_RESPONSE;
}
/*
* Make [input|output]_buffer_offset relative to "dyn_buffer"
*/
offset = buffer_offset - dyn_offset;
oob = smb_buffer_oob(dyn_buffer.length, offset, buffer_length);
if (oob) {
return NT_STATUS_INVALID_NETWORK_RESPONSE;
}
/*
* Give the caller a hint what we consumed,
* the caller may need to add possible padding.
*/
*next_offset = buffer_offset + buffer_length;
if (max_length == 0) {
/*
* If max_input_length is 0 we ignore the
* input_buffer_length, because Windows 2008 echos the
* DCERPC request from the requested input_buffer to
* the response input_buffer.
*
* We just use the same logic also for max_output_length...
*/
buffer_length = 0;
}
if (buffer_length > max_length) {
return NT_STATUS_INVALID_NETWORK_RESPONSE;
}
*buffer = (DATA_BLOB) {
.data = dyn_buffer.data + offset,
.length = buffer_length,
};
return NT_STATUS_OK;
}
static void smb2cli_ioctl_done(struct tevent_req *subreq) static void smb2cli_ioctl_done(struct tevent_req *subreq)
{ {
struct tevent_req *req = struct tevent_req *req =
@ -352,14 +261,14 @@ static void smb2cli_ioctl_done(struct tevent_req *subreq)
input_min_offset = dyn_ofs; input_min_offset = dyn_ofs;
input_next_offset = dyn_ofs; input_next_offset = dyn_ofs;
error = smb2cli_ioctl_parse_buffer(dyn_ofs, error = smb2cli_parse_dyn_buffer(dyn_ofs,
dyn_buffer, dyn_buffer,
input_min_offset, input_min_offset,
input_buffer_offset, input_buffer_offset,
input_buffer_length, input_buffer_length,
state->max_input_length, state->max_input_length,
&input_next_offset, &input_next_offset,
&state->out_input_buffer); &state->out_input_buffer);
if (tevent_req_nterror(req, error)) { if (tevent_req_nterror(req, error)) {
return; return;
} }
@ -370,14 +279,14 @@ static void smb2cli_ioctl_done(struct tevent_req *subreq)
*/ */
output_min_offset = NDR_ROUND(input_next_offset, 8); output_min_offset = NDR_ROUND(input_next_offset, 8);
output_next_offset = 0; /* this variable is completely ignored */ output_next_offset = 0; /* this variable is completely ignored */
error = smb2cli_ioctl_parse_buffer(dyn_ofs, error = smb2cli_parse_dyn_buffer(dyn_ofs,
dyn_buffer, dyn_buffer,
output_min_offset, output_min_offset,
output_buffer_offset, output_buffer_offset,
output_buffer_length, output_buffer_length,
state->max_output_length, state->max_output_length,
&output_next_offset, &output_next_offset,
&state->out_output_buffer); &state->out_output_buffer);
if (tevent_req_nterror(req, error)) { if (tevent_req_nterror(req, error)) {
return; return;
} }

View File

@ -6823,3 +6823,94 @@ uint64_t smb2cli_conn_get_mid(struct smbXcli_conn *conn)
{ {
return conn->smb2.mid; return conn->smb2.mid;
} }
NTSTATUS smb2cli_parse_dyn_buffer(uint32_t dyn_offset,
const DATA_BLOB dyn_buffer,
uint32_t min_offset,
uint32_t buffer_offset,
uint32_t buffer_length,
uint32_t max_length,
uint32_t *next_offset,
DATA_BLOB *buffer)
{
uint32_t offset;
bool oob;
*buffer = data_blob_null;
*next_offset = dyn_offset;
if (buffer_offset == 0) {
/*
* If the offset is 0, we better ignore
* the buffer_length field.
*/
return NT_STATUS_OK;
}
if (buffer_length == 0) {
/*
* If the length is 0, we better ignore
* the buffer_offset field.
*/
return NT_STATUS_OK;
}
if ((buffer_offset % 8) != 0) {
/*
* The offset needs to be 8 byte aligned.
*/
return NT_STATUS_INVALID_NETWORK_RESPONSE;
}
/*
* We used to enforce buffer_offset to be
* an exact match of the expected minimum,
* but the NetApp Ontap 7.3.7 SMB server
* gets the padding wrong and aligns the
* input_buffer_offset by a value of 8.
*
* So we just enforce that the offset is
* not lower than the expected value.
*/
SMB_ASSERT(min_offset >= dyn_offset);
if (buffer_offset < min_offset) {
return NT_STATUS_INVALID_NETWORK_RESPONSE;
}
/*
* Make [input|output]_buffer_offset relative to "dyn_buffer"
*/
offset = buffer_offset - dyn_offset;
oob = smb_buffer_oob(dyn_buffer.length, offset, buffer_length);
if (oob) {
return NT_STATUS_INVALID_NETWORK_RESPONSE;
}
/*
* Give the caller a hint what we consumed,
* the caller may need to add possible padding.
*/
*next_offset = buffer_offset + buffer_length;
if (max_length == 0) {
/*
* If max_input_length is 0 we ignore the
* input_buffer_length, because Windows 2008 echos the
* DCERPC request from the requested input_buffer to
* the response input_buffer.
*
* We just use the same logic also for max_output_length...
*/
buffer_length = 0;
}
if (buffer_length > max_length) {
return NT_STATUS_INVALID_NETWORK_RESPONSE;
}
*buffer = (DATA_BLOB) {
.data = dyn_buffer.data + offset,
.length = buffer_length,
};
return NT_STATUS_OK;
}

View File

@ -395,6 +395,15 @@ void smb2cli_conn_set_cc_max_chunks(struct smbXcli_conn *conn,
void smb2cli_conn_set_mid(struct smbXcli_conn *conn, uint64_t mid); void smb2cli_conn_set_mid(struct smbXcli_conn *conn, uint64_t mid);
uint64_t smb2cli_conn_get_mid(struct smbXcli_conn *conn); uint64_t smb2cli_conn_get_mid(struct smbXcli_conn *conn);
NTSTATUS smb2cli_parse_dyn_buffer(uint32_t dyn_offset,
const DATA_BLOB dyn_buffer,
uint32_t min_offset,
uint32_t buffer_offset,
uint32_t buffer_length,
uint32_t max_length,
uint32_t *next_offset,
DATA_BLOB *buffer);
struct tevent_req *smb2cli_req_create(TALLOC_CTX *mem_ctx, struct tevent_req *smb2cli_req_create(TALLOC_CTX *mem_ctx,
struct tevent_context *ev, struct tevent_context *ev,
struct smbXcli_conn *conn, struct smbXcli_conn *conn,