2 * DCERPC Helper routines
3 * Günther Deschner <gd@samba.org> 2010.
4 * Simo Sorce <idra@samba.org> 2010.
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 3 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, see <http://www.gnu.org/licenses/>.
22 #include "librpc/rpc/dcerpc.h"
23 #include "librpc/gen_ndr/ndr_dcerpc.h"
24 #include "librpc/gen_ndr/ndr_schannel.h"
27 #define DBGC_CLASS DBGC_RPC_PARSE
30 * @brief NDR Encodes a ncacn_packet
32 * @param mem_ctx The memory context the blob will be allocated on
33 * @param ptype The DCERPC packet type
34 * @param pfc_flags The DCERPC PFC Falgs
35 * @param auth_length The length of the trailing auth blob
36 * @param call_id The call ID
37 * @param u The payload of the packet
38 * @param blob [out] The encoded blob if successful
40 * @return an NTSTATUS error code
42 NTSTATUS dcerpc_push_ncacn_packet(TALLOC_CTX *mem_ctx,
43 enum dcerpc_pkt_type ptype,
47 union dcerpc_payload *u,
50 struct ncacn_packet r;
51 enum ndr_err_code ndr_err;
56 r.pfc_flags = pfc_flags;
57 r.drep[0] = DCERPC_DREP_LE;
61 r.auth_length = auth_length;
65 ndr_err = ndr_push_struct_blob(blob, mem_ctx, &r,
66 (ndr_push_flags_fn_t)ndr_push_ncacn_packet);
67 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
68 return ndr_map_error2ntstatus(ndr_err);
71 dcerpc_set_frag_length(blob, blob->length);
74 if (DEBUGLEVEL >= 10) {
75 /* set frag len for print function */
76 r.frag_length = blob->length;
77 NDR_PRINT_DEBUG(ncacn_packet, &r);
84 * @brief Decodes a ncacn_packet
86 * @param mem_ctx The memory context on which to allocate the packet
88 * @param blob The blob of data to decode
89 * @param r An empty ncacn_packet, must not be NULL
91 * @return a NTSTATUS error code
93 NTSTATUS dcerpc_pull_ncacn_packet(TALLOC_CTX *mem_ctx,
94 const DATA_BLOB *blob,
95 struct ncacn_packet *r,
98 enum ndr_err_code ndr_err;
101 ndr = ndr_pull_init_blob(blob, mem_ctx);
103 return NT_STATUS_NO_MEMORY;
106 ndr->flags |= LIBNDR_FLAG_BIGENDIAN;
109 ndr_err = ndr_pull_ncacn_packet(ndr, NDR_SCALARS|NDR_BUFFERS, r);
111 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
113 return ndr_map_error2ntstatus(ndr_err);
117 if (DEBUGLEVEL >= 10) {
118 NDR_PRINT_DEBUG(ncacn_packet, r);
125 * @brief NDR Encodes a NL_AUTH_MESSAGE
127 * @param mem_ctx The memory context the blob will be allocated on
128 * @param r The NL_AUTH_MESSAGE to encode
129 * @param blob [out] The encoded blob if successful
131 * @return a NTSTATUS error code
133 NTSTATUS dcerpc_push_schannel_bind(TALLOC_CTX *mem_ctx,
134 struct NL_AUTH_MESSAGE *r,
137 enum ndr_err_code ndr_err;
139 ndr_err = ndr_push_struct_blob(blob, mem_ctx, r,
140 (ndr_push_flags_fn_t)ndr_push_NL_AUTH_MESSAGE);
141 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
142 return ndr_map_error2ntstatus(ndr_err);
145 if (DEBUGLEVEL >= 10) {
146 NDR_PRINT_DEBUG(NL_AUTH_MESSAGE, r);
153 * @brief NDR Encodes a dcerpc_auth structure
155 * @param mem_ctx The memory context the blob will be allocated on
156 * @param auth_type The DCERPC Authentication Type
157 * @param auth_level The DCERPC Authentication Level
158 * @param auth_pad_length The padding added to the packet this blob will be
160 * @param auth_context_id The context id
161 * @param credentials The authentication credentials blob (signature)
162 * @param blob [out] The encoded blob if successful
164 * @return a NTSTATUS error code
166 NTSTATUS dcerpc_push_dcerpc_auth(TALLOC_CTX *mem_ctx,
167 enum dcerpc_AuthType auth_type,
168 enum dcerpc_AuthLevel auth_level,
169 uint8_t auth_pad_length,
170 uint32_t auth_context_id,
171 const DATA_BLOB *credentials,
174 struct dcerpc_auth r;
175 enum ndr_err_code ndr_err;
177 r.auth_type = auth_type;
178 r.auth_level = auth_level;
179 r.auth_pad_length = auth_pad_length;
181 r.auth_context_id = auth_context_id;
182 r.credentials = *credentials;
184 ndr_err = ndr_push_struct_blob(blob, mem_ctx, &r,
185 (ndr_push_flags_fn_t)ndr_push_dcerpc_auth);
186 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
187 return ndr_map_error2ntstatus(ndr_err);
190 if (DEBUGLEVEL >= 10) {
191 NDR_PRINT_DEBUG(dcerpc_auth, &r);
198 * @brief Decodes a dcerpc_auth blob
200 * @param mem_ctx The memory context on which to allocate the packet
202 * @param blob The blob of data to decode
203 * @param r An empty dcerpc_auth structure, must not be NULL
205 * @return a NTSTATUS error code
207 NTSTATUS dcerpc_pull_dcerpc_auth(TALLOC_CTX *mem_ctx,
208 const DATA_BLOB *blob,
209 struct dcerpc_auth *r,
212 enum ndr_err_code ndr_err;
213 struct ndr_pull *ndr;
215 ndr = ndr_pull_init_blob(blob, mem_ctx);
217 return NT_STATUS_NO_MEMORY;
220 ndr->flags |= LIBNDR_FLAG_BIGENDIAN;
223 ndr_err = ndr_pull_dcerpc_auth(ndr, NDR_SCALARS|NDR_BUFFERS, r);
225 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
227 return ndr_map_error2ntstatus(ndr_err);
231 if (DEBUGLEVEL >= 10) {
232 NDR_PRINT_DEBUG(dcerpc_auth, r);