mirror of
https://github.com/samba-team/samba.git
synced 2024-12-23 17:34:34 +03:00
s3-dcerpc: Convert frag from prs_struct to a simple DATA_BLOB
Signed-off-by: Günther Deschner <gd@samba.org>
This commit is contained in:
parent
31b59bbf99
commit
8cd3912afa
@ -76,7 +76,7 @@ typedef struct _output_data {
|
||||
* The current fragment being returned. This inclues
|
||||
* headers, data and authentication footer.
|
||||
*/
|
||||
prs_struct frag;
|
||||
DATA_BLOB frag;
|
||||
|
||||
/* The amount of data sent from the current PDU. */
|
||||
uint32 current_pdu_sent;
|
||||
|
@ -145,54 +145,41 @@ static bool create_next_pdu_ntlmssp(pipes_struct *p)
|
||||
hdr_flags |= DCERPC_PFC_FLAG_LAST;
|
||||
}
|
||||
|
||||
/*
|
||||
* Init the parse struct to point at the outgoing
|
||||
* data.
|
||||
*/
|
||||
prs_init_empty(&p->out_data.frag, p->mem_ctx, MARSHALL);
|
||||
|
||||
/* Set the data into the PDU. */
|
||||
u.response.stub_and_verifier =
|
||||
data_blob_const(p->out_data.rdata.data, data_len);
|
||||
|
||||
status = dcerpc_push_ncacn_packet(
|
||||
prs_get_mem_context(&p->out_data.frag),
|
||||
DCERPC_PKT_RESPONSE,
|
||||
hdr_flags,
|
||||
NTLMSSP_SIG_SIZE,
|
||||
p->call_id,
|
||||
&u,
|
||||
&blob);
|
||||
/* Store the packet in the data stream. */
|
||||
status = dcerpc_push_ncacn_packet(p->mem_ctx,
|
||||
DCERPC_PKT_RESPONSE,
|
||||
hdr_flags,
|
||||
NTLMSSP_SIG_SIZE,
|
||||
p->call_id,
|
||||
&u,
|
||||
&p->out_data.frag);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
DEBUG(0, ("Failed to marshall RPC Header.\n"));
|
||||
prs_mem_free(&p->out_data.frag);
|
||||
return False;
|
||||
}
|
||||
|
||||
/* Set the proper length on the pdu */
|
||||
dcerpc_set_frag_length(&blob, blob.length +
|
||||
ss_padding_len +
|
||||
RPC_HDR_AUTH_LEN +
|
||||
NTLMSSP_SIG_SIZE);
|
||||
|
||||
/* Store the packet in the data stream. */
|
||||
if (!prs_copy_data_in(&p->out_data.frag,
|
||||
(char *)blob.data, blob.length)) {
|
||||
DEBUG(0, ("Out of memory.\n"));
|
||||
prs_mem_free(&p->out_data.frag);
|
||||
return False;
|
||||
}
|
||||
dcerpc_set_frag_length(&p->out_data.frag,
|
||||
p->out_data.frag.length +
|
||||
ss_padding_len +
|
||||
RPC_HDR_AUTH_LEN +
|
||||
NTLMSSP_SIG_SIZE);
|
||||
|
||||
/* Append the sign/seal padding data. */
|
||||
if (ss_padding_len) {
|
||||
char pad[SERVER_NDR_PADDING_SIZE];
|
||||
|
||||
memset(pad, '\0', SERVER_NDR_PADDING_SIZE);
|
||||
if (!prs_copy_data_in(&p->out_data.frag, pad,
|
||||
if (!data_blob_append(p->mem_ctx,
|
||||
&p->out_data.frag, pad,
|
||||
ss_padding_len)) {
|
||||
DEBUG(0,("create_next_pdu_ntlmssp: failed to add %u bytes of pad data.\n",
|
||||
(unsigned int)ss_padding_len));
|
||||
prs_mem_free(&p->out_data.frag);
|
||||
data_blob_free(&p->out_data.frag);
|
||||
return False;
|
||||
}
|
||||
}
|
||||
@ -209,9 +196,10 @@ static bool create_next_pdu_ntlmssp(pipes_struct *p)
|
||||
auth_level = DCERPC_AUTH_LEVEL_INTEGRITY;
|
||||
}
|
||||
|
||||
frame = talloc_stackframe();
|
||||
|
||||
/* auth_blob is intentionally null, it will be appended later */
|
||||
status = dcerpc_push_dcerpc_auth(
|
||||
prs_get_mem_context(&p->out_data.frag),
|
||||
status = dcerpc_push_dcerpc_auth(frame,
|
||||
auth_type,
|
||||
auth_level,
|
||||
ss_padding_len,
|
||||
@ -220,30 +208,30 @@ static bool create_next_pdu_ntlmssp(pipes_struct *p)
|
||||
&blob);
|
||||
|
||||
/* Store auth header in the data stream. */
|
||||
if (!prs_copy_data_in(&p->out_data.frag,
|
||||
if (!data_blob_append(p->mem_ctx,
|
||||
&p->out_data.frag,
|
||||
(char *)blob.data, blob.length)) {
|
||||
DEBUG(0, ("Out of memory.\n"));
|
||||
prs_mem_free(&p->out_data.frag);
|
||||
data_blob_free(&p->out_data.frag);
|
||||
return False;
|
||||
}
|
||||
|
||||
/* Generate the sign blob. */
|
||||
|
||||
frame = talloc_stackframe();
|
||||
switch (p->auth.auth_level) {
|
||||
case DCERPC_AUTH_LEVEL_PRIVACY:
|
||||
/* Data portion is encrypted. */
|
||||
status = auth_ntlmssp_seal_packet(
|
||||
a, frame,
|
||||
(uint8_t *)prs_data_p(&p->out_data.frag)
|
||||
p->out_data.frag.data
|
||||
+ RPC_HEADER_LEN + RPC_HDR_RESP_LEN,
|
||||
data_len + ss_padding_len,
|
||||
(unsigned char *)prs_data_p(&p->out_data.frag),
|
||||
(size_t)prs_offset(&p->out_data.frag),
|
||||
p->out_data.frag.data,
|
||||
p->out_data.frag.length,
|
||||
&auth_blob);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
talloc_free(frame);
|
||||
prs_mem_free(&p->out_data.frag);
|
||||
data_blob_free(&p->out_data.frag);
|
||||
return False;
|
||||
}
|
||||
break;
|
||||
@ -251,31 +239,31 @@ static bool create_next_pdu_ntlmssp(pipes_struct *p)
|
||||
/* Data is signed. */
|
||||
status = auth_ntlmssp_sign_packet(
|
||||
a, frame,
|
||||
(unsigned char *)prs_data_p(&p->out_data.frag)
|
||||
p->out_data.frag.data
|
||||
+ RPC_HEADER_LEN + RPC_HDR_RESP_LEN,
|
||||
data_len + ss_padding_len,
|
||||
(unsigned char *)prs_data_p(&p->out_data.frag),
|
||||
(size_t)prs_offset(&p->out_data.frag),
|
||||
p->out_data.frag.data,
|
||||
p->out_data.frag.length,
|
||||
&auth_blob);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
talloc_free(frame);
|
||||
prs_mem_free(&p->out_data.frag);
|
||||
data_blob_free(&p->out_data.frag);
|
||||
return False;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
talloc_free(frame);
|
||||
prs_mem_free(&p->out_data.frag);
|
||||
data_blob_free(&p->out_data.frag);
|
||||
return False;
|
||||
}
|
||||
|
||||
/* Finally append the auth blob. */
|
||||
if (!prs_copy_data_in(&p->out_data.frag, (char *)auth_blob.data,
|
||||
NTLMSSP_SIG_SIZE)) {
|
||||
if (!data_blob_append(p->mem_ctx, &p->out_data.frag,
|
||||
auth_blob.data, NTLMSSP_SIG_SIZE)) {
|
||||
DEBUG(0, ("Failed to add %u bytes auth blob.\n",
|
||||
(unsigned int)NTLMSSP_SIG_SIZE));
|
||||
talloc_free(frame);
|
||||
prs_mem_free(&p->out_data.frag);
|
||||
data_blob_free(&p->out_data.frag);
|
||||
return False;
|
||||
}
|
||||
talloc_free(frame);
|
||||
@ -382,75 +370,61 @@ static bool create_next_pdu_schannel(pipes_struct *p)
|
||||
hdr_flags |= DCERPC_PFC_FLAG_LAST;
|
||||
}
|
||||
|
||||
/*
|
||||
* Init the parse struct to point at the outgoing
|
||||
* data.
|
||||
*/
|
||||
prs_init_empty(&p->out_data.frag, p->mem_ctx, MARSHALL);
|
||||
|
||||
/* Set the data into the PDU. */
|
||||
u.response.stub_and_verifier =
|
||||
data_blob_const(p->out_data.rdata.data +
|
||||
p->out_data.data_sent_length, data_len);
|
||||
|
||||
status = dcerpc_push_ncacn_packet(
|
||||
prs_get_mem_context(&p->out_data.frag),
|
||||
/* Store the packet in the data stream. */
|
||||
status = dcerpc_push_ncacn_packet(p->mem_ctx,
|
||||
DCERPC_PKT_RESPONSE,
|
||||
hdr_flags,
|
||||
RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN,
|
||||
p->call_id,
|
||||
&u,
|
||||
&blob);
|
||||
&p->out_data.frag);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
DEBUG(0, ("Failed to marshall RPC Header.\n"));
|
||||
prs_mem_free(&p->out_data.frag);
|
||||
return False;
|
||||
}
|
||||
|
||||
/* Store the data offset. */
|
||||
data_pos = blob.length - data_len;
|
||||
data_pos = p->out_data.frag.length - data_len;
|
||||
|
||||
/* Set the proper length on the pdu */
|
||||
dcerpc_set_frag_length(&blob, blob.length +
|
||||
ss_padding_len +
|
||||
RPC_HDR_AUTH_LEN +
|
||||
RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN);
|
||||
|
||||
/* Store the packet in the data stream. */
|
||||
if (!prs_copy_data_in(&p->out_data.frag,
|
||||
(char *)blob.data, blob.length)) {
|
||||
DEBUG(0, ("Out of memory.\n"));
|
||||
prs_mem_free(&p->out_data.frag);
|
||||
return False;
|
||||
}
|
||||
dcerpc_set_frag_length(&p->out_data.frag,
|
||||
p->out_data.frag.length +
|
||||
ss_padding_len +
|
||||
RPC_HDR_AUTH_LEN +
|
||||
RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN);
|
||||
|
||||
/* Append the sign/seal padding data. */
|
||||
if (ss_padding_len) {
|
||||
char pad[SERVER_NDR_PADDING_SIZE];
|
||||
memset(pad, '\0', SERVER_NDR_PADDING_SIZE);
|
||||
if (!prs_copy_data_in(&p->out_data.frag, pad,
|
||||
if (!data_blob_append(p->mem_ctx,
|
||||
&p->out_data.frag, pad,
|
||||
ss_padding_len)) {
|
||||
DEBUG(0,("create_next_pdu_schannel: failed to add %u bytes of pad data.\n", (unsigned int)ss_padding_len));
|
||||
prs_mem_free(&p->out_data.frag);
|
||||
data_blob_free(&p->out_data.frag);
|
||||
return False;
|
||||
}
|
||||
}
|
||||
|
||||
/* auth_blob is intentionally null, it will be appended later */
|
||||
status = dcerpc_push_dcerpc_auth(
|
||||
prs_get_mem_context(&p->out_data.frag),
|
||||
DCERPC_AUTH_TYPE_SCHANNEL,
|
||||
p->auth.auth_level,
|
||||
ss_padding_len,
|
||||
1, /* context id. */
|
||||
&auth_blob,
|
||||
&blob);
|
||||
status = dcerpc_push_dcerpc_auth(talloc_tos(),
|
||||
DCERPC_AUTH_TYPE_SCHANNEL,
|
||||
p->auth.auth_level,
|
||||
ss_padding_len,
|
||||
1, /* context id. */
|
||||
&auth_blob,
|
||||
&blob);
|
||||
|
||||
/* Store auth header in the data stream. */
|
||||
if (!prs_copy_data_in(&p->out_data.frag,
|
||||
(char *)blob.data, blob.length)) {
|
||||
if (!data_blob_append(p->mem_ctx, &p->out_data.frag,
|
||||
blob.data, blob.length)) {
|
||||
DEBUG(0, ("Out of memory.\n"));
|
||||
prs_mem_free(&p->out_data.frag);
|
||||
data_blob_free(&p->out_data.frag);
|
||||
return False;
|
||||
}
|
||||
|
||||
@ -458,7 +432,7 @@ static bool create_next_pdu_schannel(pipes_struct *p)
|
||||
* Schannel processing.
|
||||
*/
|
||||
|
||||
blob = data_blob_const(prs_data_p(&p->out_data.frag) + data_pos,
|
||||
blob = data_blob_const(p->out_data.frag.data + data_pos,
|
||||
data_len + ss_padding_len);
|
||||
|
||||
switch (p->auth.auth_level) {
|
||||
@ -486,7 +460,7 @@ static bool create_next_pdu_schannel(pipes_struct *p)
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
DEBUG(0,("create_next_pdu_schannel: failed to process packet: %s\n",
|
||||
nt_errstr(status)));
|
||||
prs_mem_free(&p->out_data.frag);
|
||||
data_blob_free(&p->out_data.frag);
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -496,9 +470,9 @@ static bool create_next_pdu_schannel(pipes_struct *p)
|
||||
dump_NL_AUTH_SIGNATURE(talloc_tos(), &auth_blob);
|
||||
}
|
||||
|
||||
if (!prs_copy_data_in(&p->out_data.frag,
|
||||
(char *)auth_blob.data, auth_blob.length)) {
|
||||
prs_mem_free(&p->out_data.frag);
|
||||
if (!data_blob_append(p->mem_ctx, &p->out_data.frag,
|
||||
auth_blob.data, auth_blob.length)) {
|
||||
data_blob_free(&p->out_data.frag);
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -519,7 +493,6 @@ static bool create_next_pdu_schannel(pipes_struct *p)
|
||||
|
||||
static bool create_next_pdu_noauth(pipes_struct *p)
|
||||
{
|
||||
DATA_BLOB blob;
|
||||
uint8_t hdr_flags;
|
||||
NTSTATUS status;
|
||||
uint32 data_len;
|
||||
@ -585,36 +558,21 @@ static bool create_next_pdu_noauth(pipes_struct *p)
|
||||
hdr_flags |= DCERPC_PFC_FLAG_LAST;
|
||||
}
|
||||
|
||||
/*
|
||||
* Init the parse struct to point at the outgoing
|
||||
* data.
|
||||
*/
|
||||
prs_init_empty(&p->out_data.frag, p->mem_ctx, MARSHALL);
|
||||
|
||||
/* Set the data into the PDU. */
|
||||
u.response.stub_and_verifier =
|
||||
data_blob_const(p->out_data.rdata.data +
|
||||
p->out_data.data_sent_length, data_len);
|
||||
|
||||
status = dcerpc_push_ncacn_packet(
|
||||
prs_get_mem_context(&p->out_data.frag),
|
||||
DCERPC_PKT_RESPONSE,
|
||||
hdr_flags,
|
||||
0,
|
||||
p->call_id,
|
||||
&u,
|
||||
&blob);
|
||||
/* Store the packet in the data stream. */
|
||||
status = dcerpc_push_ncacn_packet(p->mem_ctx,
|
||||
DCERPC_PKT_RESPONSE,
|
||||
hdr_flags,
|
||||
0,
|
||||
p->call_id,
|
||||
&u,
|
||||
&p->out_data.frag);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
DEBUG(0, ("Failed to marshall RPC Header.\n"));
|
||||
prs_mem_free(&p->out_data.frag);
|
||||
return False;
|
||||
}
|
||||
|
||||
/* Store the packet in the data stream. */
|
||||
if (!prs_copy_data_in(&p->out_data.frag,
|
||||
(char *)blob.data, blob.length)) {
|
||||
DEBUG(0, ("Out of memory.\n"));
|
||||
prs_mem_free(&p->out_data.frag);
|
||||
return False;
|
||||
}
|
||||
|
||||
@ -828,19 +786,10 @@ static bool setup_bind_nak(pipes_struct *p, struct ncacn_packet *pkt)
|
||||
{
|
||||
NTSTATUS status;
|
||||
union dcerpc_payload u;
|
||||
DATA_BLOB blob;
|
||||
|
||||
/* Free any memory in the current return data buffer. */
|
||||
data_blob_free(&p->out_data.rdata);
|
||||
|
||||
/*
|
||||
* Marshall directly into the outgoing PDU space. We
|
||||
* must do this as we need to set to the bind response
|
||||
* header and are never sending more than one PDU here.
|
||||
*/
|
||||
|
||||
prs_init_empty(&p->out_data.frag, p->mem_ctx, MARSHALL);
|
||||
|
||||
/*
|
||||
* Initialize a bind_nak header.
|
||||
*/
|
||||
@ -849,6 +798,12 @@ static bool setup_bind_nak(pipes_struct *p, struct ncacn_packet *pkt)
|
||||
|
||||
u.bind_nak.reject_reason = 0;
|
||||
|
||||
/*
|
||||
* Marshall directly into the outgoing PDU space. We
|
||||
* must do this as we need to set to the bind response
|
||||
* header and are never sending more than one PDU here.
|
||||
*/
|
||||
|
||||
status = dcerpc_push_ncacn_packet(p->mem_ctx,
|
||||
DCERPC_PKT_BIND_NAK,
|
||||
DCERPC_PFC_FLAG_FIRST |
|
||||
@ -856,15 +811,8 @@ static bool setup_bind_nak(pipes_struct *p, struct ncacn_packet *pkt)
|
||||
0,
|
||||
pkt->call_id,
|
||||
&u,
|
||||
&blob);
|
||||
&p->out_data.frag);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
prs_mem_free(&p->out_data.frag);
|
||||
return False;
|
||||
}
|
||||
|
||||
if (!prs_copy_data_in(&p->out_data.frag,
|
||||
(char *)blob.data, blob.length)) {
|
||||
prs_mem_free(&p->out_data.frag);
|
||||
return False;
|
||||
}
|
||||
|
||||
@ -889,19 +837,10 @@ bool setup_fault_pdu(pipes_struct *p, NTSTATUS fault_status)
|
||||
{
|
||||
NTSTATUS status;
|
||||
union dcerpc_payload u;
|
||||
DATA_BLOB blob;
|
||||
|
||||
/* Free any memory in the current return data buffer. */
|
||||
data_blob_free(&p->out_data.rdata);
|
||||
|
||||
/*
|
||||
* Marshall directly into the outgoing PDU space. We
|
||||
* must do this as we need to set to the bind response
|
||||
* header and are never sending more than one PDU here.
|
||||
*/
|
||||
|
||||
prs_init_empty(&p->out_data.frag, p->mem_ctx, MARSHALL);
|
||||
|
||||
/*
|
||||
* Initialize a fault header.
|
||||
*/
|
||||
@ -911,6 +850,12 @@ bool setup_fault_pdu(pipes_struct *p, NTSTATUS fault_status)
|
||||
u.fault.status = NT_STATUS_V(fault_status);
|
||||
u.fault._pad = data_blob_talloc_zero(p->mem_ctx, 4);
|
||||
|
||||
/*
|
||||
* Marshall directly into the outgoing PDU space. We
|
||||
* must do this as we need to set to the bind response
|
||||
* header and are never sending more than one PDU here.
|
||||
*/
|
||||
|
||||
status = dcerpc_push_ncacn_packet(p->mem_ctx,
|
||||
DCERPC_PKT_FAULT,
|
||||
DCERPC_PFC_FLAG_FIRST |
|
||||
@ -919,15 +864,8 @@ bool setup_fault_pdu(pipes_struct *p, NTSTATUS fault_status)
|
||||
0,
|
||||
p->call_id,
|
||||
&u,
|
||||
&blob);
|
||||
&p->out_data.frag);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
prs_mem_free(&p->out_data.frag);
|
||||
return False;
|
||||
}
|
||||
|
||||
if (!prs_copy_data_in(&p->out_data.frag,
|
||||
(char *)blob.data, blob.length)) {
|
||||
prs_mem_free(&p->out_data.frag);
|
||||
return False;
|
||||
}
|
||||
|
||||
@ -1425,7 +1363,6 @@ bool api_pipe_bind_req(pipes_struct *p, struct ncacn_packet *pkt)
|
||||
struct dcerpc_ack_ctx bind_ack_ctx;
|
||||
DATA_BLOB auth_resp = data_blob_null;
|
||||
DATA_BLOB auth_blob = data_blob_null;
|
||||
DATA_BLOB blob = data_blob_null;
|
||||
int pad_len = 0;
|
||||
|
||||
/* No rebinds on a bound pipe - use alter context. */
|
||||
@ -1491,14 +1428,6 @@ bool api_pipe_bind_req(pipes_struct *p, struct ncacn_packet *pkt)
|
||||
assoc_gid = 0x53f0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Marshall directly into the outgoing PDU space. We
|
||||
* must do this as we need to set to the bind response
|
||||
* header and are never sending more than one PDU here.
|
||||
*/
|
||||
|
||||
prs_init_empty(&p->out_data.frag, p->mem_ctx, MARSHALL);
|
||||
|
||||
/*
|
||||
* Create the bind response struct.
|
||||
*/
|
||||
@ -1634,12 +1563,20 @@ bool api_pipe_bind_req(pipes_struct *p, struct ncacn_packet *pkt)
|
||||
/* NOTE: We leave the auth_info empty so we can calculate the padding
|
||||
* later and then append the auth_info --simo */
|
||||
|
||||
status = dcerpc_push_ncacn_packet(pkt, DCERPC_PKT_BIND_ACK,
|
||||
/*
|
||||
* Marshall directly into the outgoing PDU space. We
|
||||
* must do this as we need to set to the bind response
|
||||
* header and are never sending more than one PDU here.
|
||||
*/
|
||||
|
||||
status = dcerpc_push_ncacn_packet(p->mem_ctx,
|
||||
DCERPC_PKT_BIND_ACK,
|
||||
DCERPC_PFC_FLAG_FIRST |
|
||||
DCERPC_PFC_FLAG_LAST,
|
||||
auth_resp.length,
|
||||
pkt->call_id,
|
||||
&u, &blob);
|
||||
&u,
|
||||
&p->out_data.frag);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
DEBUG(0, ("Failed to marshall bind_ack packet. (%s)\n",
|
||||
nt_errstr(status)));
|
||||
@ -1648,7 +1585,7 @@ bool api_pipe_bind_req(pipes_struct *p, struct ncacn_packet *pkt)
|
||||
if (auth_resp.length) {
|
||||
|
||||
/* Work out any padding needed before the auth footer. */
|
||||
pad_len = blob.length % SERVER_NDR_PADDING_SIZE;
|
||||
pad_len = p->out_data.frag.length % SERVER_NDR_PADDING_SIZE;
|
||||
if (pad_len) {
|
||||
pad_len = SERVER_NDR_PADDING_SIZE - pad_len;
|
||||
DEBUG(10, ("auth pad_len = %u\n",
|
||||
@ -1670,20 +1607,17 @@ bool api_pipe_bind_req(pipes_struct *p, struct ncacn_packet *pkt)
|
||||
|
||||
/* Now that we have the auth len store it into the right place in
|
||||
* the dcerpc header */
|
||||
dcerpc_set_frag_length(&blob, blob.length + pad_len + auth_blob.length);
|
||||
|
||||
/* And finally copy all bits in the output pdu */
|
||||
if (!prs_copy_data_in(&p->out_data.frag,
|
||||
(char *)blob.data, blob.length)) {
|
||||
DEBUG(0, ("Failed to copy data to output buffer.\n"));
|
||||
goto err_exit;
|
||||
}
|
||||
dcerpc_set_frag_length(&p->out_data.frag,
|
||||
p->out_data.frag.length +
|
||||
pad_len +
|
||||
auth_blob.length);
|
||||
|
||||
if (auth_blob.length) {
|
||||
if (pad_len) {
|
||||
char pad[SERVER_NDR_PADDING_SIZE];
|
||||
memset(pad, '\0', SERVER_NDR_PADDING_SIZE);
|
||||
if (!prs_copy_data_in(&p->out_data.frag, pad, pad_len)) {
|
||||
if (!data_blob_append(p->mem_ctx, &p->out_data.frag,
|
||||
pad, pad_len)) {
|
||||
DEBUG(0, ("api_pipe_bind_req: failed to add "
|
||||
"%u bytes of pad data.\n",
|
||||
(unsigned int)pad_len));
|
||||
@ -1691,9 +1625,8 @@ bool api_pipe_bind_req(pipes_struct *p, struct ncacn_packet *pkt)
|
||||
}
|
||||
}
|
||||
|
||||
if (!prs_copy_data_in(&p->out_data.frag,
|
||||
(char *)auth_blob.data,
|
||||
auth_blob.length)) {
|
||||
if (!data_blob_append(p->mem_ctx, &p->out_data.frag,
|
||||
auth_blob.data, auth_blob.length)) {
|
||||
DEBUG(0, ("Append of auth info failed.\n"));
|
||||
goto err_exit;
|
||||
}
|
||||
@ -1707,14 +1640,12 @@ bool api_pipe_bind_req(pipes_struct *p, struct ncacn_packet *pkt)
|
||||
p->out_data.current_pdu_sent = 0;
|
||||
|
||||
TALLOC_FREE(auth_blob.data);
|
||||
TALLOC_FREE(blob.data);
|
||||
return True;
|
||||
|
||||
err_exit:
|
||||
|
||||
prs_mem_free(&p->out_data.frag);
|
||||
data_blob_free(&p->out_data.frag);
|
||||
TALLOC_FREE(auth_blob.data);
|
||||
TALLOC_FREE(blob.data);
|
||||
return setup_bind_nak(p, pkt);
|
||||
}
|
||||
|
||||
@ -1732,7 +1663,6 @@ bool api_pipe_alter_context(pipes_struct *p, struct ncacn_packet *pkt)
|
||||
struct dcerpc_ack_ctx bind_ack_ctx;
|
||||
DATA_BLOB auth_resp = data_blob_null;
|
||||
DATA_BLOB auth_blob = data_blob_null;
|
||||
DATA_BLOB blob = data_blob_null;
|
||||
int pad_len = 0;
|
||||
|
||||
DEBUG(5,("api_pipe_alter_context: make response. %d\n", __LINE__));
|
||||
@ -1743,14 +1673,6 @@ bool api_pipe_alter_context(pipes_struct *p, struct ncacn_packet *pkt)
|
||||
assoc_gid = 0x53f0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Marshall directly into the outgoing PDU space. We
|
||||
* must do this as we need to set to the bind response
|
||||
* header and are never sending more than one PDU here.
|
||||
*/
|
||||
|
||||
prs_init_empty(&p->out_data.frag, p->mem_ctx, MARSHALL);
|
||||
|
||||
/*
|
||||
* Create the bind response struct.
|
||||
*/
|
||||
@ -1840,12 +1762,20 @@ bool api_pipe_alter_context(pipes_struct *p, struct ncacn_packet *pkt)
|
||||
/* NOTE: We leave the auth_info empty so we can calculate the padding
|
||||
* later and then append the auth_info --simo */
|
||||
|
||||
status = dcerpc_push_ncacn_packet(pkt, DCERPC_PKT_ALTER_RESP,
|
||||
/*
|
||||
* Marshall directly into the outgoing PDU space. We
|
||||
* must do this as we need to set to the bind response
|
||||
* header and are never sending more than one PDU here.
|
||||
*/
|
||||
|
||||
status = dcerpc_push_ncacn_packet(p->mem_ctx,
|
||||
DCERPC_PKT_ALTER_RESP,
|
||||
DCERPC_PFC_FLAG_FIRST |
|
||||
DCERPC_PFC_FLAG_LAST,
|
||||
auth_resp.length,
|
||||
pkt->call_id,
|
||||
&u, &blob);
|
||||
&u,
|
||||
&p->out_data.frag);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
DEBUG(0, ("Failed to marshall bind_ack packet. (%s)\n",
|
||||
nt_errstr(status)));
|
||||
@ -1854,7 +1784,7 @@ bool api_pipe_alter_context(pipes_struct *p, struct ncacn_packet *pkt)
|
||||
if (auth_resp.length) {
|
||||
|
||||
/* Work out any padding needed before the auth footer. */
|
||||
pad_len = blob.length % SERVER_NDR_PADDING_SIZE;
|
||||
pad_len = p->out_data.frag.length % SERVER_NDR_PADDING_SIZE;
|
||||
if (pad_len) {
|
||||
pad_len = SERVER_NDR_PADDING_SIZE - pad_len;
|
||||
DEBUG(10, ("auth pad_len = %u\n",
|
||||
@ -1876,20 +1806,17 @@ bool api_pipe_alter_context(pipes_struct *p, struct ncacn_packet *pkt)
|
||||
|
||||
/* Now that we have the auth len store it into the right place in
|
||||
* the dcerpc header */
|
||||
dcerpc_set_frag_length(&blob, blob.length + pad_len + auth_blob.length);
|
||||
|
||||
/* And finally copy all bits in the output pdu */
|
||||
if (!prs_copy_data_in(&p->out_data.frag,
|
||||
(char *)blob.data, blob.length)) {
|
||||
DEBUG(0, ("Failed to copy data to output buffer.\n"));
|
||||
goto err_exit;
|
||||
}
|
||||
dcerpc_set_frag_length(&p->out_data.frag,
|
||||
p->out_data.frag.length +
|
||||
pad_len + auth_blob.length);
|
||||
|
||||
if (auth_resp.length) {
|
||||
if (pad_len) {
|
||||
char pad[SERVER_NDR_PADDING_SIZE];
|
||||
memset(pad, '\0', SERVER_NDR_PADDING_SIZE);
|
||||
if (!prs_copy_data_in(&p->out_data.frag, pad, pad_len)) {
|
||||
if (!data_blob_append(p->mem_ctx,
|
||||
&p->out_data.frag,
|
||||
pad, pad_len)) {
|
||||
DEBUG(0, ("api_pipe_bind_req: failed to add "
|
||||
"%u bytes of pad data.\n",
|
||||
(unsigned int)pad_len));
|
||||
@ -1897,9 +1824,8 @@ bool api_pipe_alter_context(pipes_struct *p, struct ncacn_packet *pkt)
|
||||
}
|
||||
}
|
||||
|
||||
if (!prs_copy_data_in(&p->out_data.frag,
|
||||
(char *)auth_blob.data,
|
||||
auth_blob.length)) {
|
||||
if (!data_blob_append(p->mem_ctx, &p->out_data.frag,
|
||||
auth_blob.data, auth_blob.length)) {
|
||||
DEBUG(0, ("Append of auth info failed.\n"));
|
||||
goto err_exit;
|
||||
}
|
||||
@ -1913,14 +1839,12 @@ bool api_pipe_alter_context(pipes_struct *p, struct ncacn_packet *pkt)
|
||||
p->out_data.current_pdu_sent = 0;
|
||||
|
||||
TALLOC_FREE(auth_blob.data);
|
||||
TALLOC_FREE(blob.data);
|
||||
return True;
|
||||
|
||||
err_exit:
|
||||
|
||||
prs_mem_free(&p->out_data.frag);
|
||||
data_blob_free(&p->out_data.frag);
|
||||
TALLOC_FREE(auth_blob.data);
|
||||
TALLOC_FREE(blob.data);
|
||||
return setup_bind_nak(p, pkt);
|
||||
}
|
||||
|
||||
|
@ -42,7 +42,7 @@ static bool pipe_init_outgoing_data(pipes_struct *p)
|
||||
o_data->data_sent_length = 0;
|
||||
o_data->current_pdu_sent = 0;
|
||||
|
||||
prs_mem_free(&o_data->frag);
|
||||
data_blob_free(&o_data->frag);
|
||||
|
||||
/* Free any memory in the current return data buffer. */
|
||||
data_blob_free(&o_data->rdata);
|
||||
@ -143,7 +143,7 @@ static bool get_pdu_size(pipes_struct *p)
|
||||
|
||||
static void free_pipe_context(pipes_struct *p)
|
||||
{
|
||||
prs_mem_free(&p->out_data.frag);
|
||||
data_blob_free(&p->out_data.frag);
|
||||
data_blob_free(&p->out_data.rdata);
|
||||
prs_mem_free(&p->in_data.data);
|
||||
|
||||
@ -803,7 +803,7 @@ static ssize_t read_from_internal_pipe(struct pipes_struct *p, char *data,
|
||||
* PDU.
|
||||
*/
|
||||
|
||||
pdu_remaining = prs_offset(&p->out_data.frag)
|
||||
pdu_remaining = p->out_data.frag.length
|
||||
- p->out_data.current_pdu_sent;
|
||||
|
||||
if (pdu_remaining > 0) {
|
||||
@ -812,12 +812,12 @@ static ssize_t read_from_internal_pipe(struct pipes_struct *p, char *data,
|
||||
DEBUG(10,("read_from_pipe: %s: current_pdu_len = %u, "
|
||||
"current_pdu_sent = %u returning %d bytes.\n",
|
||||
get_pipe_name_from_syntax(talloc_tos(), &p->syntax),
|
||||
(unsigned int)prs_offset(&p->out_data.frag),
|
||||
(unsigned int)p->out_data.frag.length,
|
||||
(unsigned int)p->out_data.current_pdu_sent,
|
||||
(int)data_returned));
|
||||
|
||||
memcpy(data,
|
||||
prs_data_p(&p->out_data.frag)
|
||||
p->out_data.frag.data
|
||||
+ p->out_data.current_pdu_sent,
|
||||
data_returned);
|
||||
|
||||
@ -858,20 +858,20 @@ static ssize_t read_from_internal_pipe(struct pipes_struct *p, char *data,
|
||||
return -1;
|
||||
}
|
||||
|
||||
data_returned = MIN(n, prs_offset(&p->out_data.frag));
|
||||
data_returned = MIN(n, p->out_data.frag.length);
|
||||
|
||||
memcpy( data, prs_data_p(&p->out_data.frag), (size_t)data_returned);
|
||||
memcpy(data, p->out_data.frag.data, (size_t)data_returned);
|
||||
p->out_data.current_pdu_sent += (uint32)data_returned;
|
||||
|
||||
out:
|
||||
(*is_data_outstanding) = prs_offset(&p->out_data.frag) > n;
|
||||
(*is_data_outstanding) = p->out_data.frag.length > n;
|
||||
|
||||
if (p->out_data.current_pdu_sent == prs_offset(&p->out_data.frag)) {
|
||||
if (p->out_data.current_pdu_sent == p->out_data.frag.length) {
|
||||
/* We've returned everything in the out_data.frag
|
||||
* so we're done with this pdu. Free it and reset
|
||||
* current_pdu_sent. */
|
||||
p->out_data.current_pdu_sent = 0;
|
||||
prs_mem_free(&p->out_data.frag);
|
||||
data_blob_free(&p->out_data.frag);
|
||||
|
||||
if (p->out_data.data_sent_length >= p->out_data.rdata.length) {
|
||||
/*
|
||||
|
Loading…
Reference in New Issue
Block a user