librpc/rpc: move dcerpc_pull_ncacn_packet() from source3/librpc/rpc/ to the toplevel
[kamenim/samba-autobuild/.git] / source3 / librpc / rpc / dcerpc_helpers.c
index 96074a4705c9b13ca7cbb76b193fb3ec955c2ede..88d27d0fafdc81618edb233a2d8c75c48b796ae3 100644 (file)
@@ -81,56 +81,6 @@ NTSTATUS dcerpc_push_ncacn_packet(TALLOC_CTX *mem_ctx,
        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
 *
@@ -176,47 +126,6 @@ NTSTATUS dcerpc_push_dcerpc_auth(TALLOC_CTX *mem_ctx,
        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.
@@ -444,7 +353,7 @@ NTSTATUS dcerpc_add_auth_footer(struct pipe_auth_data *auth,
                                         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)) {
@@ -481,19 +390,18 @@ NTSTATUS dcerpc_add_auth_footer(struct pipe_auth_data *auth,
 *
 * @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;
@@ -502,6 +410,14 @@ NTSTATUS dcerpc_check_auth(struct pipe_auth_data *auth,
        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"));
@@ -515,7 +431,6 @@ NTSTATUS dcerpc_check_auth(struct pipe_auth_data *auth,
                if (pkt->auth_length != 0) {
                        break;
                }
-               *pad_len = 0;
                return NT_STATUS_OK;
 
        case DCERPC_AUTH_LEVEL_NONE:
@@ -524,7 +439,6 @@ NTSTATUS dcerpc_check_auth(struct pipe_auth_data *auth,
                                  "authenticated connection!\n"));
                        return NT_STATUS_INVALID_PARAMETER;
                }
-               *pad_len = 0;
                return NT_STATUS_OK;
 
        default:
@@ -543,10 +457,23 @@ NTSTATUS dcerpc_check_auth(struct pipe_auth_data *auth,
                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:
@@ -571,10 +498,13 @@ NTSTATUS dcerpc_check_auth(struct pipe_auth_data *auth,
         * 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;
 }