s3:dcerpc_helpers: remove unused DEBUG message of schannel_state->seq_num.
[Samba.git] / source3 / librpc / rpc / dcerpc_helpers.c
blob06b0f68064cd95c896f83934c6f4079a710faf4e
1 /*
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/>.
21 #include "includes.h"
22 #include "librpc/rpc/dcerpc.h"
23 #include "librpc/gen_ndr/ndr_dcerpc.h"
24 #include "librpc/gen_ndr/ndr_schannel.h"
25 #include "../libcli/auth/schannel.h"
26 #include "../libcli/auth/spnego.h"
27 #include "librpc/crypto/gse.h"
28 #include "auth/gensec/gensec.h"
30 #undef DBGC_CLASS
31 #define DBGC_CLASS DBGC_RPC_PARSE
33 /**
34 * @brief NDR Encodes a ncacn_packet
36 * @param mem_ctx The memory context the blob will be allocated on
37 * @param ptype The DCERPC packet type
38 * @param pfc_flags The DCERPC PFC Falgs
39 * @param auth_length The length of the trailing auth blob
40 * @param call_id The call ID
41 * @param u The payload of the packet
42 * @param blob [out] The encoded blob if successful
44 * @return an NTSTATUS error code
46 NTSTATUS dcerpc_push_ncacn_packet(TALLOC_CTX *mem_ctx,
47 enum dcerpc_pkt_type ptype,
48 uint8_t pfc_flags,
49 uint16_t auth_length,
50 uint32_t call_id,
51 union dcerpc_payload *u,
52 DATA_BLOB *blob)
54 struct ncacn_packet r;
55 enum ndr_err_code ndr_err;
57 r.rpc_vers = 5;
58 r.rpc_vers_minor = 0;
59 r.ptype = ptype;
60 r.pfc_flags = pfc_flags;
61 r.drep[0] = DCERPC_DREP_LE;
62 r.drep[1] = 0;
63 r.drep[2] = 0;
64 r.drep[3] = 0;
65 r.auth_length = auth_length;
66 r.call_id = call_id;
67 r.u = *u;
69 ndr_err = ndr_push_struct_blob(blob, mem_ctx, &r,
70 (ndr_push_flags_fn_t)ndr_push_ncacn_packet);
71 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
72 return ndr_map_error2ntstatus(ndr_err);
75 dcerpc_set_frag_length(blob, blob->length);
78 if (DEBUGLEVEL >= 10) {
79 /* set frag len for print function */
80 r.frag_length = blob->length;
81 NDR_PRINT_DEBUG(ncacn_packet, &r);
84 return NT_STATUS_OK;
87 /**
88 * @brief Decodes a ncacn_packet
90 * @param mem_ctx The memory context on which to allocate the packet
91 * elements
92 * @param blob The blob of data to decode
93 * @param r An empty ncacn_packet, must not be NULL
94 * @param bigendian Whether the packet is bignedian encoded
96 * @return a NTSTATUS error code
98 NTSTATUS dcerpc_pull_ncacn_packet(TALLOC_CTX *mem_ctx,
99 const DATA_BLOB *blob,
100 struct ncacn_packet *r,
101 bool bigendian)
103 enum ndr_err_code ndr_err;
104 struct ndr_pull *ndr;
106 ndr = ndr_pull_init_blob(blob, mem_ctx);
107 if (!ndr) {
108 return NT_STATUS_NO_MEMORY;
110 if (bigendian) {
111 ndr->flags |= LIBNDR_FLAG_BIGENDIAN;
114 if (CVAL(blob->data, DCERPC_PFC_OFFSET) & DCERPC_PFC_FLAG_OBJECT_UUID) {
115 ndr->flags |= LIBNDR_FLAG_OBJECT_PRESENT;
118 ndr_err = ndr_pull_ncacn_packet(ndr, NDR_SCALARS|NDR_BUFFERS, r);
120 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
121 talloc_free(ndr);
122 return ndr_map_error2ntstatus(ndr_err);
124 talloc_free(ndr);
126 if (DEBUGLEVEL >= 10) {
127 NDR_PRINT_DEBUG(ncacn_packet, r);
130 return NT_STATUS_OK;
134 * @brief NDR Encodes a NL_AUTH_MESSAGE
136 * @param mem_ctx The memory context the blob will be allocated on
137 * @param r The NL_AUTH_MESSAGE to encode
138 * @param blob [out] The encoded blob if successful
140 * @return a NTSTATUS error code
142 NTSTATUS dcerpc_push_schannel_bind(TALLOC_CTX *mem_ctx,
143 struct NL_AUTH_MESSAGE *r,
144 DATA_BLOB *blob)
146 enum ndr_err_code ndr_err;
148 ndr_err = ndr_push_struct_blob(blob, mem_ctx, r,
149 (ndr_push_flags_fn_t)ndr_push_NL_AUTH_MESSAGE);
150 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
151 return ndr_map_error2ntstatus(ndr_err);
154 if (DEBUGLEVEL >= 10) {
155 NDR_PRINT_DEBUG(NL_AUTH_MESSAGE, r);
158 return NT_STATUS_OK;
162 * @brief NDR Encodes a dcerpc_auth structure
164 * @param mem_ctx The memory context the blob will be allocated on
165 * @param auth_type The DCERPC Authentication Type
166 * @param auth_level The DCERPC Authentication Level
167 * @param auth_pad_length The padding added to the packet this blob will be
168 * appended to.
169 * @param auth_context_id The context id
170 * @param credentials The authentication credentials blob (signature)
171 * @param blob [out] The encoded blob if successful
173 * @return a NTSTATUS error code
175 NTSTATUS dcerpc_push_dcerpc_auth(TALLOC_CTX *mem_ctx,
176 enum dcerpc_AuthType auth_type,
177 enum dcerpc_AuthLevel auth_level,
178 uint8_t auth_pad_length,
179 uint32_t auth_context_id,
180 const DATA_BLOB *credentials,
181 DATA_BLOB *blob)
183 struct dcerpc_auth r;
184 enum ndr_err_code ndr_err;
186 r.auth_type = auth_type;
187 r.auth_level = auth_level;
188 r.auth_pad_length = auth_pad_length;
189 r.auth_reserved = 0;
190 r.auth_context_id = auth_context_id;
191 r.credentials = *credentials;
193 ndr_err = ndr_push_struct_blob(blob, mem_ctx, &r,
194 (ndr_push_flags_fn_t)ndr_push_dcerpc_auth);
195 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
196 return ndr_map_error2ntstatus(ndr_err);
199 if (DEBUGLEVEL >= 10) {
200 NDR_PRINT_DEBUG(dcerpc_auth, &r);
203 return NT_STATUS_OK;
207 * @brief Decodes a dcerpc_auth blob
209 * @param mem_ctx The memory context on which to allocate the packet
210 * elements
211 * @param blob The blob of data to decode
212 * @param r An empty dcerpc_auth structure, must not be NULL
214 * @return a NTSTATUS error code
216 NTSTATUS dcerpc_pull_dcerpc_auth(TALLOC_CTX *mem_ctx,
217 const DATA_BLOB *blob,
218 struct dcerpc_auth *r,
219 bool bigendian)
221 enum ndr_err_code ndr_err;
222 struct ndr_pull *ndr;
224 ndr = ndr_pull_init_blob(blob, mem_ctx);
225 if (!ndr) {
226 return NT_STATUS_NO_MEMORY;
228 if (bigendian) {
229 ndr->flags |= LIBNDR_FLAG_BIGENDIAN;
232 ndr_err = ndr_pull_dcerpc_auth(ndr, NDR_SCALARS|NDR_BUFFERS, r);
234 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
235 talloc_free(ndr);
236 return ndr_map_error2ntstatus(ndr_err);
238 talloc_free(ndr);
240 if (DEBUGLEVEL >= 10) {
241 NDR_PRINT_DEBUG(dcerpc_auth, r);
244 return NT_STATUS_OK;
248 * @brief Calculate how much data we can in a packet, including calculating
249 * auth token and pad lengths.
251 * @param auth The pipe_auth_data structure for this pipe.
252 * @param header_len The length of the packet header
253 * @param data_left The data left in the send buffer
254 * @param max_xmit_frag The max fragment size.
255 * @param pad_alignment The NDR padding size.
256 * @param data_to_send [out] The max data we will send in the pdu
257 * @param frag_len [out] The total length of the fragment
258 * @param auth_len [out] The length of the auth trailer
259 * @param pad_len [out] The padding to be applied
261 * @return A NT Error status code.
263 NTSTATUS dcerpc_guess_sizes(struct pipe_auth_data *auth,
264 size_t header_len, size_t data_left,
265 size_t max_xmit_frag, size_t pad_alignment,
266 size_t *data_to_send, size_t *frag_len,
267 size_t *auth_len, size_t *pad_len)
269 size_t max_len;
270 size_t mod_len;
271 struct gensec_security *gensec_security;
272 struct schannel_state *schannel_auth;
274 /* no auth token cases first */
275 switch (auth->auth_level) {
276 case DCERPC_AUTH_LEVEL_NONE:
277 case DCERPC_AUTH_LEVEL_CONNECT:
278 case DCERPC_AUTH_LEVEL_PACKET:
279 max_len = max_xmit_frag - header_len;
280 *data_to_send = MIN(max_len, data_left);
281 *pad_len = 0;
282 *auth_len = 0;
283 *frag_len = header_len + *data_to_send;
284 return NT_STATUS_OK;
286 case DCERPC_AUTH_LEVEL_PRIVACY:
287 break;
289 case DCERPC_AUTH_LEVEL_INTEGRITY:
290 break;
292 default:
293 return NT_STATUS_INVALID_PARAMETER;
297 /* Sign/seal case, calculate auth and pad lengths */
299 max_len = max_xmit_frag - header_len - DCERPC_AUTH_TRAILER_LENGTH;
301 /* Treat the same for all authenticated rpc requests. */
302 switch (auth->auth_type) {
303 case DCERPC_AUTH_TYPE_SPNEGO:
304 case DCERPC_AUTH_TYPE_NTLMSSP:
305 case DCERPC_AUTH_TYPE_KRB5:
306 gensec_security = talloc_get_type_abort(auth->auth_ctx,
307 struct gensec_security);
308 *auth_len = gensec_sig_size(gensec_security, max_len);
309 break;
311 case DCERPC_AUTH_TYPE_SCHANNEL:
312 schannel_auth = talloc_get_type_abort(auth->auth_ctx,
313 struct schannel_state);
314 *auth_len = netsec_outgoing_sig_size(schannel_auth);
315 break;
316 default:
317 return NT_STATUS_INVALID_PARAMETER;
320 max_len -= *auth_len;
322 *data_to_send = MIN(max_len, data_left);
324 mod_len = (header_len + *data_to_send) % pad_alignment;
325 if (mod_len) {
326 *pad_len = pad_alignment - mod_len;
327 } else {
328 *pad_len = 0;
331 if (*data_to_send + *pad_len > max_len) {
332 *data_to_send -= pad_alignment;
335 *frag_len = header_len + *data_to_send + *pad_len
336 + DCERPC_AUTH_TRAILER_LENGTH + *auth_len;
338 return NT_STATUS_OK;
341 /*******************************************************************
342 Create and add the NTLMSSP sign/seal auth data.
343 ********************************************************************/
345 static NTSTATUS add_generic_auth_footer(struct gensec_security *gensec_security,
346 enum dcerpc_AuthLevel auth_level,
347 DATA_BLOB *rpc_out)
349 uint16_t data_and_pad_len = rpc_out->length
350 - DCERPC_RESPONSE_LENGTH
351 - DCERPC_AUTH_TRAILER_LENGTH;
352 DATA_BLOB auth_blob;
353 NTSTATUS status;
355 if (!gensec_security) {
356 return NT_STATUS_INVALID_PARAMETER;
359 switch (auth_level) {
360 case DCERPC_AUTH_LEVEL_PRIVACY:
361 /* Data portion is encrypted. */
362 status = gensec_seal_packet(gensec_security,
363 rpc_out->data,
364 rpc_out->data
365 + DCERPC_RESPONSE_LENGTH,
366 data_and_pad_len,
367 rpc_out->data,
368 rpc_out->length,
369 &auth_blob);
370 if (!NT_STATUS_IS_OK(status)) {
371 return status;
373 break;
375 case DCERPC_AUTH_LEVEL_INTEGRITY:
376 /* Data is signed. */
377 status = gensec_sign_packet(gensec_security,
378 rpc_out->data,
379 rpc_out->data
380 + DCERPC_RESPONSE_LENGTH,
381 data_and_pad_len,
382 rpc_out->data,
383 rpc_out->length,
384 &auth_blob);
385 if (!NT_STATUS_IS_OK(status)) {
386 return status;
388 break;
390 default:
391 /* Can't happen. */
392 smb_panic("bad auth level");
393 /* Notreached. */
394 return NT_STATUS_INVALID_PARAMETER;
397 /* Finally attach the blob. */
398 if (!data_blob_append(NULL, rpc_out,
399 auth_blob.data, auth_blob.length)) {
400 DEBUG(0, ("Failed to add %u bytes auth blob.\n",
401 (unsigned int)auth_blob.length));
402 return NT_STATUS_NO_MEMORY;
404 data_blob_free(&auth_blob);
406 return NT_STATUS_OK;
409 /*******************************************************************
410 Check/unseal the NTLMSSP auth data. (Unseal in place).
411 ********************************************************************/
413 static NTSTATUS get_generic_auth_footer(struct gensec_security *gensec_security,
414 enum dcerpc_AuthLevel auth_level,
415 DATA_BLOB *data, DATA_BLOB *full_pkt,
416 DATA_BLOB *auth_token)
418 switch (auth_level) {
419 case DCERPC_AUTH_LEVEL_PRIVACY:
420 /* Data portion is encrypted. */
421 return gensec_unseal_packet(gensec_security,
422 data->data,
423 data->length,
424 full_pkt->data,
425 full_pkt->length,
426 auth_token);
428 case DCERPC_AUTH_LEVEL_INTEGRITY:
429 /* Data is signed. */
430 return gensec_check_packet(gensec_security,
431 data->data,
432 data->length,
433 full_pkt->data,
434 full_pkt->length,
435 auth_token);
437 default:
438 return NT_STATUS_INVALID_PARAMETER;
442 /*******************************************************************
443 Create and add the schannel sign/seal auth data.
444 ********************************************************************/
446 static NTSTATUS add_schannel_auth_footer(struct schannel_state *sas,
447 enum dcerpc_AuthLevel auth_level,
448 DATA_BLOB *rpc_out)
450 uint8_t *data_p = rpc_out->data + DCERPC_RESPONSE_LENGTH;
451 size_t data_and_pad_len = rpc_out->length
452 - DCERPC_RESPONSE_LENGTH
453 - DCERPC_AUTH_TRAILER_LENGTH;
454 DATA_BLOB auth_blob;
455 NTSTATUS status;
457 if (!sas) {
458 return NT_STATUS_INVALID_PARAMETER;
461 switch (auth_level) {
462 case DCERPC_AUTH_LEVEL_PRIVACY:
463 status = netsec_outgoing_packet(sas,
464 rpc_out->data,
465 true,
466 data_p,
467 data_and_pad_len,
468 &auth_blob);
469 break;
470 case DCERPC_AUTH_LEVEL_INTEGRITY:
471 status = netsec_outgoing_packet(sas,
472 rpc_out->data,
473 false,
474 data_p,
475 data_and_pad_len,
476 &auth_blob);
477 break;
478 default:
479 status = NT_STATUS_INTERNAL_ERROR;
480 break;
483 if (!NT_STATUS_IS_OK(status)) {
484 DEBUG(1,("add_schannel_auth_footer: failed to process packet: %s\n",
485 nt_errstr(status)));
486 return status;
489 if (DEBUGLEVEL >= 10) {
490 dump_NL_AUTH_SIGNATURE(talloc_tos(), &auth_blob);
493 /* Finally attach the blob. */
494 if (!data_blob_append(NULL, rpc_out,
495 auth_blob.data, auth_blob.length)) {
496 return NT_STATUS_NO_MEMORY;
498 data_blob_free(&auth_blob);
500 return NT_STATUS_OK;
503 /*******************************************************************
504 Check/unseal the Schannel auth data. (Unseal in place).
505 ********************************************************************/
507 static NTSTATUS get_schannel_auth_footer(TALLOC_CTX *mem_ctx,
508 struct schannel_state *auth_state,
509 enum dcerpc_AuthLevel auth_level,
510 DATA_BLOB *data, DATA_BLOB *full_pkt,
511 DATA_BLOB *auth_token)
513 switch (auth_level) {
514 case DCERPC_AUTH_LEVEL_PRIVACY:
515 /* Data portion is encrypted. */
516 return netsec_incoming_packet(auth_state,
517 true,
518 data->data,
519 data->length,
520 auth_token);
522 case DCERPC_AUTH_LEVEL_INTEGRITY:
523 /* Data is signed. */
524 return netsec_incoming_packet(auth_state,
525 false,
526 data->data,
527 data->length,
528 auth_token);
530 default:
531 return NT_STATUS_INVALID_PARAMETER;
536 * @brief Append an auth footer according to what is the current mechanism
538 * @param auth The pipe_auth_data associated with the connection
539 * @param pad_len The padding used in the packet
540 * @param rpc_out Packet blob up to and including the auth header
542 * @return A NTSTATUS error code.
544 NTSTATUS dcerpc_add_auth_footer(struct pipe_auth_data *auth,
545 size_t pad_len, DATA_BLOB *rpc_out)
547 struct schannel_state *schannel_auth;
548 struct gensec_security *gensec_security;
549 char pad[CLIENT_NDR_PADDING_SIZE] = { 0, };
550 DATA_BLOB auth_info;
551 DATA_BLOB auth_blob;
552 NTSTATUS status;
554 if (auth->auth_type == DCERPC_AUTH_TYPE_NONE ||
555 auth->auth_type == DCERPC_AUTH_TYPE_NCALRPC_AS_SYSTEM) {
556 return NT_STATUS_OK;
559 if (pad_len) {
560 /* Copy the sign/seal padding data. */
561 if (!data_blob_append(NULL, rpc_out, pad, pad_len)) {
562 return NT_STATUS_NO_MEMORY;
566 /* marshall the dcerpc_auth with an actually empty auth_blob.
567 * This is needed because the ntmlssp signature includes the
568 * auth header. We will append the actual blob later. */
569 auth_blob = data_blob_null;
570 status = dcerpc_push_dcerpc_auth(rpc_out->data,
571 auth->auth_type,
572 auth->auth_level,
573 pad_len,
574 1 /* context id. */,
575 &auth_blob,
576 &auth_info);
577 if (!NT_STATUS_IS_OK(status)) {
578 return status;
581 /* append the header */
582 if (!data_blob_append(NULL, rpc_out,
583 auth_info.data, auth_info.length)) {
584 DEBUG(0, ("Failed to add %u bytes auth blob.\n",
585 (unsigned int)auth_info.length));
586 return NT_STATUS_NO_MEMORY;
588 data_blob_free(&auth_info);
590 /* Generate any auth sign/seal and add the auth footer. */
591 switch (auth->auth_type) {
592 case DCERPC_AUTH_TYPE_NONE:
593 case DCERPC_AUTH_TYPE_NCALRPC_AS_SYSTEM:
594 status = NT_STATUS_OK;
595 break;
596 case DCERPC_AUTH_TYPE_SPNEGO:
597 case DCERPC_AUTH_TYPE_KRB5:
598 case DCERPC_AUTH_TYPE_NTLMSSP:
599 gensec_security = talloc_get_type_abort(auth->auth_ctx,
600 struct gensec_security);
601 status = add_generic_auth_footer(gensec_security,
602 auth->auth_level,
603 rpc_out);
604 break;
605 case DCERPC_AUTH_TYPE_SCHANNEL:
606 schannel_auth = talloc_get_type_abort(auth->auth_ctx,
607 struct schannel_state);
608 status = add_schannel_auth_footer(schannel_auth,
609 auth->auth_level,
610 rpc_out);
611 break;
612 default:
613 status = NT_STATUS_INVALID_PARAMETER;
614 break;
617 return status;
621 * @brief Check authentication for request/response packets
623 * @param auth The auth data for the connection
624 * @param pkt The actual ncacn_packet
625 * @param pkt_trailer The stub_and_verifier part of the packet
626 * @param header_size The header size
627 * @param raw_pkt The whole raw packet data blob
628 * @param pad_len [out] The padding length used in the packet
630 * @return A NTSTATUS error code
632 NTSTATUS dcerpc_check_auth(struct pipe_auth_data *auth,
633 struct ncacn_packet *pkt,
634 DATA_BLOB *pkt_trailer,
635 size_t header_size,
636 DATA_BLOB *raw_pkt,
637 size_t *pad_len)
639 struct schannel_state *schannel_auth;
640 struct gensec_security *gensec_security;
641 NTSTATUS status;
642 struct dcerpc_auth auth_info;
643 uint32_t auth_length;
644 DATA_BLOB full_pkt;
645 DATA_BLOB data;
647 switch (auth->auth_level) {
648 case DCERPC_AUTH_LEVEL_PRIVACY:
649 DEBUG(10, ("Requested Privacy.\n"));
650 break;
652 case DCERPC_AUTH_LEVEL_INTEGRITY:
653 DEBUG(10, ("Requested Integrity.\n"));
654 break;
656 case DCERPC_AUTH_LEVEL_CONNECT:
657 if (pkt->auth_length != 0) {
658 break;
660 *pad_len = 0;
661 return NT_STATUS_OK;
663 case DCERPC_AUTH_LEVEL_NONE:
664 if (pkt->auth_length != 0) {
665 DEBUG(3, ("Got non-zero auth len on non "
666 "authenticated connection!\n"));
667 return NT_STATUS_INVALID_PARAMETER;
669 *pad_len = 0;
670 return NT_STATUS_OK;
672 default:
673 DEBUG(3, ("Unimplemented Auth Level %d",
674 auth->auth_level));
675 return NT_STATUS_INVALID_PARAMETER;
678 /* Paranioa checks for auth_length. */
679 if (pkt->auth_length > pkt->frag_length) {
680 return NT_STATUS_INFO_LENGTH_MISMATCH;
682 if (((unsigned int)pkt->auth_length
683 + DCERPC_AUTH_TRAILER_LENGTH < (unsigned int)pkt->auth_length) ||
684 ((unsigned int)pkt->auth_length
685 + DCERPC_AUTH_TRAILER_LENGTH < DCERPC_AUTH_TRAILER_LENGTH)) {
686 /* Integer wrap attempt. */
687 return NT_STATUS_INFO_LENGTH_MISMATCH;
690 status = dcerpc_pull_auth_trailer(pkt, pkt, pkt_trailer,
691 &auth_info, &auth_length, false);
692 if (!NT_STATUS_IS_OK(status)) {
693 return status;
696 data = data_blob_const(raw_pkt->data + header_size,
697 pkt_trailer->length - auth_length);
698 full_pkt = data_blob_const(raw_pkt->data,
699 raw_pkt->length - auth_info.credentials.length);
701 switch (auth->auth_type) {
702 case DCERPC_AUTH_TYPE_NONE:
703 case DCERPC_AUTH_TYPE_NCALRPC_AS_SYSTEM:
704 return NT_STATUS_OK;
706 case DCERPC_AUTH_TYPE_SPNEGO:
707 case DCERPC_AUTH_TYPE_KRB5:
708 case DCERPC_AUTH_TYPE_NTLMSSP:
710 DEBUG(10, ("GENSEC auth\n"));
712 gensec_security = talloc_get_type_abort(auth->auth_ctx,
713 struct gensec_security);
714 status = get_generic_auth_footer(gensec_security,
715 auth->auth_level,
716 &data, &full_pkt,
717 &auth_info.credentials);
718 if (!NT_STATUS_IS_OK(status)) {
719 return status;
721 break;
723 case DCERPC_AUTH_TYPE_SCHANNEL:
725 DEBUG(10, ("SCHANNEL auth\n"));
727 schannel_auth = talloc_get_type_abort(auth->auth_ctx,
728 struct schannel_state);
729 status = get_schannel_auth_footer(pkt, schannel_auth,
730 auth->auth_level,
731 &data, &full_pkt,
732 &auth_info.credentials);
733 if (!NT_STATUS_IS_OK(status)) {
734 return status;
736 break;
738 default:
739 DEBUG(0, ("process_request_pdu: "
740 "unknown auth type %u set.\n",
741 (unsigned int)auth->auth_type));
742 return NT_STATUS_INVALID_PARAMETER;
745 /* TODO: remove later
746 * this is still needed because in the server code the
747 * pkt_trailer actually has a copy of the raw data, and they
748 * are still both used in later calls */
749 if (auth->auth_level == DCERPC_AUTH_LEVEL_PRIVACY) {
750 memcpy(pkt_trailer->data, data.data, data.length);
753 *pad_len = auth_info.auth_pad_length;
754 data_blob_free(&auth_info.credentials);
755 return NT_STATUS_OK;