diff options
Diffstat (limited to 'source3/librpc/rpc/dcerpc_helpers.c')
-rw-r--r-- | source3/librpc/rpc/dcerpc_helpers.c | 346 |
1 files changed, 50 insertions, 296 deletions
diff --git a/source3/librpc/rpc/dcerpc_helpers.c b/source3/librpc/rpc/dcerpc_helpers.c index 469e3086c7..5f8c793191 100644 --- a/source3/librpc/rpc/dcerpc_helpers.c +++ b/source3/librpc/rpc/dcerpc_helpers.c @@ -24,10 +24,8 @@ #include "librpc/gen_ndr/ndr_schannel.h" #include "../libcli/auth/schannel.h" #include "../libcli/auth/spnego.h" -#include "../libcli/auth/ntlmssp.h" -#include "ntlmssp_wrap.h" #include "librpc/crypto/gse.h" -#include "librpc/crypto/spnego.h" +#include "auth/gensec/gensec.h" #undef DBGC_CLASS #define DBGC_CLASS DBGC_RPC_PARSE @@ -113,10 +111,6 @@ NTSTATUS dcerpc_pull_ncacn_packet(TALLOC_CTX *mem_ctx, ndr->flags |= LIBNDR_FLAG_BIGENDIAN; } - if (CVAL(blob->data, DCERPC_PFC_OFFSET) & DCERPC_PFC_FLAG_OBJECT_UUID) { - ndr->flags |= LIBNDR_FLAG_OBJECT_PRESENT; - } - ndr_err = ndr_pull_ncacn_packet(ndr, NDR_SCALARS|NDR_BUFFERS, r); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { @@ -270,13 +264,8 @@ NTSTATUS dcerpc_guess_sizes(struct pipe_auth_data *auth, { size_t max_len; size_t mod_len; + struct gensec_security *gensec_security; struct schannel_state *schannel_auth; - struct spnego_context *spnego_ctx; - struct gse_context *gse_ctx; - enum spnego_mech auth_type; - void *auth_ctx; - bool seal = false; - NTSTATUS status; /* no auth token cases first */ switch (auth->auth_level) { @@ -291,7 +280,6 @@ NTSTATUS dcerpc_guess_sizes(struct pipe_auth_data *auth, return NT_STATUS_OK; case DCERPC_AUTH_LEVEL_PRIVACY: - seal = true; break; case DCERPC_AUTH_LEVEL_INTEGRITY: @@ -309,35 +297,11 @@ NTSTATUS dcerpc_guess_sizes(struct pipe_auth_data *auth, /* Treat the same for all authenticated rpc requests. */ switch (auth->auth_type) { case DCERPC_AUTH_TYPE_SPNEGO: - spnego_ctx = talloc_get_type_abort(auth->auth_ctx, - struct spnego_context); - status = spnego_get_negotiated_mech(spnego_ctx, - &auth_type, &auth_ctx); - if (!NT_STATUS_IS_OK(status)) { - return status; - } - switch (auth_type) { - case SPNEGO_NTLMSSP: - *auth_len = NTLMSSP_SIG_SIZE; - break; - - case SPNEGO_KRB5: - gse_ctx = talloc_get_type_abort(auth_ctx, - struct gse_context); - if (!gse_ctx) { - return NT_STATUS_INVALID_PARAMETER; - } - *auth_len = gse_get_signature_length(gse_ctx, - seal, max_len); - break; - - default: - return NT_STATUS_INVALID_PARAMETER; - } - break; - case DCERPC_AUTH_TYPE_NTLMSSP: - *auth_len = NTLMSSP_SIG_SIZE; + case DCERPC_AUTH_TYPE_KRB5: + gensec_security = talloc_get_type_abort(auth->auth_ctx, + struct gensec_security); + *auth_len = gensec_sig_size(gensec_security, max_len); break; case DCERPC_AUTH_TYPE_SCHANNEL: @@ -345,14 +309,6 @@ NTSTATUS dcerpc_guess_sizes(struct pipe_auth_data *auth, struct schannel_state); *auth_len = netsec_outgoing_sig_size(schannel_auth); break; - - case DCERPC_AUTH_TYPE_KRB5: - gse_ctx = talloc_get_type_abort(auth->auth_ctx, - struct gse_context); - *auth_len = gse_get_signature_length(gse_ctx, - seal, max_len); - break; - default: return NT_STATUS_INVALID_PARAMETER; } @@ -382,7 +338,7 @@ NTSTATUS dcerpc_guess_sizes(struct pipe_auth_data *auth, Create and add the NTLMSSP sign/seal auth data. ********************************************************************/ -static NTSTATUS add_ntlmssp_auth_footer(struct auth_ntlmssp_state *auth_state, +static NTSTATUS add_generic_auth_footer(struct gensec_security *gensec_security, enum dcerpc_AuthLevel auth_level, DATA_BLOB *rpc_out) { @@ -392,21 +348,21 @@ static NTSTATUS add_ntlmssp_auth_footer(struct auth_ntlmssp_state *auth_state, DATA_BLOB auth_blob; NTSTATUS status; - if (!auth_state) { + if (!gensec_security) { return NT_STATUS_INVALID_PARAMETER; } switch (auth_level) { case DCERPC_AUTH_LEVEL_PRIVACY: /* Data portion is encrypted. */ - status = auth_ntlmssp_seal_packet(auth_state, - rpc_out->data, - rpc_out->data - + DCERPC_RESPONSE_LENGTH, - data_and_pad_len, - rpc_out->data, - rpc_out->length, - &auth_blob); + status = gensec_seal_packet(gensec_security, + rpc_out->data, + rpc_out->data + + DCERPC_RESPONSE_LENGTH, + data_and_pad_len, + rpc_out->data, + rpc_out->length, + &auth_blob); if (!NT_STATUS_IS_OK(status)) { return status; } @@ -414,14 +370,14 @@ static NTSTATUS add_ntlmssp_auth_footer(struct auth_ntlmssp_state *auth_state, case DCERPC_AUTH_LEVEL_INTEGRITY: /* Data is signed. */ - status = auth_ntlmssp_sign_packet(auth_state, - rpc_out->data, - rpc_out->data - + DCERPC_RESPONSE_LENGTH, - data_and_pad_len, - rpc_out->data, - rpc_out->length, - &auth_blob); + status = gensec_sign_packet(gensec_security, + rpc_out->data, + rpc_out->data + + DCERPC_RESPONSE_LENGTH, + data_and_pad_len, + rpc_out->data, + rpc_out->length, + &auth_blob); if (!NT_STATUS_IS_OK(status)) { return status; } @@ -450,7 +406,7 @@ static NTSTATUS add_ntlmssp_auth_footer(struct auth_ntlmssp_state *auth_state, Check/unseal the NTLMSSP auth data. (Unseal in place). ********************************************************************/ -static NTSTATUS get_ntlmssp_auth_footer(struct auth_ntlmssp_state *auth_state, +static NTSTATUS get_generic_auth_footer(struct gensec_security *gensec_security, enum dcerpc_AuthLevel auth_level, DATA_BLOB *data, DATA_BLOB *full_pkt, DATA_BLOB *auth_token) @@ -458,21 +414,21 @@ static NTSTATUS get_ntlmssp_auth_footer(struct auth_ntlmssp_state *auth_state, switch (auth_level) { case DCERPC_AUTH_LEVEL_PRIVACY: /* Data portion is encrypted. */ - return auth_ntlmssp_unseal_packet(auth_state, - data->data, - data->length, - full_pkt->data, - full_pkt->length, - auth_token); + return gensec_unseal_packet(gensec_security, + data->data, + data->length, + full_pkt->data, + full_pkt->length, + auth_token); case DCERPC_AUTH_LEVEL_INTEGRITY: /* Data is signed. */ - return auth_ntlmssp_check_packet(auth_state, - data->data, - data->length, - full_pkt->data, - full_pkt->length, - auth_token); + return gensec_check_packet(gensec_security, + data->data, + data->length, + full_pkt->data, + full_pkt->length, + auth_token); default: return NT_STATUS_INVALID_PARAMETER; @@ -557,7 +513,7 @@ static NTSTATUS get_schannel_auth_footer(TALLOC_CTX *mem_ctx, case DCERPC_AUTH_LEVEL_PRIVACY: /* Data portion is encrypted. */ return netsec_incoming_packet(auth_state, - mem_ctx, true, + true, data->data, data->length, auth_token); @@ -565,7 +521,7 @@ static NTSTATUS get_schannel_auth_footer(TALLOC_CTX *mem_ctx, case DCERPC_AUTH_LEVEL_INTEGRITY: /* Data is signed. */ return netsec_incoming_packet(auth_state, - mem_ctx, false, + false, data->data, data->length, auth_token); @@ -575,168 +531,6 @@ static NTSTATUS get_schannel_auth_footer(TALLOC_CTX *mem_ctx, } } -/******************************************************************* - Create and add the gssapi sign/seal auth data. - ********************************************************************/ - -static NTSTATUS add_gssapi_auth_footer(struct gse_context *gse_ctx, - enum dcerpc_AuthLevel auth_level, - DATA_BLOB *rpc_out) -{ - DATA_BLOB data; - DATA_BLOB auth_blob; - NTSTATUS status; - - if (!gse_ctx) { - return NT_STATUS_INVALID_PARAMETER; - } - - data.data = rpc_out->data + DCERPC_RESPONSE_LENGTH; - data.length = rpc_out->length - DCERPC_RESPONSE_LENGTH - - DCERPC_AUTH_TRAILER_LENGTH; - - switch (auth_level) { - case DCERPC_AUTH_LEVEL_PRIVACY: - status = gse_seal(talloc_tos(), gse_ctx, &data, &auth_blob); - break; - case DCERPC_AUTH_LEVEL_INTEGRITY: - status = gse_sign(talloc_tos(), gse_ctx, &data, &auth_blob); - break; - default: - status = NT_STATUS_INTERNAL_ERROR; - break; - } - - if (!NT_STATUS_IS_OK(status)) { - DEBUG(1, ("Failed to process packet: %s\n", - nt_errstr(status))); - return status; - } - - /* Finally attach the blob. */ - if (!data_blob_append(NULL, rpc_out, - auth_blob.data, auth_blob.length)) { - return NT_STATUS_NO_MEMORY; - } - - data_blob_free(&auth_blob); - - return NT_STATUS_OK; -} - -/******************************************************************* - Check/unseal the gssapi auth data. (Unseal in place). - ********************************************************************/ - -static NTSTATUS get_gssapi_auth_footer(TALLOC_CTX *mem_ctx, - struct gse_context *gse_ctx, - enum dcerpc_AuthLevel auth_level, - DATA_BLOB *data, DATA_BLOB *full_pkt, - DATA_BLOB *auth_token) -{ - /* TODO: pass in full_pkt when - * DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN is set */ - switch (auth_level) { - case DCERPC_AUTH_LEVEL_PRIVACY: - /* Data portion is encrypted. */ - return gse_unseal(mem_ctx, gse_ctx, - data, auth_token); - - case DCERPC_AUTH_LEVEL_INTEGRITY: - /* Data is signed. */ - return gse_sigcheck(mem_ctx, gse_ctx, - data, auth_token); - default: - return NT_STATUS_INVALID_PARAMETER; - } -} - -/******************************************************************* - Create and add the spnego-negotiated sign/seal auth data. - ********************************************************************/ - -static NTSTATUS add_spnego_auth_footer(struct spnego_context *spnego_ctx, - enum dcerpc_AuthLevel auth_level, - DATA_BLOB *rpc_out) -{ - DATA_BLOB auth_blob; - DATA_BLOB rpc_data; - NTSTATUS status; - - if (!spnego_ctx) { - return NT_STATUS_INVALID_PARAMETER; - } - - rpc_data = data_blob_const(rpc_out->data - + DCERPC_RESPONSE_LENGTH, - rpc_out->length - - DCERPC_RESPONSE_LENGTH - - DCERPC_AUTH_TRAILER_LENGTH); - - switch (auth_level) { - case DCERPC_AUTH_LEVEL_PRIVACY: - /* Data portion is encrypted. */ - status = spnego_seal(rpc_out->data, spnego_ctx, - &rpc_data, rpc_out, &auth_blob); - break; - - if (!NT_STATUS_IS_OK(status)) { - return status; - } - break; - - case DCERPC_AUTH_LEVEL_INTEGRITY: - /* Data is signed. */ - status = spnego_sign(rpc_out->data, spnego_ctx, - &rpc_data, rpc_out, &auth_blob); - break; - - if (!NT_STATUS_IS_OK(status)) { - return status; - } - break; - - default: - /* Can't happen. */ - smb_panic("bad auth level"); - /* Notreached. */ - return NT_STATUS_INVALID_PARAMETER; - } - - /* Finally attach the blob. */ - if (!data_blob_append(NULL, rpc_out, - auth_blob.data, auth_blob.length)) { - DEBUG(0, ("Failed to add %u bytes auth blob.\n", - (unsigned int)auth_blob.length)); - return NT_STATUS_NO_MEMORY; - } - data_blob_free(&auth_blob); - - return NT_STATUS_OK; -} - -static NTSTATUS get_spnego_auth_footer(TALLOC_CTX *mem_ctx, - struct spnego_context *sp_ctx, - enum dcerpc_AuthLevel auth_level, - DATA_BLOB *data, DATA_BLOB *full_pkt, - DATA_BLOB *auth_token) -{ - switch (auth_level) { - case DCERPC_AUTH_LEVEL_PRIVACY: - /* Data portion is encrypted. */ - return spnego_unseal(mem_ctx, sp_ctx, - data, full_pkt, auth_token); - - case DCERPC_AUTH_LEVEL_INTEGRITY: - /* Data is signed. */ - return spnego_sigcheck(mem_ctx, sp_ctx, - data, full_pkt, auth_token); - - default: - return NT_STATUS_INVALID_PARAMETER; - } -} - /** * @brief Append an auth footer according to what is the current mechanism * @@ -750,9 +544,7 @@ NTSTATUS dcerpc_add_auth_footer(struct pipe_auth_data *auth, size_t pad_len, DATA_BLOB *rpc_out) { struct schannel_state *schannel_auth; - struct auth_ntlmssp_state *ntlmssp_ctx; - struct spnego_context *spnego_ctx; - struct gse_context *gse_ctx; + struct gensec_security *gensec_security; char pad[CLIENT_NDR_PADDING_SIZE] = { 0, }; DATA_BLOB auth_info; DATA_BLOB auth_blob; @@ -801,15 +593,11 @@ NTSTATUS dcerpc_add_auth_footer(struct pipe_auth_data *auth, status = NT_STATUS_OK; break; case DCERPC_AUTH_TYPE_SPNEGO: - spnego_ctx = talloc_get_type_abort(auth->auth_ctx, - struct spnego_context); - status = add_spnego_auth_footer(spnego_ctx, - auth->auth_level, rpc_out); - break; + case DCERPC_AUTH_TYPE_KRB5: case DCERPC_AUTH_TYPE_NTLMSSP: - ntlmssp_ctx = talloc_get_type_abort(auth->auth_ctx, - struct auth_ntlmssp_state); - status = add_ntlmssp_auth_footer(ntlmssp_ctx, + gensec_security = talloc_get_type_abort(auth->auth_ctx, + struct gensec_security); + status = add_generic_auth_footer(gensec_security, auth->auth_level, rpc_out); break; @@ -820,13 +608,6 @@ NTSTATUS dcerpc_add_auth_footer(struct pipe_auth_data *auth, auth->auth_level, rpc_out); break; - case DCERPC_AUTH_TYPE_KRB5: - gse_ctx = talloc_get_type_abort(auth->auth_ctx, - struct gse_context); - status = add_gssapi_auth_footer(gse_ctx, - auth->auth_level, - rpc_out); - break; default: status = NT_STATUS_INVALID_PARAMETER; break; @@ -855,9 +636,7 @@ NTSTATUS dcerpc_check_auth(struct pipe_auth_data *auth, size_t *pad_len) { struct schannel_state *schannel_auth; - struct auth_ntlmssp_state *ntlmssp_ctx; - struct spnego_context *spnego_ctx; - struct gse_context *gse_ctx; + struct gensec_security *gensec_security; NTSTATUS status; struct dcerpc_auth auth_info; uint32_t auth_length; @@ -924,24 +703,14 @@ NTSTATUS dcerpc_check_auth(struct pipe_auth_data *auth, return NT_STATUS_OK; case DCERPC_AUTH_TYPE_SPNEGO: - spnego_ctx = talloc_get_type_abort(auth->auth_ctx, - struct spnego_context); - status = get_spnego_auth_footer(pkt, spnego_ctx, - auth->auth_level, - &data, &full_pkt, - &auth_info.credentials); - if (!NT_STATUS_IS_OK(status)) { - return status; - } - break; - + case DCERPC_AUTH_TYPE_KRB5: case DCERPC_AUTH_TYPE_NTLMSSP: - DEBUG(10, ("NTLMSSP auth\n")); + DEBUG(10, ("GENSEC auth\n")); - ntlmssp_ctx = talloc_get_type_abort(auth->auth_ctx, - struct auth_ntlmssp_state); - status = get_ntlmssp_auth_footer(ntlmssp_ctx, + gensec_security = talloc_get_type_abort(auth->auth_ctx, + struct gensec_security); + status = get_generic_auth_footer(gensec_security, auth->auth_level, &data, &full_pkt, &auth_info.credentials); @@ -965,21 +734,6 @@ NTSTATUS dcerpc_check_auth(struct pipe_auth_data *auth, } break; - case DCERPC_AUTH_TYPE_KRB5: - - DEBUG(10, ("KRB5 auth\n")); - - gse_ctx = talloc_get_type_abort(auth->auth_ctx, - struct gse_context); - status = get_gssapi_auth_footer(pkt, gse_ctx, - auth->auth_level, - &data, &full_pkt, - &auth_info.credentials); - if (!NT_STATUS_IS_OK(status)) { - return status; - } - break; - default: DEBUG(0, ("process_request_pdu: " "unknown auth type %u set.\n", |