6fd3ef764d2b358a12694a187257546db7da28e6
[sfrench/samba-autobuild/.git] / source / 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, write to the Free Software
21  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22  */
23
24 #include "includes.h"
25
26 #undef DBGC_CLASS
27 #define DBGC_CLASS DBGC_RPC_PARSE
28
29 /*******************************************************************
30 interface/version dce/rpc pipe identification
31 ********************************************************************/
32
33 #define TRANS_SYNT_V2                       \
34 {                                           \
35         {                                   \
36                 0x8a885d04, 0x1ceb, 0x11c9, \
37                 { 0x9f, 0xe8 },             \
38                 { 0x08, 0x00,               \
39                   0x2b, 0x10, 0x48, 0x60 }  \
40         }, 0x02                             \
41 }
42
43 #define SYNT_NETLOGON_V2                    \
44 {                                           \
45         {                                   \
46                 0x8a885d04, 0x1ceb, 0x11c9, \
47                 { 0x9f, 0xe8 },             \
48                 { 0x08, 0x00,               \
49                   0x2b, 0x10, 0x48, 0x60 }  \
50         }, 0x02                             \
51 }
52
53 #define SYNT_WKSSVC_V1                      \
54 {                                           \
55         {                                   \
56                 0x6bffd098, 0xa112, 0x3610, \
57                 { 0x98, 0x33 },             \
58                 { 0x46, 0xc3,               \
59                   0xf8, 0x7e, 0x34, 0x5a }  \
60         }, 0x01                             \
61 }
62
63 #define SYNT_SRVSVC_V3                      \
64 {                                           \
65         {                                   \
66                 0x4b324fc8, 0x1670, 0x01d3, \
67                 { 0x12, 0x78 },             \
68                 { 0x5a, 0x47,               \
69                   0xbf, 0x6e, 0xe1, 0x88 }  \
70         }, 0x03                             \
71 }
72
73 #define SYNT_LSARPC_V0                      \
74 {                                           \
75         {                                   \
76                 0x12345778, 0x1234, 0xabcd, \
77                 { 0xef, 0x00 },             \
78                 { 0x01, 0x23,               \
79                   0x45, 0x67, 0x89, 0xab }  \
80         }, 0x00                             \
81 }
82
83 #define SYNT_LSARPC_V0_DS                \
84 {                                           \
85         {                                   \
86                 0x3919286a, 0xb10c, 0x11d0, \
87                 { 0x9b, 0xa8 },             \
88                 { 0x00, 0xc0,               \
89                   0x4f, 0xd9, 0x2e, 0xf5 }  \
90         }, 0x00                             \
91 }
92
93 #define SYNT_SAMR_V1                        \
94 {                                           \
95         {                                   \
96                 0x12345778, 0x1234, 0xabcd, \
97                 { 0xef, 0x00 },             \
98                 { 0x01, 0x23,               \
99                   0x45, 0x67, 0x89, 0xac }  \
100         }, 0x01                             \
101 }
102
103 #define SYNT_NETLOGON_V1                    \
104 {                                           \
105         {                                   \
106                 0x12345678, 0x1234, 0xabcd, \
107                 { 0xef, 0x00 },             \
108                 { 0x01, 0x23,               \
109                   0x45, 0x67, 0xcf, 0xfb }  \
110         }, 0x01                             \
111 }
112
113 #define SYNT_WINREG_V1                      \
114 {                                           \
115         {                                   \
116                 0x338cd001, 0x2244, 0x31f1, \
117                 { 0xaa, 0xaa },             \
118                 { 0x90, 0x00,               \
119                   0x38, 0x00, 0x10, 0x03 }  \
120         }, 0x01                             \
121 }
122
123 #define SYNT_SPOOLSS_V1                     \
124 {                                           \
125         {                                   \
126                 0x12345678, 0x1234, 0xabcd, \
127                 { 0xef, 0x00 },             \
128                 { 0x01, 0x23,               \
129                   0x45, 0x67, 0x89, 0xab }  \
130         }, 0x01                             \
131 }
132
133 #define SYNT_NONE_V0                        \
134 {                                           \
135         {                                   \
136                 0x0, 0x0, 0x0,              \
137                 { 0x00, 0x00 },             \
138                 { 0x00, 0x00,               \
139                   0x00, 0x00, 0x00, 0x00 }  \
140         }, 0x00                             \
141 }
142
143 #define SYNT_NETDFS_V3                      \
144 {                                           \
145         {                                   \
146                 0x4fc742e0, 0x4a10, 0x11cf, \
147                 { 0x82, 0x73 },             \
148                 { 0x00, 0xaa,               \
149                   0x00, 0x4a, 0xe6, 0x73 }  \
150         }, 0x03                             \
151 }
152
153 #define SYNT_ECHO_V1                        \
154 {                                           \
155         {                                   \
156                 0x60a15ec5, 0x4de8, 0x11d7, \
157                 { 0xa6, 0x37 },             \
158                 { 0x00, 0x50,               \
159                   0x56, 0xa2, 0x01, 0x82 }  \
160         }, 0x01                             \
161 }
162
163 #define SYNT_SHUTDOWN_V1                    \
164 {                                           \
165         {                                   \
166                 0x894de0c0, 0x0d55, 0x11d3, \
167                 { 0xa3, 0x22 },             \
168                 { 0x00, 0xc0,               \
169                   0x4f, 0xa3, 0x21, 0xa1 }  \
170         }, 0x01                             \
171 }
172
173 #define SYNT_SVCCTL_V2                      \
174 {                                           \
175         {                                   \
176                 0x367abb81, 0x9844, 0x35f1, \
177                 { 0xad, 0x32 },             \
178                 { 0x98, 0xf0,               \
179                   0x38, 0x00, 0x10, 0x03 }  \
180         }, 0x02                             \
181 }
182
183
184 #define SYNT_EVENTLOG_V0                    \
185 {                                           \
186         {                                   \
187                 0x82273fdc, 0xe32a, 0x18c3, \
188                 { 0x3f, 0x78 },             \
189                 { 0x82, 0x79,               \
190                   0x29, 0xdc, 0x23, 0xea }  \
191         }, 0x00                             \
192 }
193
194 #define SYNT_UNIXINFO_V0                    \
195 {                                           \
196         {                                   \
197                 0x9c54e310, 0xa955, 0x4885, \
198                 { 0xbd, 0x31 },             \
199                 { 0x78, 0x78,               \
200                   0x71, 0x47, 0xdf, 0xa6 }  \
201         }, 0x00                             \
202 }
203
204 #define SYNT_NTSVCS_V1                      \
205 {                                           \
206         {                                   \
207                 0x8d9f4e40, 0xa03d, 0x11ce, \
208                 { 0x8f, 0x69},              \
209                 { 0x08, 0x00,               \
210                   0x3e, 0x30, 0x05, 0x1b }  \
211         }, 0x01                             \
212 }
213
214 #define SYNT_EPMAPPER_V3                                        \
215 {                                                                                       \
216         {                                                                               \
217                 0xe1af8308, 0x5d1f,0x11c9, \
218                 { 0x91,0xa4},                                           \
219                          {0x08,0x00,                            \
220                               0x2b,0x14,0xa0,0xfa}      \
221         }, 0x03 \
222 }
223
224 /*
225  * IMPORTANT!!  If you update this structure, make sure to
226  * update the index #defines in smb.h.
227  */
228
229 const struct pipe_id_info pipe_names [] =
230 {
231         /* client pipe , abstract syntax       , server pipe   , transfer syntax */
232         { PIPE_LSARPC  , SYNT_LSARPC_V0        , PIPE_LSASS    , TRANS_SYNT_V2 },
233         { PIPE_LSARPC  , SYNT_LSARPC_V0_DS     , PIPE_LSASS    , TRANS_SYNT_V2 },
234         { PIPE_SAMR    , SYNT_SAMR_V1          , PIPE_LSASS    , TRANS_SYNT_V2 },
235         { PIPE_NETLOGON, SYNT_NETLOGON_V1      , PIPE_LSASS    , TRANS_SYNT_V2 },
236         { PIPE_SRVSVC  , SYNT_SRVSVC_V3        , PIPE_NTSVCS   , TRANS_SYNT_V2 },
237         { PIPE_WKSSVC  , SYNT_WKSSVC_V1        , PIPE_NTSVCS   , TRANS_SYNT_V2 },
238         { PIPE_WINREG  , SYNT_WINREG_V1        , PIPE_WINREG   , TRANS_SYNT_V2 },
239         { PIPE_SPOOLSS , SYNT_SPOOLSS_V1       , PIPE_SPOOLSS  , TRANS_SYNT_V2 },
240         { PIPE_NETDFS  , SYNT_NETDFS_V3        , PIPE_NETDFS   , TRANS_SYNT_V2 },
241         { PIPE_ECHO    , SYNT_ECHO_V1          , PIPE_ECHO     , TRANS_SYNT_V2 },
242         { PIPE_SHUTDOWN, SYNT_SHUTDOWN_V1      , PIPE_SHUTDOWN , TRANS_SYNT_V2 },
243         { PIPE_SVCCTL  , SYNT_SVCCTL_V2        , PIPE_NTSVCS   , TRANS_SYNT_V2 },
244         { PIPE_EVENTLOG, SYNT_EVENTLOG_V0      , PIPE_EVENTLOG , TRANS_SYNT_V2 },
245         { PIPE_UNIXINFO, SYNT_UNIXINFO_V0      , PIPE_UNIXINFO , TRANS_SYNT_V2 },
246         { PIPE_NTSVCS  , SYNT_NTSVCS_V1        , PIPE_NTSVCS   , TRANS_SYNT_V2 },
247         { PIPE_EPMAPPER, SYNT_EPMAPPER_V3          , PIPE_EPMAPPER , TRANS_SYNT_V2 },
248         { NULL         , SYNT_NONE_V0          , NULL          , SYNT_NONE_V0  }
249 };
250
251 /****************************************************************************
252  Return the pipe name from the index.
253  ****************************************************************************/
254
255 const char *cli_get_pipe_name(int pipe_idx)
256 {
257         return &pipe_names[pipe_idx].client_pipe[5];
258 }
259
260 /*******************************************************************
261  Inits an RPC_HDR structure.
262 ********************************************************************/
263
264 void init_rpc_hdr(RPC_HDR *hdr, enum RPC_PKT_TYPE pkt_type, uint8 flags,
265                                 uint32 call_id, int data_len, int auth_len)
266 {
267         hdr->major        = 5;               /* RPC version 5 */
268         hdr->minor        = 0;               /* minor version 0 */
269         hdr->pkt_type     = pkt_type;        /* RPC packet type */
270         hdr->flags        = flags;           /* dce/rpc flags */
271         hdr->pack_type[0] = 0x10;            /* little-endian data representation */
272         hdr->pack_type[1] = 0;               /* packed data representation */
273         hdr->pack_type[2] = 0;               /* packed data representation */
274         hdr->pack_type[3] = 0;               /* packed data representation */
275         hdr->frag_len     = data_len;        /* fragment length, fill in later */
276         hdr->auth_len     = auth_len;        /* authentication length */
277         hdr->call_id      = call_id;         /* call identifier - match incoming RPC */
278 }
279
280 /*******************************************************************
281  Reads or writes an RPC_HDR structure.
282 ********************************************************************/
283
284 BOOL smb_io_rpc_hdr(const char *desc,  RPC_HDR *rpc, prs_struct *ps, int depth)
285 {
286         if (rpc == NULL)
287                 return False;
288
289         prs_debug(ps, depth, desc, "smb_io_rpc_hdr");
290         depth++;
291
292         if(!prs_uint8 ("major     ", ps, depth, &rpc->major))
293                 return False;
294
295         if(!prs_uint8 ("minor     ", ps, depth, &rpc->minor))
296                 return False;
297         if(!prs_uint8 ("pkt_type  ", ps, depth, &rpc->pkt_type))
298                 return False;
299         if(!prs_uint8 ("flags     ", ps, depth, &rpc->flags))
300                 return False;
301
302         /* We always marshall in little endian format. */
303         if (MARSHALLING(ps))
304                 rpc->pack_type[0] = 0x10;
305
306         if(!prs_uint8("pack_type0", ps, depth, &rpc->pack_type[0]))
307                 return False;
308         if(!prs_uint8("pack_type1", ps, depth, &rpc->pack_type[1]))
309                 return False;
310         if(!prs_uint8("pack_type2", ps, depth, &rpc->pack_type[2]))
311                 return False;
312         if(!prs_uint8("pack_type3", ps, depth, &rpc->pack_type[3]))
313                 return False;
314
315         /*
316          * If reading and pack_type[0] == 0 then the data is in big-endian
317          * format. Set the flag in the prs_struct to specify reverse-endainness.
318          */
319
320         if (UNMARSHALLING(ps) && rpc->pack_type[0] == 0) {
321                 DEBUG(10,("smb_io_rpc_hdr: PDU data format is big-endian. Setting flag.\n"));
322                 prs_set_endian_data(ps, RPC_BIG_ENDIAN);
323         }
324
325         if(!prs_uint16("frag_len  ", ps, depth, &rpc->frag_len))
326                 return False;
327         if(!prs_uint16("auth_len  ", ps, depth, &rpc->auth_len))
328                 return False;
329         if(!prs_uint32("call_id   ", ps, depth, &rpc->call_id))
330                 return False;
331         return True;
332 }
333
334 /*******************************************************************
335  Reads or writes an RPC_IFACE structure.
336 ********************************************************************/
337
338 static BOOL smb_io_rpc_iface(const char *desc, RPC_IFACE *ifc, prs_struct *ps, int depth)
339 {
340         if (ifc == NULL)
341                 return False;
342
343         prs_debug(ps, depth, desc, "smb_io_rpc_iface");
344         depth++;
345
346         if (!prs_align(ps))
347                 return False;
348
349         if (!smb_io_uuid(  "uuid", &ifc->uuid, ps, depth))
350                 return False;
351
352         if(!prs_uint32 ("version", ps, depth, &ifc->version))
353                 return False;
354
355         return True;
356 }
357
358 /*******************************************************************
359  Inits an RPC_ADDR_STR structure.
360 ********************************************************************/
361
362 static void init_rpc_addr_str(RPC_ADDR_STR *str, const char *name)
363 {
364         str->len = strlen(name) + 1;
365         fstrcpy(str->str, name);
366 }
367
368 /*******************************************************************
369  Reads or writes an RPC_ADDR_STR structure.
370 ********************************************************************/
371
372 static BOOL smb_io_rpc_addr_str(const char *desc,  RPC_ADDR_STR *str, prs_struct *ps, int depth)
373 {
374         if (str == NULL)
375                 return False;
376
377         prs_debug(ps, depth, desc, "smb_io_rpc_addr_str");
378         depth++;
379         if(!prs_align(ps))
380                 return False;
381
382         if(!prs_uint16 (      "len", ps, depth, &str->len))
383                 return False;
384         if(!prs_uint8s (True, "str", ps, depth, (uchar*)str->str, MIN(str->len, sizeof(str->str)) ))
385                 return False;
386         return True;
387 }
388
389 /*******************************************************************
390  Inits an RPC_HDR_BBA structure.
391 ********************************************************************/
392
393 static void init_rpc_hdr_bba(RPC_HDR_BBA *bba, uint16 max_tsize, uint16 max_rsize, uint32 assoc_gid)
394 {
395         bba->max_tsize = max_tsize; /* maximum transmission fragment size (0x1630) */
396         bba->max_rsize = max_rsize; /* max receive fragment size (0x1630) */   
397         bba->assoc_gid = assoc_gid; /* associated group id (0x0) */ 
398 }
399
400 /*******************************************************************
401  Reads or writes an RPC_HDR_BBA structure.
402 ********************************************************************/
403
404 static BOOL smb_io_rpc_hdr_bba(const char *desc,  RPC_HDR_BBA *rpc, prs_struct *ps, int depth)
405 {
406         if (rpc == NULL)
407                 return False;
408
409         prs_debug(ps, depth, desc, "smb_io_rpc_hdr_bba");
410         depth++;
411
412         if(!prs_uint16("max_tsize", ps, depth, &rpc->max_tsize))
413                 return False;
414         if(!prs_uint16("max_rsize", ps, depth, &rpc->max_rsize))
415                 return False;
416         if(!prs_uint32("assoc_gid", ps, depth, &rpc->assoc_gid))
417                 return False;
418         return True;
419 }
420
421 /*******************************************************************
422  Inits an RPC_CONTEXT structure.
423  Note the transfer pointer must remain valid until this is marshalled.
424 ********************************************************************/
425
426 void init_rpc_context(RPC_CONTEXT *rpc_ctx, uint16 context_id, RPC_IFACE *abstract, RPC_IFACE *transfer)
427 {
428         rpc_ctx->context_id   = context_id   ; /* presentation context identifier (0x0) */
429         rpc_ctx->num_transfer_syntaxes = 1 ; /* the number of syntaxes (has always been 1?)(0x1) */
430
431         /* num and vers. of interface client is using */
432         rpc_ctx->abstract = *abstract;
433
434         /* vers. of interface to use for replies */
435         rpc_ctx->transfer = transfer;
436 }
437
438 /*******************************************************************
439  Inits an RPC_HDR_RB structure.
440  Note the context pointer must remain valid until this is marshalled.
441 ********************************************************************/
442
443 void init_rpc_hdr_rb(RPC_HDR_RB *rpc, 
444                                 uint16 max_tsize, uint16 max_rsize, uint32 assoc_gid,
445                                 RPC_CONTEXT *context)
446 {
447         init_rpc_hdr_bba(&rpc->bba, max_tsize, max_rsize, assoc_gid);
448
449         rpc->num_contexts = 1;
450         rpc->rpc_context = context;
451 }
452
453 /*******************************************************************
454  Reads or writes an RPC_CONTEXT structure.
455 ********************************************************************/
456
457 BOOL smb_io_rpc_context(const char *desc, RPC_CONTEXT *rpc_ctx, prs_struct *ps, int depth)
458 {
459         int i;
460
461         if (rpc_ctx == NULL)
462                 return False;
463
464         if(!prs_align(ps))
465                 return False;
466         if(!prs_uint16("context_id  ", ps, depth, &rpc_ctx->context_id ))
467                 return False;
468         if(!prs_uint8 ("num_transfer_syntaxes", ps, depth, &rpc_ctx->num_transfer_syntaxes))
469                 return False;
470
471         /* num_transfer_syntaxes must not be zero. */
472         if (rpc_ctx->num_transfer_syntaxes == 0)
473                 return False;
474
475         if(!smb_io_rpc_iface("", &rpc_ctx->abstract, ps, depth))
476                 return False;
477
478         if (UNMARSHALLING(ps)) {
479                 if (!(rpc_ctx->transfer = PRS_ALLOC_MEM(ps, RPC_IFACE, rpc_ctx->num_transfer_syntaxes))) {
480                         return False;
481                 }
482         }
483
484         for (i = 0; i < rpc_ctx->num_transfer_syntaxes; i++ ) {
485                 if (!smb_io_rpc_iface("", &rpc_ctx->transfer[i], ps, depth))
486                         return False;
487         }
488         return True;
489
490
491 /*******************************************************************
492  Reads or writes an RPC_HDR_RB structure.
493 ********************************************************************/
494
495 BOOL smb_io_rpc_hdr_rb(const char *desc, RPC_HDR_RB *rpc, prs_struct *ps, int depth)
496 {
497         int i;
498         
499         if (rpc == NULL)
500                 return False;
501
502         prs_debug(ps, depth, desc, "smb_io_rpc_hdr_rb");
503         depth++;
504
505         if(!smb_io_rpc_hdr_bba("", &rpc->bba, ps, depth))
506                 return False;
507
508         if(!prs_uint8("num_contexts", ps, depth, &rpc->num_contexts))
509                 return False;
510
511         /* 3 pad bytes following - will be mopped up by the prs_align in smb_io_rpc_context(). */
512
513         /* num_contexts must not be zero. */
514         if (rpc->num_contexts == 0)
515                 return False;
516
517         if (UNMARSHALLING(ps)) {
518                 if (!(rpc->rpc_context = PRS_ALLOC_MEM(ps, RPC_CONTEXT, rpc->num_contexts))) {
519                         return False;
520                 }
521         }
522
523         for (i = 0; i < rpc->num_contexts; i++ ) {
524                 if (!smb_io_rpc_context("", &rpc->rpc_context[i], ps, depth))
525                         return False;
526         }
527
528         return True;
529 }
530
531 /*******************************************************************
532  Inits an RPC_RESULTS structure.
533
534  lkclXXXX only one reason at the moment!
535 ********************************************************************/
536
537 static void init_rpc_results(RPC_RESULTS *res, 
538                                 uint8 num_results, uint16 result, uint16 reason)
539 {
540         res->num_results = num_results; /* the number of results (0x01) */
541         res->result      = result     ;  /* result (0x00 = accept) */
542         res->reason      = reason     ;  /* reason (0x00 = no reason specified) */
543 }
544
545 /*******************************************************************
546  Reads or writes an RPC_RESULTS structure.
547
548  lkclXXXX only one reason at the moment!
549 ********************************************************************/
550
551 static BOOL smb_io_rpc_results(const char *desc, RPC_RESULTS *res, prs_struct *ps, int depth)
552 {
553         if (res == NULL)
554                 return False;
555
556         prs_debug(ps, depth, desc, "smb_io_rpc_results");
557         depth++;
558
559         if(!prs_align(ps))
560                 return False;
561         
562         if(!prs_uint8 ("num_results", ps, depth, &res->num_results))    
563                 return False;
564
565         if(!prs_align(ps))
566                 return False;
567         
568         if(!prs_uint16("result     ", ps, depth, &res->result))
569                 return False;
570         if(!prs_uint16("reason     ", ps, depth, &res->reason))
571                 return False;
572         return True;
573 }
574
575 /*******************************************************************
576  Init an RPC_HDR_BA structure.
577
578  lkclXXXX only one reason at the moment!
579
580 ********************************************************************/
581
582 void init_rpc_hdr_ba(RPC_HDR_BA *rpc, 
583                                 uint16 max_tsize, uint16 max_rsize, uint32 assoc_gid,
584                                 const char *pipe_addr,
585                                 uint8 num_results, uint16 result, uint16 reason,
586                                 RPC_IFACE *transfer)
587 {
588         init_rpc_hdr_bba (&rpc->bba, max_tsize, max_rsize, assoc_gid);
589         init_rpc_addr_str(&rpc->addr, pipe_addr);
590         init_rpc_results (&rpc->res, num_results, result, reason);
591
592         /* the transfer syntax from the request */
593         memcpy(&rpc->transfer, transfer, sizeof(rpc->transfer));
594 }
595
596 /*******************************************************************
597  Reads or writes an RPC_HDR_BA structure.
598 ********************************************************************/
599
600 BOOL smb_io_rpc_hdr_ba(const char *desc, RPC_HDR_BA *rpc, prs_struct *ps, int depth)
601 {
602         if (rpc == NULL)
603                 return False;
604
605         prs_debug(ps, depth, desc, "smb_io_rpc_hdr_ba");
606         depth++;
607
608         if(!smb_io_rpc_hdr_bba("", &rpc->bba, ps, depth))
609                 return False;
610         if(!smb_io_rpc_addr_str("", &rpc->addr, ps, depth))
611                 return False;
612         if(!smb_io_rpc_results("", &rpc->res, ps, depth))
613                 return False;
614         if(!smb_io_rpc_iface("", &rpc->transfer, ps, depth))
615                 return False;
616         return True;
617 }
618
619 /*******************************************************************
620  Init an RPC_HDR_REQ structure.
621 ********************************************************************/
622
623 void init_rpc_hdr_req(RPC_HDR_REQ *hdr, uint32 alloc_hint, uint16 opnum)
624 {
625         hdr->alloc_hint   = alloc_hint; /* allocation hint */
626         hdr->context_id   = 0;         /* presentation context identifier */
627         hdr->opnum        = opnum;     /* opnum */
628 }
629
630 /*******************************************************************
631  Reads or writes an RPC_HDR_REQ structure.
632 ********************************************************************/
633
634 BOOL smb_io_rpc_hdr_req(const char *desc, RPC_HDR_REQ *rpc, prs_struct *ps, int depth)
635 {
636         if (rpc == NULL)
637                 return False;
638
639         prs_debug(ps, depth, desc, "smb_io_rpc_hdr_req");
640         depth++;
641
642         if(!prs_uint32("alloc_hint", ps, depth, &rpc->alloc_hint))
643                 return False;
644         if(!prs_uint16("context_id", ps, depth, &rpc->context_id))
645                 return False;
646         if(!prs_uint16("opnum     ", ps, depth, &rpc->opnum))
647                 return False;
648         return True;
649 }
650
651 /*******************************************************************
652  Reads or writes an RPC_HDR_RESP structure.
653 ********************************************************************/
654
655 BOOL smb_io_rpc_hdr_resp(const char *desc, RPC_HDR_RESP *rpc, prs_struct *ps, int depth)
656 {
657         if (rpc == NULL)
658                 return False;
659
660         prs_debug(ps, depth, desc, "smb_io_rpc_hdr_resp");
661         depth++;
662
663         if(!prs_uint32("alloc_hint", ps, depth, &rpc->alloc_hint))
664                 return False;
665         if(!prs_uint16("context_id", ps, depth, &rpc->context_id))
666                 return False;
667         if(!prs_uint8 ("cancel_ct ", ps, depth, &rpc->cancel_count))
668                 return False;
669         if(!prs_uint8 ("reserved  ", ps, depth, &rpc->reserved))
670                 return False;
671         return True;
672 }
673
674 /*******************************************************************
675  Reads or writes an RPC_HDR_FAULT structure.
676 ********************************************************************/
677
678 BOOL smb_io_rpc_hdr_fault(const char *desc, RPC_HDR_FAULT *rpc, prs_struct *ps, int depth)
679 {
680         if (rpc == NULL)
681                 return False;
682
683         prs_debug(ps, depth, desc, "smb_io_rpc_hdr_fault");
684         depth++;
685
686         if(!prs_dcerpc_status("status  ", ps, depth, &rpc->status))
687                 return False;
688         if(!prs_uint32("reserved", ps, depth, &rpc->reserved))
689                 return False;
690
691     return True;
692 }
693
694 /*******************************************************************
695  Inits an RPC_HDR_AUTH structure.
696 ********************************************************************/
697
698 void init_rpc_hdr_auth(RPC_HDR_AUTH *rai,
699                                 uint8 auth_type, uint8 auth_level,
700                                 uint8 auth_pad_len,
701                                 uint32 auth_context_id)
702 {
703         rai->auth_type     = auth_type;
704         rai->auth_level    = auth_level;
705         rai->auth_pad_len  = auth_pad_len;
706         rai->auth_reserved = 0;
707         rai->auth_context_id = auth_context_id;
708 }
709
710 /*******************************************************************
711  Reads or writes an RPC_HDR_AUTH structure.
712 ********************************************************************/
713
714 BOOL smb_io_rpc_hdr_auth(const char *desc, RPC_HDR_AUTH *rai, prs_struct *ps, int depth)
715 {
716         if (rai == NULL)
717                 return False;
718
719         prs_debug(ps, depth, desc, "smb_io_rpc_hdr_auth");
720         depth++;
721
722         if(!prs_align(ps))
723                 return False;
724
725         if(!prs_uint8 ("auth_type    ", ps, depth, &rai->auth_type))
726                 return False;
727         if(!prs_uint8 ("auth_level   ", ps, depth, &rai->auth_level))
728                 return False;
729         if(!prs_uint8 ("auth_pad_len ", ps, depth, &rai->auth_pad_len))
730                 return False;
731         if(!prs_uint8 ("auth_reserved", ps, depth, &rai->auth_reserved))
732                 return False;
733         if(!prs_uint32("auth_context_id", ps, depth, &rai->auth_context_id))
734                 return False;
735
736         return True;
737 }
738
739 /*******************************************************************
740  Checks an RPC_AUTH_VERIFIER structure.
741 ********************************************************************/
742
743 BOOL rpc_auth_verifier_chk(RPC_AUTH_VERIFIER *rav,
744                                 const char *signature, uint32 msg_type)
745 {
746         return (strequal(rav->signature, signature) && rav->msg_type == msg_type);
747 }
748
749 /*******************************************************************
750  Inits an RPC_AUTH_VERIFIER structure.
751 ********************************************************************/
752
753 void init_rpc_auth_verifier(RPC_AUTH_VERIFIER *rav,
754                                 const char *signature, uint32 msg_type)
755 {
756         fstrcpy(rav->signature, signature); /* "NTLMSSP" */
757         rav->msg_type = msg_type; /* NTLMSSP_MESSAGE_TYPE */
758 }
759
760 /*******************************************************************
761  Reads or writes an RPC_AUTH_VERIFIER structure.
762 ********************************************************************/
763
764 BOOL smb_io_rpc_auth_verifier(const char *desc, RPC_AUTH_VERIFIER *rav, prs_struct *ps, int depth)
765 {
766         if (rav == NULL)
767                 return False;
768
769         prs_debug(ps, depth, desc, "smb_io_rpc_auth_verifier");
770         depth++;
771
772         /* "NTLMSSP" */
773         if(!prs_string("signature", ps, depth, rav->signature,
774                         sizeof(rav->signature)))
775                 return False;
776         if(!prs_uint32("msg_type ", ps, depth, &rav->msg_type)) /* NTLMSSP_MESSAGE_TYPE */
777                 return False;
778
779         return True;
780 }
781
782 /*******************************************************************
783  This parses an RPC_AUTH_VERIFIER for schannel. I think
784 ********************************************************************/
785
786 BOOL smb_io_rpc_schannel_verifier(const char *desc, RPC_AUTH_VERIFIER *rav, prs_struct *ps, int depth)
787 {
788         if (rav == NULL)
789                 return False;
790
791         prs_debug(ps, depth, desc, "smb_io_rpc_schannel_verifier");
792         depth++;
793
794         if(!prs_string("signature", ps, depth, rav->signature, sizeof(rav->signature)))
795                 return False;
796         if(!prs_uint32("msg_type ", ps, depth, &rav->msg_type))
797                 return False;
798
799         return True;
800 }
801
802 /*******************************************************************
803 creates an RPC_AUTH_SCHANNEL_NEG structure.
804 ********************************************************************/
805
806 void init_rpc_auth_schannel_neg(RPC_AUTH_SCHANNEL_NEG *neg,
807                               const char *domain, const char *myname)
808 {
809         neg->type1 = 0;
810         neg->type2 = 0x3;
811         fstrcpy(neg->domain, domain);
812         fstrcpy(neg->myname, myname);
813 }
814
815 /*******************************************************************
816  Reads or writes an RPC_AUTH_SCHANNEL_NEG structure.
817 ********************************************************************/
818
819 BOOL smb_io_rpc_auth_schannel_neg(const char *desc, RPC_AUTH_SCHANNEL_NEG *neg,
820                                 prs_struct *ps, int depth)
821 {
822         if (neg == NULL)
823                 return False;
824
825         prs_debug(ps, depth, desc, "smb_io_rpc_auth_schannel_neg");
826         depth++;
827
828         if(!prs_align(ps))
829                 return False;
830
831         if(!prs_uint32("type1", ps, depth, &neg->type1))
832                 return False;
833         if(!prs_uint32("type2", ps, depth, &neg->type2))
834                 return False;
835         if(!prs_string("domain  ", ps, depth, neg->domain, sizeof(neg->domain)))
836                 return False;
837         if(!prs_string("myname  ", ps, depth, neg->myname, sizeof(neg->myname)))
838                 return False;
839
840         return True;
841 }
842
843 /*******************************************************************
844 reads or writes an RPC_AUTH_SCHANNEL_CHK structure.
845 ********************************************************************/
846
847 BOOL smb_io_rpc_auth_schannel_chk(const char *desc, int auth_len, 
848                                 RPC_AUTH_SCHANNEL_CHK * chk,
849                                 prs_struct *ps, int depth)
850 {
851         if (chk == NULL)
852                 return False;
853
854         prs_debug(ps, depth, desc, "smb_io_rpc_auth_schannel_chk");
855         depth++;
856
857         if ( !prs_uint8s(False, "sig  ", ps, depth, chk->sig, sizeof(chk->sig)) )
858                 return False;
859                 
860         if ( !prs_uint8s(False, "seq_num", ps, depth, chk->seq_num, sizeof(chk->seq_num)) )
861                 return False;
862                 
863         if ( !prs_uint8s(False, "packet_digest", ps, depth, chk->packet_digest, sizeof(chk->packet_digest)) )
864                 return False;
865         
866         if ( auth_len == RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN ) {
867                 if ( !prs_uint8s(False, "confounder", ps, depth, chk->confounder, sizeof(chk->confounder)) )
868                         return False;
869         }
870
871         return True;
872 }