summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source3/rpc_server/srv_pipe.c200
1 files changed, 89 insertions, 111 deletions
diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c
index 551041149f..3034b8aa68 100644
--- a/source3/rpc_server/srv_pipe.c
+++ b/source3/rpc_server/srv_pipe.c
@@ -1448,19 +1448,17 @@ static bool pipe_ntlmssp_auth_bind(pipes_struct *p,
bool api_pipe_bind_req(pipes_struct *p, struct ncacn_packet *pkt)
{
- RPC_HDR hdr;
- RPC_HDR_BA hdr_ba;
struct dcerpc_auth auth_info;
uint16 assoc_gid;
- fstring ack_pipe_name;
- prs_struct out_hdr_ba;
- int auth_len = 0;
unsigned int auth_type = DCERPC_AUTH_TYPE_NONE;
- uint32_t ss_padding_len = 0;
NTSTATUS status;
struct ndr_syntax_id id;
+ union dcerpc_payload u;
+ 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. */
if (p->pipe_bound) {
@@ -1517,10 +1515,6 @@ bool api_pipe_bind_req(pipes_struct *p, struct ncacn_packet *pkt)
}
}
- /* name has to be \PIPE\xxxxx */
- fstrcpy(ack_pipe_name, "\\PIPE\\");
- fstrcat(ack_pipe_name, rpc_srv_get_pipe_srv_name(&id));
-
DEBUG(5,("api_pipe_bind_req: make response. %d\n", __LINE__));
if (pkt->u.bind.assoc_group_id != 0) {
@@ -1538,17 +1532,6 @@ bool api_pipe_bind_req(pipes_struct *p, struct ncacn_packet *pkt)
prs_init_empty(&p->out_data.frag, p->mem_ctx, MARSHALL);
/*
- * Setup the memory to marshall the ba header, and the
- * auth footers.
- */
-
- if(!prs_init(&out_hdr_ba, 1024, p->mem_ctx, MARSHALL)) {
- DEBUG(0,("api_pipe_bind_req: malloc out_hdr_ba failed.\n"));
- prs_mem_free(&p->out_data.frag);
- return False;
- }
-
- /*
* Create the bind response struct.
*/
@@ -1562,48 +1545,22 @@ bool api_pipe_bind_req(pipes_struct *p, struct ncacn_packet *pkt)
&pkt->u.bind.ctx_list[0].abstract_syntax,
&pkt->u.bind.ctx_list[0].transfer_syntaxes[0],
pkt->u.bind.ctx_list[0].context_id)) {
- init_rpc_hdr_ba(&hdr_ba,
- RPC_MAX_PDU_FRAG_LEN,
- RPC_MAX_PDU_FRAG_LEN,
- assoc_gid,
- ack_pipe_name,
- 0x1, 0x0, 0x0,
- &pkt->u.bind.ctx_list[0].transfer_syntaxes[0]);
+
+ bind_ack_ctx.result = 0;
+ bind_ack_ctx.reason = 0;
+ bind_ack_ctx.syntax = pkt->u.bind.ctx_list[0].transfer_syntaxes[0];
} else {
- /* Rejection reason: abstract syntax not supported */
- init_rpc_hdr_ba(&hdr_ba, RPC_MAX_PDU_FRAG_LEN,
- RPC_MAX_PDU_FRAG_LEN, assoc_gid,
- ack_pipe_name, 0x1, 0x2, 0x1,
- &null_ndr_syntax_id);
p->pipe_bound = False;
- }
-
- /*
- * and marshall it.
- */
-
- if(!smb_io_rpc_hdr_ba("", &hdr_ba, &out_hdr_ba, 0)) {
- DEBUG(0,("api_pipe_bind_req: marshalling of RPC_HDR_BA failed.\n"));
- goto err_exit;
+ /* Rejection reason: abstract syntax not supported */
+ bind_ack_ctx.result = DCERPC_BIND_PROVIDER_REJECT;
+ bind_ack_ctx.reason = DCERPC_BIND_REASON_ASYNTAX;
+ bind_ack_ctx.syntax = null_ndr_syntax_id;
}
/*
* Check if this is an authenticated bind request.
*/
-
if (pkt->auth_length) {
- /*
- * Decode the authentication verifier.
- */
-
- /* Work out any padding needed before the auth footer. */
- if ((RPC_HEADER_LEN + prs_offset(&out_hdr_ba)) % SERVER_NDR_PADDING_SIZE) {
- ss_padding_len = SERVER_NDR_PADDING_SIZE -
- ((RPC_HEADER_LEN + prs_offset(&out_hdr_ba)) % SERVER_NDR_PADDING_SIZE);
- DEBUG(10,("api_pipe_bind_req: auth pad_len = %u\n",
- (unsigned int)ss_padding_len ));
- }
-
/* Quick length check. Won't catch a bad auth footer,
* prevents overrun. */
@@ -1617,6 +1574,9 @@ bool api_pipe_bind_req(pipes_struct *p, struct ncacn_packet *pkt)
goto err_exit;
}
+ /*
+ * Decode the authentication verifier.
+ */
status = dcerpc_pull_dcerpc_auth(pkt,
&pkt->u.bind.auth_info,
&auth_info);
@@ -1640,11 +1600,8 @@ bool api_pipe_bind_req(pipes_struct *p, struct ncacn_packet *pkt)
(unsigned int)auth_info.auth_level ));
goto err_exit;
}
- } else {
- ZERO_STRUCT(auth_info);
- }
- switch(auth_type) {
+ switch (auth_type) {
case DCERPC_AUTH_TYPE_NTLMSSP:
if (!pipe_ntlmssp_auth_bind(p, pkt,
&auth_info, &auth_resp)) {
@@ -1668,26 +1625,72 @@ bool api_pipe_bind_req(pipes_struct *p, struct ncacn_packet *pkt)
break;
case DCERPC_AUTH_TYPE_NONE:
- /* Unauthenticated bind request. */
- /* We're finished - no more packets. */
- p->auth.auth_type = PIPE_AUTH_TYPE_NONE;
- /* We must set the pipe auth_level here also. */
- p->auth.auth_level = DCERPC_AUTH_LEVEL_NONE;
- p->pipe_bound = True;
- /* The session key was initialized from the SMB
- * session in make_internal_rpc_pipe_p */
- ss_padding_len = 0;
break;
default:
- DEBUG(0,("api_pipe_bind_req: unknown auth type %x requested.\n", auth_type ));
+ DEBUG(0, ("Unknown auth type %x requested.\n", auth_type));
goto err_exit;
+ }
+ }
+
+ if (auth_type == DCERPC_AUTH_TYPE_NONE) {
+ /* Unauthenticated bind request. */
+ /* We're finished - no more packets. */
+ p->auth.auth_type = PIPE_AUTH_TYPE_NONE;
+ /* We must set the pipe auth_level here also. */
+ p->auth.auth_level = DCERPC_AUTH_LEVEL_NONE;
+ p->pipe_bound = True;
+ /* The session key was initialized from the SMB
+ * session in make_internal_rpc_pipe_p */
+ }
+
+ ZERO_STRUCT(u.bind_ack);
+ u.bind_ack.max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
+ u.bind_ack.max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
+ u.bind_ack.assoc_group_id = assoc_gid;
+
+ /* name has to be \PIPE\xxxxx */
+ u.bind_ack.secondary_address =
+ talloc_asprintf(pkt, "\\PIPE\\%s",
+ rpc_srv_get_pipe_srv_name(&id));
+ if (!u.bind_ack.secondary_address) {
+ DEBUG(0, ("Out of memory!\n"));
+ goto err_exit;
+ }
+ u.bind_ack.secondary_address_size =
+ strlen(u.bind_ack.secondary_address) + 1;
+
+ u.bind_ack.num_results = 1;
+ u.bind_ack.ctx_list = &bind_ack_ctx;
+
+ /* 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,
+ DCERPC_PFC_FLAG_FIRST |
+ DCERPC_PFC_FLAG_LAST,
+ auth_resp.length,
+ pkt->call_id,
+ &u, &blob);
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(0, ("Failed to marshall bind_ack packet. (%s)\n",
+ nt_errstr(status)));
}
+
if (auth_resp.length) {
+
+ /* Work out any padding needed before the auth footer. */
+ pad_len = blob.length % SERVER_NDR_PADDING_SIZE;
+ if (pad_len) {
+ pad_len = SERVER_NDR_PADDING_SIZE - pad_len;
+ DEBUG(10, ("auth pad_len = %u\n",
+ (unsigned int)pad_len));
+ }
+
status = dcerpc_push_dcerpc_auth(pkt,
auth_type,
auth_info.auth_level,
- ss_padding_len,
+ pad_len,
1, /* auth_context_id */
&auth_resp,
&auth_blob);
@@ -1697,49 +1700,25 @@ bool api_pipe_bind_req(pipes_struct *p, struct ncacn_packet *pkt)
}
}
- /*
- * Create the header, now we know the length.
- */
-
- if (auth_blob.length) {
- auth_len = auth_blob.length - RPC_HDR_AUTH_LEN;
- }
-
- init_rpc_hdr(&hdr,
- DCERPC_PKT_BIND_ACK,
- DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST,
- pkt->call_id,
- RPC_HEADER_LEN + prs_offset(&out_hdr_ba) +
- ss_padding_len + auth_blob.length,
- auth_len);
-
- /*
- * Marshall the header into the outgoing PDU.
- */
-
- if (!smb_io_rpc_hdr("", &hdr, &p->out_data.frag, 0)) {
- DEBUG(0,("api_pipe_bind_req: marshalling of RPC_HDR failed.\n"));
- goto err_exit;
- }
-
- /*
- * Now add the RPC_HDR_BA and any auth needed.
- */
+ /* 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);
- if(!prs_append_prs_data(&p->out_data.frag, &out_hdr_ba)) {
- DEBUG(0,("api_pipe_bind_req: append of RPC_HDR_BA failed.\n"));
+ /* 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;
}
- if (auth_len) {
- if (ss_padding_len) {
+ 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,
- ss_padding_len)) {
- DEBUG(0,("api_pipe_bind_req: failed to add %u "
- "bytes of pad data.\n",
- (unsigned int)ss_padding_len));
+ if (!prs_copy_data_in(&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));
goto err_exit;
}
}
@@ -1747,7 +1726,7 @@ 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)) {
- DEBUG(0,("api_pipe_bind_req: append of auth info failed.\n"));
+ DEBUG(0, ("Append of auth info failed.\n"));
goto err_exit;
}
}
@@ -1759,16 +1738,15 @@ bool api_pipe_bind_req(pipes_struct *p, struct ncacn_packet *pkt)
p->out_data.data_sent_length = 0;
p->out_data.current_pdu_sent = 0;
- prs_mem_free(&out_hdr_ba);
TALLOC_FREE(auth_blob.data);
-
+ TALLOC_FREE(blob.data);
return True;
err_exit:
prs_mem_free(&p->out_data.frag);
- prs_mem_free(&out_hdr_ba);
TALLOC_FREE(auth_blob.data);
+ TALLOC_FREE(blob.data);
return setup_bind_nak(p, pkt);
}