summaryrefslogtreecommitdiff
path: root/source3/rpc_server
diff options
context:
space:
mode:
Diffstat (limited to 'source3/rpc_server')
-rw-r--r--source3/rpc_server/srv_pipe.c229
1 files changed, 37 insertions, 192 deletions
diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c
index ea9e3de6da..e5aee6691c 100644
--- a/source3/rpc_server/srv_pipe.c
+++ b/source3/rpc_server/srv_pipe.c
@@ -108,149 +108,14 @@ static DATA_BLOB generic_session_key(void)
}
/*******************************************************************
- Handle NTLMSSP.
- ********************************************************************/
-
-static bool add_ntlmssp_auth(struct pipes_struct *p)
-{
- enum dcerpc_AuthLevel auth_level = p->auth.auth_level;
- DATA_BLOB auth_blob = data_blob_null;
- NTSTATUS status;
-
- /* FIXME: Is this right ?
- * Keeping only to avoid changing semantics during refactoring
- * --simo
- */
- if (auth_level != DCERPC_AUTH_LEVEL_PRIVACY) {
- auth_level = DCERPC_AUTH_LEVEL_INTEGRITY;
- }
-
- /* Generate the auth blob. */
- switch (auth_level) {
- case DCERPC_AUTH_LEVEL_PRIVACY:
- /* Data portion is encrypted. */
- status = auth_ntlmssp_seal_packet(
- p->auth.a_u.auth_ntlmssp_state,
- (TALLOC_CTX *)p->out_data.frag.data,
- &p->out_data.frag.data[DCERPC_RESPONSE_LENGTH],
- p->out_data.frag.length
- - DCERPC_RESPONSE_LENGTH
- - DCERPC_AUTH_TRAILER_LENGTH,
- p->out_data.frag.data,
- p->out_data.frag.length,
- &auth_blob);
- break;
-
- case DCERPC_AUTH_LEVEL_INTEGRITY:
- /* Data is signed. */
- status = auth_ntlmssp_sign_packet(
- p->auth.a_u.auth_ntlmssp_state,
- (TALLOC_CTX *)p->out_data.frag.data,
- &p->out_data.frag.data[DCERPC_RESPONSE_LENGTH],
- p->out_data.frag.length
- - DCERPC_RESPONSE_LENGTH
- - DCERPC_AUTH_TRAILER_LENGTH,
- p->out_data.frag.data,
- p->out_data.frag.length,
- &auth_blob);
- break;
-
- default:
- status = NT_STATUS_INTERNAL_ERROR;
- return false;
- }
-
- if (!NT_STATUS_IS_OK(status)) {
- DEBUG(0, ("Failed to add NTLMSSP auth blob: %s\n",
- nt_errstr(status)));
- data_blob_free(&p->out_data.frag);
- return false;
- }
-
- /* Finally append the auth blob. */
- if (!data_blob_append(p->mem_ctx, &p->out_data.frag,
- auth_blob.data, auth_blob.length)) {
- DEBUG(0, ("Failed to add %u bytes auth blob.\n",
- (unsigned int)auth_blob.length));
- data_blob_free(&p->out_data.frag);
- return False;
- }
- data_blob_free(&auth_blob);
-
- return true;
-}
-
-/*******************************************************************
- Append a schannel authenticated fragment.
- ********************************************************************/
-
-static bool add_schannel_auth(struct pipes_struct *p)
-{
- DATA_BLOB auth_blob = data_blob_null;
- NTSTATUS status;
-
- /* Schannel processing. */
- switch (p->auth.auth_level) {
- case DCERPC_AUTH_LEVEL_PRIVACY:
- status = netsec_outgoing_packet(
- p->auth.a_u.schannel_auth,
- (TALLOC_CTX *)p->out_data.frag.data,
- true,
- &p->out_data.frag.data[DCERPC_RESPONSE_LENGTH],
- p->out_data.frag.length
- - DCERPC_RESPONSE_LENGTH
- - DCERPC_AUTH_TRAILER_LENGTH,
- &auth_blob);
- break;
-
- case DCERPC_AUTH_LEVEL_INTEGRITY:
- status = netsec_outgoing_packet(
- p->auth.a_u.schannel_auth,
- (TALLOC_CTX *)p->out_data.frag.data,
- false,
- &p->out_data.frag.data[DCERPC_RESPONSE_LENGTH],
- p->out_data.frag.length
- - DCERPC_RESPONSE_LENGTH
- - DCERPC_AUTH_TRAILER_LENGTH,
- &auth_blob);
- break;
-
- default:
- status = NT_STATUS_INTERNAL_ERROR;
- break;
- }
-
- if (!NT_STATUS_IS_OK(status)) {
- DEBUG(0, ("Failed to add SCHANNEL auth blob: %s\n",
- nt_errstr(status)));
- data_blob_free(&p->out_data.frag);
- return false;
- }
-
- if (DEBUGLEVEL >= 10) {
- dump_NL_AUTH_SIGNATURE(talloc_tos(), &auth_blob);
- }
-
- if (!data_blob_append(p->mem_ctx, &p->out_data.frag,
- auth_blob.data, auth_blob.length)) {
- DEBUG(0, ("Failed to add %u bytes auth blob.\n",
- (unsigned int)auth_blob.length));
- data_blob_free(&p->out_data.frag);
- return false;
- }
- data_blob_free(&auth_blob);
-
- return true;
-}
-
-/*******************************************************************
Generate the next PDU to be returned from the data.
********************************************************************/
static bool create_next_packet(struct pipes_struct *p,
enum dcerpc_AuthType auth_type,
enum dcerpc_AuthLevel auth_level,
- size_t auth_length)
+ size_t auth_length,
+ size_t *_pad_len)
{
union dcerpc_payload u;
uint8_t pfc_flags;
@@ -338,9 +203,6 @@ static bool create_next_packet(struct pipes_struct *p,
}
if (auth_length) {
- DATA_BLOB empty = data_blob_null;
- DATA_BLOB auth_hdr;
-
/* Set the proper length on the pdu, including padding.
* Only needed if an auth trailer will be appended. */
dcerpc_set_frag_length(&p->out_data.frag,
@@ -348,47 +210,12 @@ static bool create_next_packet(struct pipes_struct *p,
+ pad_len
+ DCERPC_AUTH_TRAILER_LENGTH
+ auth_length);
-
- if (pad_len) {
- size_t offset = p->out_data.frag.length;
-
- if (!data_blob_realloc(p->mem_ctx,
- &p->out_data.frag,
- offset + pad_len)) {
- DEBUG(0, ("Failed to add padding!\n"));
- data_blob_free(&p->out_data.frag);
- return false;
- }
- memset(&p->out_data.frag.data[offset], '\0', pad_len);
- }
-
- /* auth blob is intentionally empty,
- * it will be appended later */
- status = dcerpc_push_dcerpc_auth(p->out_data.frag.data,
- auth_type,
- auth_level,
- pad_len,
- 1, /* context id. */
- &empty,
- &auth_hdr);
- if (!NT_STATUS_IS_OK(status)) {
- DEBUG(0, ("Failed to marshall RPC Auth.\n"));
- return false;
- }
-
- /* Store auth header in the data stream. */
- if (!data_blob_append(p->mem_ctx, &p->out_data.frag,
- auth_hdr.data, auth_hdr.length)) {
- DEBUG(0, ("Out of memory.\n"));
- data_blob_free(&p->out_data.frag);
- return false;
- }
- data_blob_free(&auth_hdr);
}
/* Setup the counts for this PDU. */
p->out_data.data_sent_length += data_len;
p->out_data.current_pdu_sent = 0;
+ *_pad_len = pad_len;
return true;
}
@@ -400,6 +227,10 @@ bool create_next_pdu(struct pipes_struct *p)
{
enum dcerpc_AuthType auth_type =
map_pipe_auth_type_to_rpc_auth_type(p->auth.auth_type);
+ size_t auth_len = 0;
+ size_t pad_len = 0;
+ NTSTATUS status;
+ bool ret;
/*
* If we're in the fault state, keep returning fault PDU's until
@@ -416,8 +247,7 @@ bool create_next_pdu(struct pipes_struct *p)
/* This is incorrect for auth level connect. Fixme. JRA */
/* No authentication done. */
- return create_next_packet(p, auth_type,
- p->auth.auth_level, 0);
+ break;
case DCERPC_AUTH_LEVEL_CALL:
case DCERPC_AUTH_LEVEL_PACKET:
@@ -427,27 +257,42 @@ bool create_next_pdu(struct pipes_struct *p)
switch(p->auth.auth_type) {
case PIPE_AUTH_TYPE_NTLMSSP:
case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
- if (!create_next_packet(p, auth_type,
- p->auth.auth_level,
- NTLMSSP_SIG_SIZE)) {
- return false;
- }
- return add_ntlmssp_auth(p);
+ auth_len = NTLMSSP_SIG_SIZE;
+ break;
case PIPE_AUTH_TYPE_SCHANNEL:
- if (!create_next_packet(p, auth_type,
- p->auth.auth_level,
- NL_AUTH_SIGNATURE_SIZE)) {
- return false;
- }
- return add_schannel_auth(p);
- default:
+ auth_len = NL_AUTH_SIGNATURE_SIZE;
break;
+
+ default:
+ goto err_out;
}
- default:
+
break;
+
+ default:
+ goto err_out;
}
+ ret = create_next_packet(p, auth_type,
+ p->auth.auth_level,
+ auth_len, &pad_len);
+ if (!ret) {
+ return false;
+ }
+
+ if (auth_len) {
+ status = dcerpc_add_auth_footer(&p->auth, pad_len,
+ &p->out_data.frag);
+ if (!NT_STATUS_IS_OK(status)) {
+ data_blob_free(&p->out_data.frag);
+ return false;
+ }
+ }
+
+ return true;
+
+err_out:
DEBUG(0, ("Invalid internal auth level %u / type %u\n",
(unsigned int)p->auth.auth_level,
(unsigned int)p->auth.auth_type));