return NT_STATUS_OK;
}
-/**
-* @brief Decodes a ncacn_packet
-*
-* @param mem_ctx The memory context on which to allocate the packet
-* elements
-* @param blob The blob of data to decode
-* @param r An empty ncacn_packet, must not be NULL
-* @param bigendian Whether the packet is bignedian encoded
-*
-* @return a NTSTATUS error code
-*/
-NTSTATUS dcerpc_pull_ncacn_packet(TALLOC_CTX *mem_ctx,
- const DATA_BLOB *blob,
- struct ncacn_packet *r,
- bool bigendian)
-{
- enum ndr_err_code ndr_err;
- struct ndr_pull *ndr;
-
- ndr = ndr_pull_init_blob(blob, mem_ctx);
- if (!ndr) {
- return NT_STATUS_NO_MEMORY;
- }
- if (bigendian) {
- 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)) {
- talloc_free(ndr);
- return ndr_map_error2ntstatus(ndr_err);
- }
- talloc_free(ndr);
-
- if (DEBUGLEVEL >= 10) {
- NDR_PRINT_DEBUG(ncacn_packet, r);
- }
-
- if (r->frag_length != blob->length) {
- return NT_STATUS_RPC_PROTOCOL_ERROR;
- }
-
- return NT_STATUS_OK;
-}
-
/**
* @brief NDR Encodes a dcerpc_auth structure
*
return NT_STATUS_OK;
}
-/**
-* @brief Decodes a dcerpc_auth blob
-*
-* @param mem_ctx The memory context on which to allocate the packet
-* elements
-* @param blob The blob of data to decode
-* @param r An empty dcerpc_auth structure, must not be NULL
-*
-* @return a NTSTATUS error code
-*/
-NTSTATUS dcerpc_pull_dcerpc_auth(TALLOC_CTX *mem_ctx,
- const DATA_BLOB *blob,
- struct dcerpc_auth *r,
- bool bigendian)
-{
- enum ndr_err_code ndr_err;
- struct ndr_pull *ndr;
-
- ndr = ndr_pull_init_blob(blob, mem_ctx);
- if (!ndr) {
- return NT_STATUS_NO_MEMORY;
- }
- if (bigendian) {
- ndr->flags |= LIBNDR_FLAG_BIGENDIAN;
- }
-
- ndr_err = ndr_pull_dcerpc_auth(ndr, NDR_SCALARS|NDR_BUFFERS, r);
-
- if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
- talloc_free(ndr);
- return ndr_map_error2ntstatus(ndr_err);
- }
- talloc_free(ndr);
-
- if (DEBUGLEVEL >= 10) {
- NDR_PRINT_DEBUG(dcerpc_auth, r);
- }
-
- return NT_STATUS_OK;
-}
-
/**
* @brief Calculate how much data we can in a packet, including calculating
* auth token and pad lengths.
auth->auth_type,
auth->auth_level,
pad_len,
- 1 /* context id. */,
+ auth->auth_context_id,
&auth_blob,
&auth_info);
if (!NT_STATUS_IS_OK(status)) {
*
* @param auth The auth data for the connection
* @param pkt The actual ncacn_packet
-* @param pkt_trailer The stub_and_verifier part of the packet
+* @param pkt_trailer [in][out] The stub_and_verifier part of the packet,
+* the auth_trailer and padding will be removed.
* @param header_size The header size
* @param raw_pkt The whole raw packet data blob
-* @param pad_len [out] The padding length used in the packet
*
* @return A NTSTATUS error code
*/
NTSTATUS dcerpc_check_auth(struct pipe_auth_data *auth,
struct ncacn_packet *pkt,
DATA_BLOB *pkt_trailer,
- size_t header_size,
- DATA_BLOB *raw_pkt,
- size_t *pad_len)
+ uint8_t header_size,
+ DATA_BLOB *raw_pkt)
{
struct gensec_security *gensec_security;
NTSTATUS status;
DATA_BLOB full_pkt;
DATA_BLOB data;
+ /*
+ * These check should be done in the caller.
+ */
+ SMB_ASSERT(raw_pkt->length == pkt->frag_length);
+ SMB_ASSERT(header_size <= pkt->frag_length);
+ SMB_ASSERT(pkt_trailer->length < pkt->frag_length);
+ SMB_ASSERT((pkt_trailer->length + header_size) <= pkt->frag_length);
+
switch (auth->auth_level) {
case DCERPC_AUTH_LEVEL_PRIVACY:
DEBUG(10, ("Requested Privacy.\n"));
if (pkt->auth_length != 0) {
break;
}
- *pad_len = 0;
return NT_STATUS_OK;
case DCERPC_AUTH_LEVEL_NONE:
"authenticated connection!\n"));
return NT_STATUS_INVALID_PARAMETER;
}
- *pad_len = 0;
return NT_STATUS_OK;
default:
return status;
}
+ if (auth_info.auth_type != auth->auth_type) {
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+
+ if (auth_info.auth_level != auth->auth_level) {
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+
+ if (auth_info.auth_context_id != auth->auth_context_id) {
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+
+ pkt_trailer->length -= auth_length;
data = data_blob_const(raw_pkt->data + header_size,
- pkt_trailer->length - auth_length);
- full_pkt = data_blob_const(raw_pkt->data,
- raw_pkt->length - auth_info.credentials.length);
+ pkt_trailer->length);
+ full_pkt = data_blob_const(raw_pkt->data, raw_pkt->length);
+ full_pkt.length -= auth_info.credentials.length;
switch (auth->auth_type) {
case DCERPC_AUTH_TYPE_NONE:
* pkt_trailer actually has a copy of the raw data, and they
* are still both used in later calls */
if (auth->auth_level == DCERPC_AUTH_LEVEL_PRIVACY) {
+ if (pkt_trailer->length != data.length) {
+ return NT_STATUS_INVALID_PARAMETER;
+ }
memcpy(pkt_trailer->data, data.data, data.length);
}
- *pad_len = auth_info.auth_pad_length;
+ pkt_trailer->length -= auth_info.auth_pad_length;
data_blob_free(&auth_info.credentials);
return NT_STATUS_OK;
}