d15cc1248c609b77df89c5e32bf4212af2377f77
[kai/samba.git] / source3 / rpc_server / srv_pipe.c
1
2 /* 
3  *  Unix SMB/Netbios implementation.
4  *  Version 1.9.
5  *  RPC Pipe client / server routines
6  *  Copyright (C) Andrew Tridgell              1992-1998
7  *  Copyright (C) Luke Kenneth Casson Leighton 1996-1998,
8  *  Copyright (C) Paul Ashton                  1997-1998.
9  *  
10  *  This program is free software; you can redistribute it and/or modify
11  *  it under the terms of the GNU General Public License as published by
12  *  the Free Software Foundation; either version 2 of the License, or
13  *  (at your option) any later version.
14  *  
15  *  This program is distributed in the hope that it will be useful,
16  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
17  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  *  GNU General Public License for more details.
19  *  
20  *  You should have received a copy of the GNU General Public License
21  *  along with this program; if not, write to the Free Software
22  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23  */
24
25 /*  this module apparently provides an implementation of DCE/RPC over a
26  *  named pipe (IPC$ connection using SMBtrans).  details of DCE/RPC
27  *  documentation are available (in on-line form) from the X-Open group.
28  *
29  *  this module should provide a level of abstraction between SMB
30  *  and DCE/RPC, while minimising the amount of mallocs, unnecessary
31  *  data copies, and network traffic.
32  *
33  *  in this version, which takes a "let's learn what's going on and
34  *  get something running" approach, there is additional network
35  *  traffic generated, but the code should be easier to understand...
36  *
37  *  ... if you read the docs.  or stare at packets for weeks on end.
38  *
39  */
40
41 #include "includes.h"
42 #include "nterr.h"
43
44 extern int DEBUGLEVEL;
45
46 static void NTLMSSPcalc_p( rpcsrv_struct *p, unsigned char *data, int len)
47 {
48     unsigned char *hash = p->ntlmssp_hash;
49     unsigned char index_i = hash[256];
50     unsigned char index_j = hash[257];
51     int ind;
52
53     for( ind = 0; ind < len; ind++)
54     {
55         unsigned char tc;
56         unsigned char t;
57
58         index_i++;
59         index_j += hash[index_i];
60
61         tc = hash[index_i];
62         hash[index_i] = hash[index_j];
63         hash[index_j] = tc;
64
65         t = hash[index_i] + hash[index_j];
66         data[ind] = data[ind] ^ hash[t];
67     }
68
69     hash[256] = index_i;
70     hash[257] = index_j;
71 }
72
73 /*******************************************************************
74  frees all temporary data used in construction of pdu
75  ********************************************************************/
76 void rpcsrv_free_temp(rpcsrv_struct *l)
77 {
78         mem_free_data(l->rhdr .data);
79         mem_free_data(l->rfault .data);
80         mem_free_data(l->rdata_i.data);         
81         mem_free_data(l->rauth  .data);
82         mem_free_data(l->rverf  .data);
83         mem_free_data(l->rntlm  .data);         
84 }
85
86 /*******************************************************************
87  turns a DCE/RPC request into a DCE/RPC reply
88
89  this is where the data really should be split up into an array of
90  headers and data sections.
91
92  ********************************************************************/
93 BOOL create_rpc_reply(rpcsrv_struct *l, uint32 data_start)
94 {
95         char *data;
96         BOOL auth_verify = IS_BITS_SET_ALL(l->ntlmssp_chal.neg_flags, NTLMSSP_NEGOTIATE_SIGN);
97         BOOL auth_seal   = IS_BITS_SET_ALL(l->ntlmssp_chal.neg_flags, NTLMSSP_NEGOTIATE_SEAL);
98         uint32 data_len;
99         uint32 auth_len;
100         uint32 data_end = l->rdata.offset + (l->ntlmssp_auth ? (8 + 16) : 0);
101
102         DEBUG(5,("create_rpc_reply: data_start: %d data_end: %d max_tsize: %d\n",
103                   data_start, data_end, l->hdr_ba.bba.max_tsize));
104
105         auth_len = l->hdr.auth_len;
106
107         if (l->ntlmssp_auth)
108         {
109                 DEBUG(10,("create_rpc_reply: auth\n"));
110                 if (auth_len != 16)
111                 {
112                         return False;
113                 }
114         }
115
116         prs_init(&l->rhdr , 0x18, 4, 0, False);
117         prs_init(&l->rauth, 1024, 4, 0, False);
118         prs_init(&l->rverf, 0x10, 4, 0, False);
119
120         l->hdr.pkt_type = RPC_RESPONSE; /* mark header as an rpc response */
121
122         /* set up rpc header (fragmentation issues) */
123         if (data_start == 0)
124         {
125                 l->hdr.flags = RPC_FLG_FIRST;
126         }
127         else
128         {
129                 l->hdr.flags = 0;
130         }
131
132         l->hdr_resp.alloc_hint = data_end - data_start; /* calculate remaining data to be sent */
133
134         if (l->hdr_resp.alloc_hint + 0x18 <= l->hdr_ba.bba.max_tsize)
135         {
136                 l->hdr.flags |= RPC_FLG_LAST;
137                 l->hdr.frag_len = l->hdr_resp.alloc_hint + 0x18;
138         }
139         else
140         {
141                 l->hdr.frag_len = l->hdr_ba.bba.max_tsize;
142         }
143
144         if (l->ntlmssp_auth)
145         {
146                 l->hdr_resp.alloc_hint -= auth_len + 8;
147         }
148
149         if (l->ntlmssp_auth)
150         {
151                 data_len = l->hdr.frag_len - auth_len - (auth_verify ? 8 : 0) - 0x18;
152         }
153         else
154         {
155                 data_len = l->hdr.frag_len - 0x18;
156         }
157
158         l->rhdr.data->offset.start = 0;
159         l->rhdr.data->offset.end   = 0x18;
160
161         /* store the header in the data stream */
162         smb_io_rpc_hdr     ("hdr" , &(l->hdr     ), &(l->rhdr), 0);
163         smb_io_rpc_hdr_resp("resp", &(l->hdr_resp), &(l->rhdr), 0);
164
165         /* don't use rdata: use rdata_i instead, which moves... */
166         /* make a pointer to the rdata data, NOT A COPY */
167
168         l->rdata_i.data = NULL;
169         prs_init(&l->rdata_i, 0, l->rdata.align, l->rdata.data->margin, l->rdata.io);
170         data = mem_data(&(l->rdata.data), data_start);
171         mem_create(l->rdata_i.data, data, 0, data_len, 0, False); 
172         l->rdata_i.offset = data_len;
173
174         if (auth_len > 0)
175         {
176                 uint32 crc32 = 0;
177
178                 DEBUG(5,("create_rpc_reply: sign: %s seal: %s data %d auth %d\n",
179                          BOOLSTR(auth_verify), BOOLSTR(auth_seal), data_len, auth_len));
180
181                 if (auth_seal)
182                 {
183                         crc32 = crc32_calc_buffer(data_len, data);
184                         NTLMSSPcalc_p(l, (uchar*)data, data_len);
185                 }
186
187                 if (auth_seal || auth_verify)
188                 {
189                         make_rpc_hdr_auth(&l->auth_info, 0x0a, 0x06, 0x08, (auth_verify ? 1 : 0));
190                         smb_io_rpc_hdr_auth("hdr_auth", &l->auth_info, &l->rauth, 0);
191                 }
192
193                 if (auth_verify)
194                 {
195                         char *auth_data;
196                         l->ntlmssp_seq_num++;
197                         make_rpc_auth_ntlmssp_chk(&l->ntlmssp_chk, NTLMSSP_SIGN_VERSION, crc32, l->ntlmssp_seq_num++);
198                         smb_io_rpc_auth_ntlmssp_chk("auth_sign", &(l->ntlmssp_chk), &l->rverf, 0);
199                         auth_data = mem_data(&l->rverf.data, 4);
200                         NTLMSSPcalc_p(l, (uchar*)auth_data, 12);
201                 }
202         }
203
204         /* set up the data chain */
205         if (l->ntlmssp_auth)
206         {
207                 prs_link(NULL       , &l->rhdr   , &l->rdata_i);
208                 prs_link(&l->rhdr   , &l->rdata_i, &l->rauth  );
209                 prs_link(&l->rdata_i, &l->rauth  , &l->rverf  );
210                 prs_link(&l->rauth  , &l->rverf  , NULL       );
211         }
212         else
213         {
214                 prs_link(NULL    , &l->rhdr   , &l->rdata_i);
215                 prs_link(&l->rhdr, &l->rdata_i, NULL       );
216         }
217
218         return l->rhdr.data != NULL && l->rhdr.offset == 0x18;
219 }
220
221 static BOOL api_pipe_ntlmssp_verify(rpcsrv_struct *l)
222 {
223         uchar *pwd = NULL;
224         uchar null_pwd[16];
225         uchar lm_owf[24];
226         uchar nt_owf[128];
227         size_t lm_owf_len;
228         size_t nt_owf_len;
229         size_t usr_len;
230         size_t dom_len;
231         size_t wks_len;
232         BOOL anonymous = False;
233
234         memset(null_pwd, 0, sizeof(null_pwd));
235
236         DEBUG(5,("api_pipe_ntlmssp_verify: checking user details\n"));
237
238         lm_owf_len = l->ntlmssp_resp.hdr_lm_resp.str_str_len;
239         nt_owf_len = l->ntlmssp_resp.hdr_nt_resp.str_str_len;
240         usr_len    = l->ntlmssp_resp.hdr_usr    .str_str_len;
241         dom_len    = l->ntlmssp_resp.hdr_domain .str_str_len;
242         wks_len    = l->ntlmssp_resp.hdr_wks    .str_str_len;
243
244         if (lm_owf_len == 0 && nt_owf_len == 0 &&
245             usr_len == 0 && dom_len == 0 && wks_len == 0)
246         {
247                 anonymous = True;
248         }
249         else
250         {
251                 if (lm_owf_len == 0) return False;
252                 if (nt_owf_len == 0) return False;
253                 if (l->ntlmssp_resp.hdr_usr    .str_str_len == 0) return False;
254                 if (l->ntlmssp_resp.hdr_domain .str_str_len == 0) return False;
255                 if (l->ntlmssp_resp.hdr_wks    .str_str_len == 0) return False;
256         }
257
258         if (lm_owf_len > sizeof(lm_owf)) return False;
259         if (nt_owf_len > sizeof(nt_owf)) return False;
260
261         memcpy(lm_owf, l->ntlmssp_resp.lm_resp, sizeof(lm_owf));
262         memcpy(nt_owf, l->ntlmssp_resp.nt_resp, sizeof(nt_owf));
263
264 #ifdef DEBUG_PASSWORD
265         DEBUG(100,("lm, nt owfs, chal\n"));
266         dump_data(100, lm_owf, sizeof(lm_owf));
267         dump_data(100, nt_owf, sizeof(nt_owf));
268         dump_data(100, l->ntlmssp_chal.challenge, 8);
269 #endif
270
271         memset(l->user_name, 0, sizeof(l->user_name));
272         memset(l->domain   , 0, sizeof(l->domain   ));
273         memset(l->wks      , 0, sizeof(l->wks      ));
274
275         if (IS_BITS_SET_ALL(l->ntlmssp_chal.neg_flags, NTLMSSP_NEGOTIATE_UNICODE))
276         {
277                 unibuf_to_ascii(l->user_name, l->ntlmssp_resp.user,
278                                 MIN(l->ntlmssp_resp.hdr_usr   .str_str_len/2,
279                                     sizeof(l->user_name)-1));
280                 unibuf_to_ascii(l->domain   , l->ntlmssp_resp.domain,
281                                 MIN(l->ntlmssp_resp.hdr_domain.str_str_len/2,
282                                     sizeof(l->domain   )-1));
283                 unibuf_to_ascii(l->wks      , l->ntlmssp_resp.wks,
284                                 MIN(l->ntlmssp_resp.hdr_wks   .str_str_len/2,
285                                     sizeof(l->wks      )-1));
286         }
287         else
288         {
289                 fstrcpy(l->user_name, l->ntlmssp_resp.user  );
290                 fstrcpy(l->domain   , l->ntlmssp_resp.domain);
291                 fstrcpy(l->wks      , l->ntlmssp_resp.wks   );
292         }
293
294
295         if (anonymous)
296         {
297                 DEBUG(5,("anonymous user session\n"));
298                 mdfour(l->user_sess_key, null_pwd, 16);
299                 pwd = null_pwd;
300                 l->ntlmssp_validated = True;
301         }
302         else
303         {
304                 DEBUG(5,("user: %s domain: %s wks: %s\n", l->user_name, l->domain, l->wks));
305                 become_root(False);
306                 l->ntlmssp_validated = check_domain_security(l->user_name, l->domain,
307                                       (uchar*)l->ntlmssp_chal.challenge,
308                                       lm_owf, lm_owf_len,
309                                       nt_owf, nt_owf_len,
310                                       l->user_sess_key);
311                 unbecome_root(False);
312         }
313
314         if (l->ntlmssp_validated && pwd != NULL)
315         {
316                 uchar p24[24];
317                 NTLMSSPOWFencrypt(pwd, lm_owf, p24);
318                 {
319                         unsigned char j = 0;
320                         int ind;
321
322                         unsigned char k2[8];
323
324                         memcpy(k2, p24, 5);
325                         k2[5] = 0xe5;
326                         k2[6] = 0x38;
327                         k2[7] = 0xb0;
328
329                         for (ind = 0; ind < 256; ind++)
330                         {
331                                 l->ntlmssp_hash[ind] = (unsigned char)ind;
332                         }
333
334                         for( ind = 0; ind < 256; ind++)
335                         {
336                                 unsigned char tc;
337
338                                 j += (l->ntlmssp_hash[ind] + k2[ind%8]);
339
340                                 tc = l->ntlmssp_hash[ind];
341                                 l->ntlmssp_hash[ind] = l->ntlmssp_hash[j];
342                                 l->ntlmssp_hash[j] = tc;
343                         }
344
345                         l->ntlmssp_hash[256] = 0;
346                         l->ntlmssp_hash[257] = 0;
347                 }
348                 l->ntlmssp_seq_num = 0;
349         }
350         else
351         {
352                 l->ntlmssp_validated = False;
353         }
354
355         return l->ntlmssp_validated;
356 }
357
358 static BOOL api_pipe_ntlmssp(rpcsrv_struct *l, prs_struct *pd)
359 {
360         /* receive a negotiate; send a challenge; receive a response */
361         switch (l->auth_verifier.msg_type)
362         {
363                 case NTLMSSP_NEGOTIATE:
364                 {
365                         smb_io_rpc_auth_ntlmssp_neg("", &l->ntlmssp_neg, pd, 0);
366                         break;
367                 }
368                 case NTLMSSP_AUTH:
369                 {
370                         smb_io_rpc_auth_ntlmssp_resp("", &l->ntlmssp_resp, pd, 0);
371                         if (!api_pipe_ntlmssp_verify(l))
372                         {
373                                 pd->offset = 0;
374                         }
375                         break;
376                 }
377                 default:
378                 {
379                         /* NTLMSSP expected: unexpected message type */
380                         DEBUG(3,("unexpected message type in NTLMSSP %d\n",
381                                   l->auth_verifier.msg_type));
382                         return False;
383                 }
384         }
385
386         return (pd->offset != 0);
387 }
388
389 struct api_cmd
390 {
391   char * pipe_clnt_name;
392   char * pipe_srv_name;
393   BOOL (*fn) (rpcsrv_struct *, prs_struct *);
394 };
395
396 static struct api_cmd **api_fd_commands = NULL;
397 uint32 num_cmds = 0;
398
399 static void api_cmd_free(struct api_cmd *item)
400 {
401         if (item != NULL)
402         {
403                 if (item->pipe_clnt_name != NULL)
404                 {
405                         free(item->pipe_clnt_name);
406                 }
407                 if (item->pipe_srv_name != NULL)
408                 {
409                         free(item->pipe_srv_name);
410                 }
411                 free(item);
412         }
413 }
414
415 static struct api_cmd *api_cmd_dup(const struct api_cmd *from)
416 {
417         struct api_cmd *copy = NULL;
418         if (from == NULL)
419         {
420                 return NULL;
421         }
422         copy = (struct api_cmd *) malloc(sizeof(struct api_cmd));
423         if (copy != NULL)
424         {
425                 ZERO_STRUCTP(copy);
426                 if (from->pipe_clnt_name != NULL)
427                 {
428                         copy->pipe_clnt_name  = strdup(from->pipe_clnt_name );
429                 }
430                 if (from->pipe_srv_name != NULL)
431                 {
432                         copy->pipe_srv_name = strdup(from->pipe_srv_name);
433                 }
434                 if (from->fn != NULL)
435                 {
436                         copy->fn    = from->fn;
437                 }
438         }
439         return copy;
440 }
441
442 static void free_api_cmd_array(uint32 num_entries, struct api_cmd **entries)
443 {
444         void(*fn)(void*) = (void(*)(void*))&api_cmd_free;
445         free_void_array(num_entries, (void**)entries, *fn);
446 }
447
448 static struct api_cmd* add_api_cmd_to_array(uint32 *len,
449                                 struct api_cmd ***array,
450                                 const struct api_cmd *name)
451 {
452         void*(*fn)(const void*) = (void*(*)(const void*))&api_cmd_dup;
453         return (struct api_cmd*)add_copy_to_array(len,
454                              (void***)array, (const void*)name, *fn, False);
455                                 
456 }
457
458
459 void close_msrpc_command_processor(void)
460 {
461         free_api_cmd_array(num_cmds, api_fd_commands);
462 }
463
464 void add_msrpc_command_processor(char* pipe_name,
465                                 char* process_name,
466                                 BOOL (*fn) (rpcsrv_struct *, prs_struct *))
467 {
468         struct api_cmd cmd;
469         cmd.pipe_clnt_name = pipe_name;
470         cmd.pipe_srv_name = process_name;
471         cmd.fn = fn;
472
473         add_api_cmd_to_array(&num_cmds, &api_fd_commands, &cmd);
474 }
475
476 static BOOL api_pipe_bind_auth_resp(rpcsrv_struct *l, prs_struct *pd)
477 {
478         DEBUG(5,("api_pipe_bind_auth_resp: decode request. %d\n", __LINE__));
479
480         if (l->hdr.auth_len == 0) return False;
481
482         /* decode the authentication verifier response */
483         smb_io_rpc_hdr_autha("", &l->autha_info, pd, 0);
484         if (pd->offset == 0) return False;
485
486         if (!rpc_hdr_auth_chk(&(l->auth_info))) return False;
487
488         smb_io_rpc_auth_ntlmssp_verifier("", &l->auth_verifier, pd, 0);
489         if (pd->offset == 0) return False;
490
491         if (!rpc_auth_ntlmssp_verifier_chk(&(l->auth_verifier), "NTLMSSP", NTLMSSP_AUTH)) return False;
492         
493         return api_pipe_ntlmssp(l, pd);
494 }
495
496 static BOOL api_pipe_fault_resp(rpcsrv_struct *l, prs_struct *pd, uint32 status)
497 {
498         DEBUG(5,("api_pipe_fault_resp: make response\n"));
499
500         prs_init(&(l->rhdr     ), 0x18, 4, 0, False);
501         prs_init(&(l->rfault   ), 0x8 , 4, 0, False);
502
503         /***/
504         /*** set up the header, response header and fault status ***/
505         /***/
506
507         l->hdr_fault.status   = status;
508         l->hdr_fault.reserved = 0x0;
509
510         l->hdr_resp.alloc_hint   = 0x0;
511         l->hdr_resp.cancel_count = 0x0;
512         l->hdr_resp.reserved     = 0x0;
513
514         make_rpc_hdr(&l->hdr, RPC_FAULT, RPC_FLG_NOCALL | RPC_FLG_FIRST | RPC_FLG_LAST,
515                      l->hdr.call_id,
516                      0x20,
517                      0);
518
519         smb_io_rpc_hdr      ("hdr"  , &(l->hdr      ), &(l->rhdr), 0);
520         smb_io_rpc_hdr_resp ("resp" , &(l->hdr_resp ), &(l->rhdr), 0);
521         smb_io_rpc_hdr_fault("fault", &(l->hdr_fault), &(l->rfault), 0);
522         mem_realloc_data(l->rhdr.data, l->rhdr.offset);
523         mem_realloc_data(l->rfault.data, l->rfault.offset);
524
525         /***/
526         /*** link rpc header and fault together ***/
527         /***/
528
529         prs_link(NULL    , &l->rhdr  , &l->rfault);
530         prs_link(&l->rhdr, &l->rfault, NULL      );
531
532         return True;
533 }
534
535 static BOOL srv_pipe_bind_and_alt_req(rpcsrv_struct *l, prs_struct *pd, 
536                                 const char* ack_pipe_name,
537                                 enum RPC_PKT_TYPE pkt_type)
538 {
539         uint16 assoc_gid;
540
541         l->ntlmssp_auth = False;
542
543         /* decode the bind request */
544         smb_io_rpc_hdr_rb("", &l->hdr_rb, pd, 0);
545
546         if (pd->offset == 0) return False;
547
548         if (l->hdr.auth_len != 0)
549         {
550                 /* decode the authentication verifier */
551                 smb_io_rpc_hdr_auth    ("", &l->auth_info    , pd, 0);
552                 if (pd->offset == 0) return False;
553
554                 l->ntlmssp_auth = l->auth_info.auth_type = 0x0a;
555
556                 if (l->ntlmssp_auth)
557                 {
558                         smb_io_rpc_auth_ntlmssp_verifier("", &l->auth_verifier, pd, 0);
559                         if (pd->offset == 0) return False;
560
561                         l->ntlmssp_auth = strequal(l->auth_verifier.signature, "NTLMSSP");
562                 }
563
564                 if (l->ntlmssp_auth)
565                 {
566                         if (!api_pipe_ntlmssp(l, pd)) return False;
567                 }
568         }
569
570         DEBUG(5,("api_pipe_bind_req: make response. %d\n", __LINE__));
571
572         prs_init(&(l->rdata), 1024, 4, 0, False);
573         prs_init(&(l->rhdr ), 0x18, 4, 0, False);
574         prs_init(&(l->rauth), 1024, 4, 0, False);
575         prs_init(&(l->rverf), 0x08, 4, 0, False);
576         prs_init(&(l->rntlm), 1024, 4, 0, False);
577
578         /***/
579         /*** do the bind ack first ***/
580         /***/
581
582         if (l->ntlmssp_auth)
583         {
584                 assoc_gid = 0x7a77;
585         }
586         else
587         {
588                 assoc_gid = l->hdr_rb.bba.assoc_gid;
589         }
590
591         make_rpc_hdr_ba(&l->hdr_ba,
592                         l->hdr_rb.bba.max_tsize,
593                         l->hdr_rb.bba.max_rsize,
594                         assoc_gid,
595                         ack_pipe_name,
596                         0x1, 0x0, 0x0,
597                         &(l->hdr_rb.transfer));
598
599         smb_io_rpc_hdr_ba("", &l->hdr_ba, &l->rdata, 0);
600         mem_realloc_data(l->rdata.data, l->rdata.offset);
601
602         /***/
603         /*** now the authentication ***/
604         /***/
605
606         if (l->ntlmssp_auth)
607         {
608                 uint8 challenge[8];
609                 generate_random_buffer(challenge, 8, False);
610
611                 /*** authentication info ***/
612
613                 make_rpc_hdr_auth(&l->auth_info, 0x0a, 0x06, 0, 1);
614                 smb_io_rpc_hdr_auth("", &l->auth_info, &l->rverf, 0);
615                 mem_realloc_data(l->rverf.data, l->rverf.offset);
616
617                 /*** NTLMSSP verifier ***/
618
619                 make_rpc_auth_ntlmssp_verifier(&l->auth_verifier,
620                                        "NTLMSSP", NTLMSSP_CHALLENGE);
621                 smb_io_rpc_auth_ntlmssp_verifier("", &l->auth_verifier, &l->rauth, 0);
622                 mem_realloc_data(l->rauth.data, l->rauth.offset);
623
624                 /* NTLMSSP challenge ***/
625
626                 make_rpc_auth_ntlmssp_chal(&l->ntlmssp_chal,
627                                            0x000082b1, challenge);
628                 smb_io_rpc_auth_ntlmssp_chal("", &l->ntlmssp_chal, &l->rntlm, 0);
629                 mem_realloc_data(l->rntlm.data, l->rntlm.offset);
630         }
631
632         /***/
633         /*** then do the header, now we know the length ***/
634         /***/
635
636         make_rpc_hdr(&l->hdr, pkt_type, RPC_FLG_FIRST | RPC_FLG_LAST,
637                      l->hdr.call_id,
638                      l->rdata.offset + l->rverf.offset + l->rauth.offset + l->rntlm.offset + 0x10,
639                      l->rauth.offset + l->rntlm.offset);
640
641         smb_io_rpc_hdr("", &l->hdr, &l->rhdr, 0);
642         mem_realloc_data(l->rhdr.data, l->rdata.offset);
643
644         /***/
645         /*** link rpc header, bind acknowledgment and authentication responses ***/
646         /***/
647
648         if (l->ntlmssp_auth)
649         {
650                 prs_link(NULL     , &l->rhdr , &l->rdata);
651                 prs_link(&l->rhdr , &l->rdata, &l->rverf);
652                 prs_link(&l->rdata, &l->rverf, &l->rauth);
653                 prs_link(&l->rverf, &l->rauth, &l->rntlm);
654                 prs_link(&l->rauth, &l->rntlm, NULL     );
655         }
656         else
657         {
658                 prs_link(NULL    , &l->rhdr , &l->rdata);
659                 prs_link(&l->rhdr, &l->rdata, NULL     );
660         }
661
662         return True;
663 }
664
665 static BOOL api_pipe_bind_and_alt_req(rpcsrv_struct *l, prs_struct *pd,
666                                 const char* name,
667                                 enum RPC_PKT_TYPE pkt_type)
668 {
669         fstring ack_pipe_name;
670         fstring pipe_srv_name;
671         int i = 0;
672
673         DEBUG(5,("api_pipe_bind_req: decode request. %d\n", __LINE__));
674
675         for (i = 0; i < num_cmds; i++)
676         {
677                 if (strequal(api_fd_commands[i]->pipe_clnt_name, name) &&
678                     api_fd_commands[i]->fn != NULL)
679                 {
680                         DEBUG(3,("api_pipe_bind_req: \\PIPE\\%s -> \\PIPE\\%s\n",
681                                    api_fd_commands[i]->pipe_clnt_name,
682                                    api_fd_commands[i]->pipe_srv_name));
683                         fstrcpy(pipe_srv_name, api_fd_commands[i]->pipe_srv_name);
684                         break;
685                 }
686         }
687
688         if (api_fd_commands[i]->fn == NULL) return False;
689
690         switch (pkt_type)
691         {
692                 case RPC_BINDACK:
693                 {
694                         /* name has to be \PIPE\xxxxx */
695                         fstrcpy(ack_pipe_name, "\\PIPE\\");
696                         fstrcat(ack_pipe_name, pipe_srv_name);
697                         break;
698                 }
699                 case RPC_ALTCONTRESP:
700                 {
701                         /* secondary address CAN be NULL
702                          * as the specs says it's ignored.
703                          * It MUST NULL to have the spoolss working.
704                          */
705                         fstrcpy(ack_pipe_name, "");
706                         break;
707                 }
708                 default:
709                 {
710                         return False;
711                 }
712         }
713         return srv_pipe_bind_and_alt_req(l, pd, ack_pipe_name, pkt_type);
714 }
715
716 /*
717  * The RPC Alter-Context call is used only by the spoolss pipe
718  * simply because there is a bug (?) in the MS unmarshalling code
719  * or in the marshalling code. If it's in the later, then Samba
720  * have the same bug.
721  */
722 static BOOL api_pipe_bind_req(rpcsrv_struct *l, prs_struct *pd,
723                                 const char* name)
724 {
725         return api_pipe_bind_and_alt_req(l, pd, name, RPC_BINDACK);
726 }
727
728 static BOOL api_pipe_alt_req(rpcsrv_struct *l, prs_struct *pd,
729                                 const char* name)
730 {
731         return api_pipe_bind_and_alt_req(l, pd, name, RPC_ALTCONTRESP);
732 }
733
734 static BOOL api_pipe_auth_process(rpcsrv_struct *l, prs_struct *pd)
735 {
736         BOOL auth_verify = IS_BITS_SET_ALL(l->ntlmssp_chal.neg_flags, NTLMSSP_NEGOTIATE_SIGN);
737         BOOL auth_seal   = IS_BITS_SET_ALL(l->ntlmssp_chal.neg_flags, NTLMSSP_NEGOTIATE_SEAL);
738         int data_len;
739         int auth_len;
740         uint32 old_offset;
741         uint32 crc32 = 0;
742
743         auth_len = l->hdr.auth_len;
744
745         if (auth_len != 16 && auth_verify)
746         {
747                 return False;
748         }
749
750         data_len = l->hdr.frag_len - auth_len - (auth_verify ? 8 : 0) - 0x18;
751         
752         DEBUG(5,("api_pipe_auth_process: sign: %s seal: %s data %d auth %d\n",
753                  BOOLSTR(auth_verify), BOOLSTR(auth_seal), data_len, auth_len));
754
755         if (auth_seal)
756         {
757                 char *data = mem_data(&pd->data, pd->offset);
758                 DEBUG(5,("api_pipe_auth_process: data %d\n", pd->offset));
759                 NTLMSSPcalc_p(l, (uchar*)data, data_len);
760                 crc32 = crc32_calc_buffer(data_len, data);
761         }
762
763         /*** skip the data, record the offset so we can restore it again */
764         old_offset = pd->offset;
765
766         if (auth_seal || auth_verify)
767         {
768                 pd->offset += data_len;
769                 smb_io_rpc_hdr_auth("hdr_auth", &l->auth_info, pd, 0);
770         }
771
772         if (auth_verify)
773         {
774                 char *req_data = mem_data(&pd->data, pd->offset + 4);
775                 DEBUG(5,("api_pipe_auth_process: auth %d\n", pd->offset + 4));
776                 NTLMSSPcalc_p(l, (uchar*)req_data, 12);
777                 smb_io_rpc_auth_ntlmssp_chk("auth_sign", &(l->ntlmssp_chk), pd, 0);
778
779                 if (!rpc_auth_ntlmssp_chk(&(l->ntlmssp_chk), crc32,
780                                           l->ntlmssp_seq_num))
781                 {
782                         return False;
783                 }
784         }
785
786         pd->offset = old_offset;
787
788         return True;
789 }
790
791 static BOOL api_pipe_request(rpcsrv_struct *l, prs_struct *pd, const char* name)
792 {
793         int i = 0;
794
795         if (l->ntlmssp_auth && l->ntlmssp_validated)
796         {
797                 if (!api_pipe_auth_process(l, pd)) return False;
798
799                 DEBUG(0,("api_pipe_request: **** MUST CALL become_user() HERE **** \n"));
800 #if 0
801                 become_user();
802 #endif
803         }
804
805         for (i = 0; i < num_cmds; i++)
806         {
807                 if (strequal(api_fd_commands[i]->pipe_clnt_name, name) &&
808                     api_fd_commands[i]->fn != NULL)
809                 {
810                         DEBUG(3,("Doing \\PIPE\\%s\n", api_fd_commands[i]->pipe_clnt_name));
811                         return api_fd_commands[i]->fn(l, pd);
812                 }
813         }
814         return False;
815 }
816
817 BOOL rpc_add_to_pdu(prs_struct *ps, const char *data, int len)
818 {
819         int prev_size;
820         int new_size;
821         char *to = NULL;
822
823         ps->offset = 0;
824
825         if (ps->data == NULL)
826         {
827                 DEBUG(10,("rpc_add_to_pdu: new_size: %d\n", len));
828                 prs_init(ps, len, 4, 0, True);
829                 prev_size = 0;
830                 new_size  = len;
831                 if (ps->data == NULL)
832                 {
833                         return False;
834                 }
835         }
836         else
837         {
838                 prev_size = ps->data->data_used;
839                 new_size  = prev_size + len;
840                 DEBUG(10,("rpc_add_to_pdu: prev_size: %d new_size: %d\n",
841                                 prev_size, new_size));
842                 if (!mem_realloc_data(ps->data, new_size))
843                 {
844                         return False;
845                 }
846         }
847
848         DEBUG(10,("ps->data->start: %d\n", ps->data->offset.start));
849         ps->data->offset.start = 0x0;
850
851         to = mem_data(&ps->data, prev_size);
852         if (to == NULL)
853         {
854                 DEBUG(10,("rpc_add_to_pdu: data could not be found\n"));
855                 return False;
856         }
857         if (ps->data->data_used != new_size)
858         {
859                 DEBUG(10,("rpc_add_to_pdu: ERROR: data used %d new_size %d\n",
860                                 ps->data->data_used, new_size));
861                 return False;
862         }
863         memcpy(to, data, len);
864         return True;
865 }
866
867 static BOOL rpc_redir_remote(pipes_struct *p, prs_struct *req, prs_struct *resp)
868 {
869         DEBUG(10,("rpc_redirect\n"));
870
871         if (!msrpc_send_prs(p->m, req))
872         {
873                 DEBUG(2,("msrpc redirect send failed\n"));
874                 return False;
875         }
876         if (!msrpc_receive_prs(p->m, resp))
877         {
878                 DEBUG(2,("msrpc redirect receive failed\n"));
879                 return False;
880         }
881         prs_link(NULL, resp, NULL);
882         prs_debug_out(resp, "redirect", 100);
883         return True;
884 }
885
886 static BOOL rpc_redir_local(rpcsrv_struct *l, prs_struct *req, prs_struct *resp,
887                                 const char* name)
888 {
889         BOOL reply = False;
890
891         if (req->data == NULL) return False;
892
893         /* lkclXXXX still assume that the first complete PDU is always
894            in a single request!!!
895          */
896         /* process the rpc header */
897         req->offset = 0x0;
898         smb_io_rpc_hdr("", &l->hdr, req, 0);
899
900         if (req->offset == 0) return False;
901
902         switch (l->hdr.pkt_type)
903         {
904                 case RPC_BIND   :
905                 {
906                         reply = api_pipe_bind_req(l, req, name);
907                         break;
908                 }
909                 case RPC_ALTCONT:
910                 {
911                         reply = api_pipe_alt_req(l, req, name);
912                         break;
913                 }
914                 case RPC_REQUEST:
915                 {
916                         if (l->ntlmssp_auth && !l->ntlmssp_validated)
917                         {
918                                 /* authentication _was_ requested
919                                    and it failed.  sorry, no deal!
920                                  */
921                                 reply = False;
922                         }
923                         else
924                         {
925                                 /* read the rpc header */
926                                 smb_io_rpc_hdr_req("req", &(l->hdr_req), req, 0);
927                                 reply = api_pipe_request(l, req, name);
928                         }
929                         break;
930                 }
931                 case RPC_BINDRESP: /* not the real name! */
932                 {
933                         reply = api_pipe_bind_auth_resp(l, req);
934                         l->ntlmssp_auth = reply;
935                         break;
936                 }
937         }
938
939         if (!reply)
940         {
941                 reply = api_pipe_fault_resp(l, req, 0x1c010002);
942         }
943         
944         if (reply)
945         {
946                 /* flatten the data into a single pdu */
947                 reply = prs_copy(resp, &l->rhdr);
948         }
949
950         /* delete intermediate data used to set up the pdu.  leave
951            rdata alone because that's got the rest of the data in it */
952         rpcsrv_free_temp(l);
953
954         return reply;
955 }
956
957 BOOL rpc_send_and_rcv_pdu(pipes_struct *p)
958 {
959         DEBUG(10,("rpc_send_and_rcv_pdu\n"));
960
961         if (p->m != NULL)
962         {
963                 return rpc_redir_remote(p, &p->smb_pdu, &p->rsmb_pdu);
964         }
965         else if (p->l != NULL)
966         {
967                 return rpc_redir_local(p->l, &p->smb_pdu, &p->rsmb_pdu,
968                                         p->name);
969         }
970         return False;
971 }
972
973 /*******************************************************************
974  entry point from msrpc to smb.  adds data received to pdu; checks
975  pdu; hands pdu off to msrpc, which gets a pdu back (except in the
976  case of the RPC_BINDCONT pdu).
977  ********************************************************************/
978 BOOL rpc_to_smb(pipes_struct *p, char *data, int len)
979 {
980         BOOL reply = rpc_add_to_pdu(&p->smb_pdu, data, len);
981
982         if (reply && is_complete_pdu(&p->smb_pdu))
983         {
984                 p->smb_pdu.offset = p->smb_pdu.data->data_size;
985                 prs_link(NULL, &p->smb_pdu, NULL);
986                 reply = rpc_send_and_rcv_pdu(p);
987                 mem_free_data(p->smb_pdu.data);
988                 prs_init(&p->smb_pdu, 0, 4, 0, True);
989
990         }
991         return reply;
992 }
993
994 /*******************************************************************
995  receives a netlogon pipe and responds.
996  ********************************************************************/
997 static BOOL api_rpc_command(rpcsrv_struct *l, 
998                                 char *rpc_name, struct api_struct *api_rpc_cmds,
999                                 prs_struct *data)
1000 {
1001         int fn_num;
1002         DEBUG(4,("api_rpc_command: %s op 0x%x - ", rpc_name, l->hdr_req.opnum));
1003
1004         for (fn_num = 0; api_rpc_cmds[fn_num].name; fn_num++)
1005         {
1006                 if (api_rpc_cmds[fn_num].opnum == l->hdr_req.opnum && api_rpc_cmds[fn_num].fn != NULL)
1007                 {
1008                         DEBUG(3,("api_rpc_command: %s\n", api_rpc_cmds[fn_num].name));
1009                         break;
1010                 }
1011         }
1012
1013         if (api_rpc_cmds[fn_num].name == NULL)
1014         {
1015                 DEBUG(4, ("unknown\n"));
1016                 return False;
1017         }
1018
1019         /* start off with 1024 bytes, and a large safety margin too */
1020         prs_init(&l->rdata, 1024, 4, SAFETY_MARGIN, False);
1021
1022         /* do the actual command */
1023         api_rpc_cmds[fn_num].fn(l, data, &(l->rdata));
1024
1025         if (l->rdata.data == NULL || l->rdata.offset == 0)
1026         {
1027                 mem_free_data(l->rdata.data);
1028                 return False;
1029         }
1030
1031         mem_realloc_data(l->rdata.data, l->rdata.offset);
1032
1033         DEBUG(10,("called %s\n", rpc_name));
1034
1035         return True;
1036 }
1037
1038
1039 /*******************************************************************
1040  receives a netlogon pipe and responds.
1041  ********************************************************************/
1042 BOOL api_rpcTNP(rpcsrv_struct *l, char *rpc_name, struct api_struct *api_rpc_cmds,
1043                                 prs_struct *data)
1044 {
1045         if (data == NULL || data->data == NULL)
1046         {
1047                 DEBUG(2,("%s: NULL data received\n", rpc_name));
1048                 return False;
1049         }
1050
1051         /* interpret the command */
1052         if (!api_rpc_command(l, rpc_name, api_rpc_cmds, data))
1053         {
1054                 return False;
1055         }
1056
1057         /* create the rpc header */
1058         if (!create_rpc_reply(l, 0))
1059         {
1060                 return False;
1061         }
1062
1063         return True;
1064 }
1065
1066 BOOL is_complete_pdu(prs_struct *ps)
1067 {
1068         RPC_HDR hdr;
1069         int len = ps->data->data_size;
1070
1071         DEBUG(10,("is_complete_pdu - len %d\n", len));
1072         ps->offset = 0x0;
1073
1074         if (!ps->io)
1075         {
1076                 /* writing.  oops!! */
1077                 DEBUG(4,("is_complete_pdu: write set, not read!\n"));
1078                 return False;
1079         }
1080                 
1081         if (!smb_io_rpc_hdr("hdr", &hdr, ps, 0))
1082         {
1083                 return False;
1084         }
1085         /* check that the fragment length is equal to the data length so far */
1086         return hdr.frag_len == len;
1087 }