Make use of ndr_syntax_id_equal
[kamenim/samba.git] / source3 / rpc_parse / parse_rpc.c
1 /* 
2  *  Unix SMB/CIFS implementation.
3  *  RPC Pipe client / server routines
4  *  Copyright (C) Andrew Tridgell              1992-1997,
5  *  Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
6  *  Copyright (C) Paul Ashton                       1997.
7  *  Copyright (C) Jeremy Allison                    1999.
8  *  
9  *  This program is free software; you can redistribute it and/or modify
10  *  it under the terms of the GNU General Public License as published by
11  *  the Free Software Foundation; either version 3 of the License, or
12  *  (at your option) any later version.
13  *  
14  *  This program is distributed in the hope that it will be useful,
15  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
16  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  *  GNU General Public License for more details.
18  *  
19  *  You should have received a copy of the GNU General Public License
20  *  along with this program; if not, see <http://www.gnu.org/licenses/>.
21  */
22
23 #include "includes.h"
24
25 #undef DBGC_CLASS
26 #define DBGC_CLASS DBGC_RPC_PARSE
27
28 /*******************************************************************
29 interface/version dce/rpc pipe identification
30 ********************************************************************/
31
32 const struct ndr_syntax_id syntax_spoolss = {
33         {
34                 0x12345678, 0x1234, 0xabcd,
35                 { 0xef, 0x00 },
36                 { 0x01, 0x23,
37                   0x45, 0x67, 0x89, 0xab }
38         }, 0x01
39 };
40
41 /*
42  * IMPORTANT!!  If you update this structure, make sure to
43  * update the index #defines in smb.h.
44  */
45
46 const struct pipe_id_info pipe_names [] =
47 {
48         { PIPE_LSARPC  , &ndr_table_lsarpc.syntax_id, PIPE_LSASS    , &ndr_transfer_syntax },
49         { PIPE_LSARPC  , &ndr_table_dssetup.syntax_id, PIPE_LSASS    , &ndr_transfer_syntax },
50         { PIPE_SAMR    , &ndr_table_samr.syntax_id, PIPE_LSASS    , &ndr_transfer_syntax },
51         { PIPE_NETLOGON, &ndr_table_netlogon.syntax_id, PIPE_LSASS    , &ndr_transfer_syntax },
52         { PIPE_SRVSVC  , &ndr_table_srvsvc.syntax_id, PIPE_NTSVCS   , &ndr_transfer_syntax },
53         { PIPE_WKSSVC  , &ndr_table_wkssvc.syntax_id, PIPE_NTSVCS   , &ndr_transfer_syntax },
54         { PIPE_WINREG  , &ndr_table_winreg.syntax_id, PIPE_WINREG   , &ndr_transfer_syntax },
55         { PIPE_SPOOLSS , &syntax_spoolss        , PIPE_SPOOLSS  , &ndr_transfer_syntax },
56         { PIPE_NETDFS  , &ndr_table_netdfs.syntax_id, PIPE_NETDFS   , &ndr_transfer_syntax },
57         { PIPE_ECHO    , &ndr_table_rpcecho.syntax_id, PIPE_ECHO     , &ndr_transfer_syntax },
58         { PIPE_SHUTDOWN, &ndr_table_initshutdown.syntax_id, PIPE_SHUTDOWN , &ndr_transfer_syntax },
59         { PIPE_SVCCTL  , &ndr_table_svcctl.syntax_id, PIPE_NTSVCS   , &ndr_transfer_syntax },
60         { PIPE_EVENTLOG, &ndr_table_eventlog.syntax_id, PIPE_EVENTLOG , &ndr_transfer_syntax },
61         { PIPE_NTSVCS  , &ndr_table_ntsvcs.syntax_id, PIPE_NTSVCS   , &ndr_transfer_syntax },
62         { PIPE_EPMAPPER  , &ndr_table_epmapper.syntax_id, PIPE_EPMAPPER   , &ndr_transfer_syntax },
63         { PIPE_DRSUAPI , &ndr_table_drsuapi.syntax_id, PIPE_DRSUAPI   , &ndr_transfer_syntax },
64         { NULL         , NULL                  , NULL          , NULL }
65 };
66
67 /****************************************************************************
68  Return the pipe name from the index.
69  ****************************************************************************/
70
71 const char *cli_get_pipe_name(int pipe_idx)
72 {
73         return &pipe_names[pipe_idx].client_pipe[5];
74 }
75
76 /****************************************************************************
77  Return the pipe idx from the syntax.
78  ****************************************************************************/
79 int cli_get_pipe_idx(const RPC_IFACE *syntax)
80 {
81         int i;
82         for (i = 0; pipe_names[i].client_pipe; i++) {
83                 if (ndr_syntax_id_equal(pipe_names[i].abstr_syntax, syntax)) {
84                         return i;
85                 }
86         }
87
88         return -1;
89 }
90
91 /*******************************************************************
92  Inits an RPC_HDR structure.
93 ********************************************************************/
94
95 void init_rpc_hdr(RPC_HDR *hdr, enum RPC_PKT_TYPE pkt_type, uint8 flags,
96                                 uint32 call_id, int data_len, int auth_len)
97 {
98         hdr->major        = 5;               /* RPC version 5 */
99         hdr->minor        = 0;               /* minor version 0 */
100         hdr->pkt_type     = pkt_type;        /* RPC packet type */
101         hdr->flags        = flags;           /* dce/rpc flags */
102         hdr->pack_type[0] = 0x10;            /* little-endian data representation */
103         hdr->pack_type[1] = 0;               /* packed data representation */
104         hdr->pack_type[2] = 0;               /* packed data representation */
105         hdr->pack_type[3] = 0;               /* packed data representation */
106         hdr->frag_len     = data_len;        /* fragment length, fill in later */
107         hdr->auth_len     = auth_len;        /* authentication length */
108         hdr->call_id      = call_id;         /* call identifier - match incoming RPC */
109 }
110
111 /*******************************************************************
112  Reads or writes an RPC_HDR structure.
113 ********************************************************************/
114
115 bool smb_io_rpc_hdr(const char *desc,  RPC_HDR *rpc, prs_struct *ps, int depth)
116 {
117         if (rpc == NULL)
118                 return False;
119
120         prs_debug(ps, depth, desc, "smb_io_rpc_hdr");
121         depth++;
122
123         if(!prs_uint8 ("major     ", ps, depth, &rpc->major))
124                 return False;
125
126         if(!prs_uint8 ("minor     ", ps, depth, &rpc->minor))
127                 return False;
128         if(!prs_uint8 ("pkt_type  ", ps, depth, &rpc->pkt_type))
129                 return False;
130         if(!prs_uint8 ("flags     ", ps, depth, &rpc->flags))
131                 return False;
132
133         /* We always marshall in little endian format. */
134         if (MARSHALLING(ps))
135                 rpc->pack_type[0] = 0x10;
136
137         if(!prs_uint8("pack_type0", ps, depth, &rpc->pack_type[0]))
138                 return False;
139         if(!prs_uint8("pack_type1", ps, depth, &rpc->pack_type[1]))
140                 return False;
141         if(!prs_uint8("pack_type2", ps, depth, &rpc->pack_type[2]))
142                 return False;
143         if(!prs_uint8("pack_type3", ps, depth, &rpc->pack_type[3]))
144                 return False;
145
146         /*
147          * If reading and pack_type[0] == 0 then the data is in big-endian
148          * format. Set the flag in the prs_struct to specify reverse-endainness.
149          */
150
151         if (UNMARSHALLING(ps) && rpc->pack_type[0] == 0) {
152                 DEBUG(10,("smb_io_rpc_hdr: PDU data format is big-endian. Setting flag.\n"));
153                 prs_set_endian_data(ps, RPC_BIG_ENDIAN);
154         }
155
156         if(!prs_uint16("frag_len  ", ps, depth, &rpc->frag_len))
157                 return False;
158         if(!prs_uint16("auth_len  ", ps, depth, &rpc->auth_len))
159                 return False;
160         if(!prs_uint32("call_id   ", ps, depth, &rpc->call_id))
161                 return False;
162         return True;
163 }
164
165 /*******************************************************************
166  Reads or writes an RPC_IFACE structure.
167 ********************************************************************/
168
169 static bool smb_io_rpc_iface(const char *desc, RPC_IFACE *ifc, prs_struct *ps, int depth)
170 {
171         if (ifc == NULL)
172                 return False;
173
174         prs_debug(ps, depth, desc, "smb_io_rpc_iface");
175         depth++;
176
177         if (!prs_align(ps))
178                 return False;
179
180         if (!smb_io_uuid(  "uuid", &ifc->uuid, ps, depth))
181                 return False;
182
183         if(!prs_uint32 ("version", ps, depth, &ifc->if_version))
184                 return False;
185
186         return True;
187 }
188
189 /*******************************************************************
190  Inits an RPC_ADDR_STR structure.
191 ********************************************************************/
192
193 static void init_rpc_addr_str(RPC_ADDR_STR *str, const char *name)
194 {
195         str->len = strlen(name) + 1;
196         fstrcpy(str->str, name);
197 }
198
199 /*******************************************************************
200  Reads or writes an RPC_ADDR_STR structure.
201 ********************************************************************/
202
203 static bool smb_io_rpc_addr_str(const char *desc,  RPC_ADDR_STR *str, prs_struct *ps, int depth)
204 {
205         if (str == NULL)
206                 return False;
207
208         prs_debug(ps, depth, desc, "smb_io_rpc_addr_str");
209         depth++;
210         if(!prs_align(ps))
211                 return False;
212
213         if(!prs_uint16 (      "len", ps, depth, &str->len))
214                 return False;
215         if(!prs_uint8s (True, "str", ps, depth, (uchar*)str->str, MIN(str->len, sizeof(str->str)) ))
216                 return False;
217         return True;
218 }
219
220 /*******************************************************************
221  Inits an RPC_HDR_BBA structure.
222 ********************************************************************/
223
224 static void init_rpc_hdr_bba(RPC_HDR_BBA *bba, uint16 max_tsize, uint16 max_rsize, uint32 assoc_gid)
225 {
226         bba->max_tsize = max_tsize; /* maximum transmission fragment size (0x1630) */
227         bba->max_rsize = max_rsize; /* max receive fragment size (0x1630) */   
228         bba->assoc_gid = assoc_gid; /* associated group id (0x0) */ 
229 }
230
231 /*******************************************************************
232  Reads or writes an RPC_HDR_BBA structure.
233 ********************************************************************/
234
235 static bool smb_io_rpc_hdr_bba(const char *desc,  RPC_HDR_BBA *rpc, prs_struct *ps, int depth)
236 {
237         if (rpc == NULL)
238                 return False;
239
240         prs_debug(ps, depth, desc, "smb_io_rpc_hdr_bba");
241         depth++;
242
243         if(!prs_uint16("max_tsize", ps, depth, &rpc->max_tsize))
244                 return False;
245         if(!prs_uint16("max_rsize", ps, depth, &rpc->max_rsize))
246                 return False;
247         if(!prs_uint32("assoc_gid", ps, depth, &rpc->assoc_gid))
248                 return False;
249         return True;
250 }
251
252 /*******************************************************************
253  Inits an RPC_CONTEXT structure.
254  Note the transfer pointer must remain valid until this is marshalled.
255 ********************************************************************/
256
257 void init_rpc_context(RPC_CONTEXT *rpc_ctx, uint16 context_id,
258                       const RPC_IFACE *abstract, const RPC_IFACE *transfer)
259 {
260         rpc_ctx->context_id   = context_id   ; /* presentation context identifier (0x0) */
261         rpc_ctx->num_transfer_syntaxes = 1 ; /* the number of syntaxes (has always been 1?)(0x1) */
262
263         /* num and vers. of interface client is using */
264         rpc_ctx->abstract = *abstract;
265
266         /* vers. of interface to use for replies */
267         rpc_ctx->transfer = CONST_DISCARD(RPC_IFACE *, transfer);
268 }
269
270 /*******************************************************************
271  Inits an RPC_HDR_RB structure.
272  Note the context pointer must remain valid until this is marshalled.
273 ********************************************************************/
274
275 void init_rpc_hdr_rb(RPC_HDR_RB *rpc, 
276                                 uint16 max_tsize, uint16 max_rsize, uint32 assoc_gid,
277                                 RPC_CONTEXT *context)
278 {
279         init_rpc_hdr_bba(&rpc->bba, max_tsize, max_rsize, assoc_gid);
280
281         rpc->num_contexts = 1;
282         rpc->rpc_context = context;
283 }
284
285 /*******************************************************************
286  Reads or writes an RPC_CONTEXT structure.
287 ********************************************************************/
288
289 bool smb_io_rpc_context(const char *desc, RPC_CONTEXT *rpc_ctx, prs_struct *ps, int depth)
290 {
291         int i;
292
293         if (rpc_ctx == NULL)
294                 return False;
295
296         if(!prs_align(ps))
297                 return False;
298         if(!prs_uint16("context_id  ", ps, depth, &rpc_ctx->context_id ))
299                 return False;
300         if(!prs_uint8 ("num_transfer_syntaxes", ps, depth, &rpc_ctx->num_transfer_syntaxes))
301                 return False;
302
303         /* num_transfer_syntaxes must not be zero. */
304         if (rpc_ctx->num_transfer_syntaxes == 0)
305                 return False;
306
307         if(!smb_io_rpc_iface("", &rpc_ctx->abstract, ps, depth))
308                 return False;
309
310         if (UNMARSHALLING(ps)) {
311                 if (!(rpc_ctx->transfer = PRS_ALLOC_MEM(ps, RPC_IFACE, rpc_ctx->num_transfer_syntaxes))) {
312                         return False;
313                 }
314         }
315
316         for (i = 0; i < rpc_ctx->num_transfer_syntaxes; i++ ) {
317                 if (!smb_io_rpc_iface("", &rpc_ctx->transfer[i], ps, depth))
318                         return False;
319         }
320         return True;
321
322
323 /*******************************************************************
324  Reads or writes an RPC_HDR_RB structure.
325 ********************************************************************/
326
327 bool smb_io_rpc_hdr_rb(const char *desc, RPC_HDR_RB *rpc, prs_struct *ps, int depth)
328 {
329         int i;
330         
331         if (rpc == NULL)
332                 return False;
333
334         prs_debug(ps, depth, desc, "smb_io_rpc_hdr_rb");
335         depth++;
336
337         if(!smb_io_rpc_hdr_bba("", &rpc->bba, ps, depth))
338                 return False;
339
340         if(!prs_uint8("num_contexts", ps, depth, &rpc->num_contexts))
341                 return False;
342
343         /* 3 pad bytes following - will be mopped up by the prs_align in smb_io_rpc_context(). */
344
345         /* num_contexts must not be zero. */
346         if (rpc->num_contexts == 0)
347                 return False;
348
349         if (UNMARSHALLING(ps)) {
350                 if (!(rpc->rpc_context = PRS_ALLOC_MEM(ps, RPC_CONTEXT, rpc->num_contexts))) {
351                         return False;
352                 }
353         }
354
355         for (i = 0; i < rpc->num_contexts; i++ ) {
356                 if (!smb_io_rpc_context("", &rpc->rpc_context[i], ps, depth))
357                         return False;
358         }
359
360         return True;
361 }
362
363 /*******************************************************************
364  Inits an RPC_RESULTS structure.
365
366  lkclXXXX only one reason at the moment!
367 ********************************************************************/
368
369 static void init_rpc_results(RPC_RESULTS *res, 
370                                 uint8 num_results, uint16 result, uint16 reason)
371 {
372         res->num_results = num_results; /* the number of results (0x01) */
373         res->result      = result     ;  /* result (0x00 = accept) */
374         res->reason      = reason     ;  /* reason (0x00 = no reason specified) */
375 }
376
377 /*******************************************************************
378  Reads or writes an RPC_RESULTS structure.
379
380  lkclXXXX only one reason at the moment!
381 ********************************************************************/
382
383 static bool smb_io_rpc_results(const char *desc, RPC_RESULTS *res, prs_struct *ps, int depth)
384 {
385         if (res == NULL)
386                 return False;
387
388         prs_debug(ps, depth, desc, "smb_io_rpc_results");
389         depth++;
390
391         if(!prs_align(ps))
392                 return False;
393         
394         if(!prs_uint8 ("num_results", ps, depth, &res->num_results))    
395                 return False;
396
397         if(!prs_align(ps))
398                 return False;
399         
400         if(!prs_uint16("result     ", ps, depth, &res->result))
401                 return False;
402         if(!prs_uint16("reason     ", ps, depth, &res->reason))
403                 return False;
404         return True;
405 }
406
407 /*******************************************************************
408  Init an RPC_HDR_BA structure.
409
410  lkclXXXX only one reason at the moment!
411
412 ********************************************************************/
413
414 void init_rpc_hdr_ba(RPC_HDR_BA *rpc, 
415                                 uint16 max_tsize, uint16 max_rsize, uint32 assoc_gid,
416                                 const char *pipe_addr,
417                                 uint8 num_results, uint16 result, uint16 reason,
418                                 RPC_IFACE *transfer)
419 {
420         init_rpc_hdr_bba (&rpc->bba, max_tsize, max_rsize, assoc_gid);
421         init_rpc_addr_str(&rpc->addr, pipe_addr);
422         init_rpc_results (&rpc->res, num_results, result, reason);
423
424         /* the transfer syntax from the request */
425         memcpy(&rpc->transfer, transfer, sizeof(rpc->transfer));
426 }
427
428 /*******************************************************************
429  Reads or writes an RPC_HDR_BA structure.
430 ********************************************************************/
431
432 bool smb_io_rpc_hdr_ba(const char *desc, RPC_HDR_BA *rpc, prs_struct *ps, int depth)
433 {
434         if (rpc == NULL)
435                 return False;
436
437         prs_debug(ps, depth, desc, "smb_io_rpc_hdr_ba");
438         depth++;
439
440         if(!smb_io_rpc_hdr_bba("", &rpc->bba, ps, depth))
441                 return False;
442         if(!smb_io_rpc_addr_str("", &rpc->addr, ps, depth))
443                 return False;
444         if(!smb_io_rpc_results("", &rpc->res, ps, depth))
445                 return False;
446         if(!smb_io_rpc_iface("", &rpc->transfer, ps, depth))
447                 return False;
448         return True;
449 }
450
451 /*******************************************************************
452  Init an RPC_HDR_REQ structure.
453 ********************************************************************/
454
455 void init_rpc_hdr_req(RPC_HDR_REQ *hdr, uint32 alloc_hint, uint16 opnum)
456 {
457         hdr->alloc_hint   = alloc_hint; /* allocation hint */
458         hdr->context_id   = 0;         /* presentation context identifier */
459         hdr->opnum        = opnum;     /* opnum */
460 }
461
462 /*******************************************************************
463  Reads or writes an RPC_HDR_REQ structure.
464 ********************************************************************/
465
466 bool smb_io_rpc_hdr_req(const char *desc, RPC_HDR_REQ *rpc, prs_struct *ps, int depth)
467 {
468         if (rpc == NULL)
469                 return False;
470
471         prs_debug(ps, depth, desc, "smb_io_rpc_hdr_req");
472         depth++;
473
474         if(!prs_uint32("alloc_hint", ps, depth, &rpc->alloc_hint))
475                 return False;
476         if(!prs_uint16("context_id", ps, depth, &rpc->context_id))
477                 return False;
478         if(!prs_uint16("opnum     ", ps, depth, &rpc->opnum))
479                 return False;
480         return True;
481 }
482
483 /*******************************************************************
484  Reads or writes an RPC_HDR_RESP structure.
485 ********************************************************************/
486
487 bool smb_io_rpc_hdr_resp(const char *desc, RPC_HDR_RESP *rpc, prs_struct *ps, int depth)
488 {
489         if (rpc == NULL)
490                 return False;
491
492         prs_debug(ps, depth, desc, "smb_io_rpc_hdr_resp");
493         depth++;
494
495         if(!prs_uint32("alloc_hint", ps, depth, &rpc->alloc_hint))
496                 return False;
497         if(!prs_uint16("context_id", ps, depth, &rpc->context_id))
498                 return False;
499         if(!prs_uint8 ("cancel_ct ", ps, depth, &rpc->cancel_count))
500                 return False;
501         if(!prs_uint8 ("reserved  ", ps, depth, &rpc->reserved))
502                 return False;
503         return True;
504 }
505
506 /*******************************************************************
507  Reads or writes an RPC_HDR_FAULT structure.
508 ********************************************************************/
509
510 bool smb_io_rpc_hdr_fault(const char *desc, RPC_HDR_FAULT *rpc, prs_struct *ps, int depth)
511 {
512         if (rpc == NULL)
513                 return False;
514
515         prs_debug(ps, depth, desc, "smb_io_rpc_hdr_fault");
516         depth++;
517
518         if(!prs_dcerpc_status("status  ", ps, depth, &rpc->status))
519                 return False;
520         if(!prs_uint32("reserved", ps, depth, &rpc->reserved))
521                 return False;
522
523     return True;
524 }
525
526 /*******************************************************************
527  Inits an RPC_HDR_AUTH structure.
528 ********************************************************************/
529
530 void init_rpc_hdr_auth(RPC_HDR_AUTH *rai,
531                                 uint8 auth_type, uint8 auth_level,
532                                 uint8 auth_pad_len,
533                                 uint32 auth_context_id)
534 {
535         rai->auth_type     = auth_type;
536         rai->auth_level    = auth_level;
537         rai->auth_pad_len  = auth_pad_len;
538         rai->auth_reserved = 0;
539         rai->auth_context_id = auth_context_id;
540 }
541
542 /*******************************************************************
543  Reads or writes an RPC_HDR_AUTH structure.
544 ********************************************************************/
545
546 bool smb_io_rpc_hdr_auth(const char *desc, RPC_HDR_AUTH *rai, prs_struct *ps, int depth)
547 {
548         if (rai == NULL)
549                 return False;
550
551         prs_debug(ps, depth, desc, "smb_io_rpc_hdr_auth");
552         depth++;
553
554         if(!prs_align(ps))
555                 return False;
556
557         if(!prs_uint8 ("auth_type    ", ps, depth, &rai->auth_type))
558                 return False;
559         if(!prs_uint8 ("auth_level   ", ps, depth, &rai->auth_level))
560                 return False;
561         if(!prs_uint8 ("auth_pad_len ", ps, depth, &rai->auth_pad_len))
562                 return False;
563         if(!prs_uint8 ("auth_reserved", ps, depth, &rai->auth_reserved))
564                 return False;
565         if(!prs_uint32("auth_context_id", ps, depth, &rai->auth_context_id))
566                 return False;
567
568         return True;
569 }
570
571 /*******************************************************************
572  Checks an RPC_AUTH_VERIFIER structure.
573 ********************************************************************/
574
575 bool rpc_auth_verifier_chk(RPC_AUTH_VERIFIER *rav,
576                                 const char *signature, uint32 msg_type)
577 {
578         return (strequal(rav->signature, signature) && rav->msg_type == msg_type);
579 }
580
581 /*******************************************************************
582  Inits an RPC_AUTH_VERIFIER structure.
583 ********************************************************************/
584
585 void init_rpc_auth_verifier(RPC_AUTH_VERIFIER *rav,
586                                 const char *signature, uint32 msg_type)
587 {
588         fstrcpy(rav->signature, signature); /* "NTLMSSP" */
589         rav->msg_type = msg_type; /* NTLMSSP_MESSAGE_TYPE */
590 }
591
592 /*******************************************************************
593  Reads or writes an RPC_AUTH_VERIFIER structure.
594 ********************************************************************/
595
596 bool smb_io_rpc_auth_verifier(const char *desc, RPC_AUTH_VERIFIER *rav, prs_struct *ps, int depth)
597 {
598         if (rav == NULL)
599                 return False;
600
601         prs_debug(ps, depth, desc, "smb_io_rpc_auth_verifier");
602         depth++;
603
604         /* "NTLMSSP" */
605         if(!prs_string("signature", ps, depth, rav->signature,
606                         sizeof(rav->signature)))
607                 return False;
608         if(!prs_uint32("msg_type ", ps, depth, &rav->msg_type)) /* NTLMSSP_MESSAGE_TYPE */
609                 return False;
610
611         return True;
612 }
613
614 /*******************************************************************
615  This parses an RPC_AUTH_VERIFIER for schannel. I think
616 ********************************************************************/
617
618 bool smb_io_rpc_schannel_verifier(const char *desc, RPC_AUTH_VERIFIER *rav, prs_struct *ps, int depth)
619 {
620         if (rav == NULL)
621                 return False;
622
623         prs_debug(ps, depth, desc, "smb_io_rpc_schannel_verifier");
624         depth++;
625
626         if(!prs_string("signature", ps, depth, rav->signature, sizeof(rav->signature)))
627                 return False;
628         if(!prs_uint32("msg_type ", ps, depth, &rav->msg_type))
629                 return False;
630
631         return True;
632 }
633
634 /*******************************************************************
635 creates an RPC_AUTH_SCHANNEL_NEG structure.
636 ********************************************************************/
637
638 void init_rpc_auth_schannel_neg(RPC_AUTH_SCHANNEL_NEG *neg,
639                               const char *domain, const char *myname)
640 {
641         neg->type1 = 0;
642         neg->type2 = 0x3;
643         fstrcpy(neg->domain, domain);
644         fstrcpy(neg->myname, myname);
645 }
646
647 /*******************************************************************
648  Reads or writes an RPC_AUTH_SCHANNEL_NEG structure.
649 ********************************************************************/
650
651 bool smb_io_rpc_auth_schannel_neg(const char *desc, RPC_AUTH_SCHANNEL_NEG *neg,
652                                 prs_struct *ps, int depth)
653 {
654         if (neg == NULL)
655                 return False;
656
657         prs_debug(ps, depth, desc, "smb_io_rpc_auth_schannel_neg");
658         depth++;
659
660         if(!prs_align(ps))
661                 return False;
662
663         if(!prs_uint32("type1", ps, depth, &neg->type1))
664                 return False;
665         if(!prs_uint32("type2", ps, depth, &neg->type2))
666                 return False;
667         if(!prs_string("domain  ", ps, depth, neg->domain, sizeof(neg->domain)))
668                 return False;
669         if(!prs_string("myname  ", ps, depth, neg->myname, sizeof(neg->myname)))
670                 return False;
671
672         return True;
673 }
674
675 /*******************************************************************
676 reads or writes an RPC_AUTH_SCHANNEL_CHK structure.
677 ********************************************************************/
678
679 bool smb_io_rpc_auth_schannel_chk(const char *desc, int auth_len, 
680                                 RPC_AUTH_SCHANNEL_CHK * chk,
681                                 prs_struct *ps, int depth)
682 {
683         if (chk == NULL)
684                 return False;
685
686         prs_debug(ps, depth, desc, "smb_io_rpc_auth_schannel_chk");
687         depth++;
688
689         if ( !prs_uint8s(False, "sig  ", ps, depth, chk->sig, sizeof(chk->sig)) )
690                 return False;
691                 
692         if ( !prs_uint8s(False, "seq_num", ps, depth, chk->seq_num, sizeof(chk->seq_num)) )
693                 return False;
694                 
695         if ( !prs_uint8s(False, "packet_digest", ps, depth, chk->packet_digest, sizeof(chk->packet_digest)) )
696                 return False;
697         
698         if ( auth_len == RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN ) {
699                 if ( !prs_uint8s(False, "confounder", ps, depth, chk->confounder, sizeof(chk->confounder)) )
700                         return False;
701         }
702
703         return True;
704 }