delineation between smb and msrpc more marked. smbd now constructs
[tprouty/samba.git] / source / 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         struct smb_passwd *smb_pass = NULL;
235         
236         memset(null_pwd, 0, sizeof(null_pwd));
237
238         DEBUG(5,("api_pipe_ntlmssp_verify: checking user details\n"));
239
240         lm_owf_len = l->ntlmssp_resp.hdr_lm_resp.str_str_len;
241         nt_owf_len = l->ntlmssp_resp.hdr_nt_resp.str_str_len;
242         usr_len    = l->ntlmssp_resp.hdr_usr    .str_str_len;
243         dom_len    = l->ntlmssp_resp.hdr_domain .str_str_len;
244         wks_len    = l->ntlmssp_resp.hdr_wks    .str_str_len;
245
246         if (lm_owf_len == 0 && nt_owf_len == 0 &&
247             usr_len == 0 && dom_len == 0 && wks_len == 0)
248         {
249                 anonymous = True;
250         }
251         else
252         {
253                 if (lm_owf_len == 0) return False;
254                 if (nt_owf_len == 0) return False;
255                 if (l->ntlmssp_resp.hdr_usr    .str_str_len == 0) return False;
256                 if (l->ntlmssp_resp.hdr_domain .str_str_len == 0) return False;
257                 if (l->ntlmssp_resp.hdr_wks    .str_str_len == 0) return False;
258         }
259
260         if (lm_owf_len > sizeof(lm_owf)) return False;
261         if (nt_owf_len > sizeof(nt_owf)) return False;
262
263         memcpy(lm_owf, l->ntlmssp_resp.lm_resp, sizeof(lm_owf));
264         memcpy(nt_owf, l->ntlmssp_resp.nt_resp, sizeof(nt_owf));
265
266 #ifdef DEBUG_PASSWORD
267         DEBUG(100,("lm, nt owfs, chal\n"));
268         dump_data(100, lm_owf, sizeof(lm_owf));
269         dump_data(100, nt_owf, sizeof(nt_owf));
270         dump_data(100, l->ntlmssp_chal.challenge, 8);
271 #endif
272
273         memset(l->user_name, 0, sizeof(l->user_name));
274         memset(l->domain   , 0, sizeof(l->domain   ));
275         memset(l->wks      , 0, sizeof(l->wks      ));
276
277         if (IS_BITS_SET_ALL(l->ntlmssp_chal.neg_flags, NTLMSSP_NEGOTIATE_UNICODE))
278         {
279                 unibuf_to_ascii(l->user_name, l->ntlmssp_resp.user,
280                                 MIN(l->ntlmssp_resp.hdr_usr   .str_str_len/2,
281                                     sizeof(l->user_name)-1));
282                 unibuf_to_ascii(l->domain   , l->ntlmssp_resp.domain,
283                                 MIN(l->ntlmssp_resp.hdr_domain.str_str_len/2,
284                                     sizeof(l->domain   )-1));
285                 unibuf_to_ascii(l->wks      , l->ntlmssp_resp.wks,
286                                 MIN(l->ntlmssp_resp.hdr_wks   .str_str_len/2,
287                                     sizeof(l->wks      )-1));
288         }
289         else
290         {
291                 fstrcpy(l->user_name, l->ntlmssp_resp.user  );
292                 fstrcpy(l->domain   , l->ntlmssp_resp.domain);
293                 fstrcpy(l->wks      , l->ntlmssp_resp.wks   );
294         }
295
296
297         if (anonymous)
298         {
299                 DEBUG(5,("anonymous user session\n"));
300                 mdfour(l->user_sess_key, null_pwd, 16);
301                 pwd = null_pwd;
302                 l->ntlmssp_validated = True;
303         }
304         else
305         {
306                 DEBUG(5,("user: %s domain: %s wks: %s\n", l->user_name, l->domain, l->wks));
307                 become_root(True);
308                 smb_pass = getsmbpwnam(l->user_name);
309                 l->ntlmssp_validated = pass_check_smb(smb_pass, l->domain,
310                                       (uchar*)l->ntlmssp_chal.challenge,
311                                       lm_owf, lm_owf_len,
312                                       nt_owf, nt_owf_len,
313                                       NULL, l->user_sess_key);
314                 unbecome_root(True);
315
316                 if (smb_pass != NULL)
317                 {
318                         pwd = smb_pass->smb_passwd;
319                 }
320         }
321
322         if (l->ntlmssp_validated && pwd != NULL)
323         {
324                 uchar p24[24];
325                 NTLMSSPOWFencrypt(pwd, lm_owf, p24);
326                 {
327                         unsigned char j = 0;
328                         int ind;
329
330                         unsigned char k2[8];
331
332                         memcpy(k2, p24, 5);
333                         k2[5] = 0xe5;
334                         k2[6] = 0x38;
335                         k2[7] = 0xb0;
336
337                         for (ind = 0; ind < 256; ind++)
338                         {
339                                 l->ntlmssp_hash[ind] = (unsigned char)ind;
340                         }
341
342                         for( ind = 0; ind < 256; ind++)
343                         {
344                                 unsigned char tc;
345
346                                 j += (l->ntlmssp_hash[ind] + k2[ind%8]);
347
348                                 tc = l->ntlmssp_hash[ind];
349                                 l->ntlmssp_hash[ind] = l->ntlmssp_hash[j];
350                                 l->ntlmssp_hash[j] = tc;
351                         }
352
353                         l->ntlmssp_hash[256] = 0;
354                         l->ntlmssp_hash[257] = 0;
355                 }
356                 l->ntlmssp_seq_num = 0;
357         }
358         else
359         {
360                 l->ntlmssp_validated = False;
361         }
362
363         return l->ntlmssp_validated;
364 }
365
366 static BOOL api_pipe_ntlmssp(rpcsrv_struct *l, prs_struct *pd)
367 {
368         /* receive a negotiate; send a challenge; receive a response */
369         switch (l->auth_verifier.msg_type)
370         {
371                 case NTLMSSP_NEGOTIATE:
372                 {
373                         smb_io_rpc_auth_ntlmssp_neg("", &l->ntlmssp_neg, pd, 0);
374                         break;
375                 }
376                 case NTLMSSP_AUTH:
377                 {
378                         smb_io_rpc_auth_ntlmssp_resp("", &l->ntlmssp_resp, pd, 0);
379                         if (!api_pipe_ntlmssp_verify(l))
380                         {
381                                 pd->offset = 0;
382                         }
383                         break;
384                 }
385                 default:
386                 {
387                         /* NTLMSSP expected: unexpected message type */
388                         DEBUG(3,("unexpected message type in NTLMSSP %d\n",
389                                   l->auth_verifier.msg_type));
390                         return False;
391                 }
392         }
393
394         return (pd->offset != 0);
395 }
396
397 struct api_cmd
398 {
399   char * pipe_clnt_name;
400   char * pipe_srv_name;
401   BOOL (*fn) (rpcsrv_struct *, prs_struct *);
402 };
403
404 static struct api_cmd **api_fd_commands = NULL;
405 uint32 num_cmds = 0;
406
407 static void api_cmd_free(struct api_cmd *item)
408 {
409         if (item != NULL)
410         {
411                 if (item->pipe_clnt_name != NULL)
412                 {
413                         free(item->pipe_clnt_name);
414                 }
415                 if (item->pipe_srv_name != NULL)
416                 {
417                         free(item->pipe_srv_name);
418                 }
419                 free(item);
420         }
421 }
422
423 static struct api_cmd *api_cmd_dup(const struct api_cmd *from)
424 {
425         struct api_cmd *copy = NULL;
426         if (from == NULL)
427         {
428                 return NULL;
429         }
430         copy = (struct api_cmd *) malloc(sizeof(struct api_cmd));
431         if (copy != NULL)
432         {
433                 ZERO_STRUCTP(copy);
434                 if (from->pipe_clnt_name != NULL)
435                 {
436                         copy->pipe_clnt_name  = strdup(from->pipe_clnt_name );
437                 }
438                 if (from->pipe_srv_name != NULL)
439                 {
440                         copy->pipe_srv_name = strdup(from->pipe_srv_name);
441                 }
442                 if (from->fn != NULL)
443                 {
444                         copy->fn    = from->fn;
445                 }
446         }
447         return copy;
448 }
449
450 static void free_api_cmd_array(uint32 num_entries, struct api_cmd **entries)
451 {
452         void(*fn)(void*) = (void(*)(void*))&api_cmd_free;
453         free_void_array(num_entries, (void**)entries, *fn);
454 }
455
456 static struct api_cmd* add_api_cmd_to_array(uint32 *len,
457                                 struct api_cmd ***array,
458                                 const struct api_cmd *name)
459 {
460         void*(*fn)(const void*) = (void*(*)(const void*))&api_cmd_dup;
461         return (struct api_cmd*)add_copy_to_array(len,
462                              (void***)array, (const void*)name, *fn, False);
463                                 
464 }
465
466 #if 0
467 {
468     { "lsarpc",   "lsass",   api_ntlsa_rpc },
469     { "samr",     "lsass",   api_samr_rpc },
470     { "srvsvc",   "ntsvcs",  api_srvsvc_rpc },
471     { "wkssvc",   "ntsvcs",  api_wkssvc_rpc },
472     { "browser",  "ntsvcs",  api_brs_rpc },
473     { "svcctl",   "ntsvcs",  api_svcctl_rpc },
474     { "NETLOGON", "lsass",   api_netlog_rpc },
475     { "winreg",   "winreg",  api_reg_rpc },
476     { "spoolss",  "spoolss", api_spoolss_rpc },
477     { NULL,       NULL,      NULL }
478 };
479 #endif
480
481 void close_msrpc_command_processor(void)
482 {
483         free_api_cmd_array(num_cmds, api_fd_commands);
484 }
485
486 void add_msrpc_command_processor(char* pipe_name,
487                                 char* process_name,
488                                 BOOL (*fn) (rpcsrv_struct *, prs_struct *))
489 {
490         struct api_cmd cmd;
491         cmd.pipe_clnt_name = pipe_name;
492         cmd.pipe_srv_name = process_name;
493         cmd.fn = fn;
494
495         add_api_cmd_to_array(&num_cmds, &api_fd_commands, &cmd);
496 }
497
498 static BOOL api_pipe_bind_auth_resp(rpcsrv_struct *l, prs_struct *pd)
499 {
500         DEBUG(5,("api_pipe_bind_auth_resp: decode request. %d\n", __LINE__));
501
502         if (l->hdr.auth_len == 0) return False;
503
504         /* decode the authentication verifier response */
505         smb_io_rpc_hdr_autha("", &l->autha_info, pd, 0);
506         if (pd->offset == 0) return False;
507
508         if (!rpc_hdr_auth_chk(&(l->auth_info))) return False;
509
510         smb_io_rpc_auth_ntlmssp_verifier("", &l->auth_verifier, pd, 0);
511         if (pd->offset == 0) return False;
512
513         if (!rpc_auth_ntlmssp_verifier_chk(&(l->auth_verifier), "NTLMSSP", NTLMSSP_AUTH)) return False;
514         
515         return api_pipe_ntlmssp(l, pd);
516 }
517
518 static BOOL api_pipe_fault_resp(rpcsrv_struct *l, prs_struct *pd, uint32 status)
519 {
520         DEBUG(5,("api_pipe_fault_resp: make response\n"));
521
522         prs_init(&(l->rhdr     ), 0x18, 4, 0, False);
523         prs_init(&(l->rfault   ), 0x8 , 4, 0, False);
524
525         /***/
526         /*** set up the header, response header and fault status ***/
527         /***/
528
529         l->hdr_fault.status   = status;
530         l->hdr_fault.reserved = 0x0;
531
532         l->hdr_resp.alloc_hint   = 0x0;
533         l->hdr_resp.cancel_count = 0x0;
534         l->hdr_resp.reserved     = 0x0;
535
536         make_rpc_hdr(&l->hdr, RPC_FAULT, RPC_FLG_NOCALL | RPC_FLG_FIRST | RPC_FLG_LAST,
537                      l->hdr.call_id,
538                      0x20,
539                      0);
540
541         smb_io_rpc_hdr      ("hdr"  , &(l->hdr      ), &(l->rhdr), 0);
542         smb_io_rpc_hdr_resp ("resp" , &(l->hdr_resp ), &(l->rhdr), 0);
543         smb_io_rpc_hdr_fault("fault", &(l->hdr_fault), &(l->rfault), 0);
544         mem_realloc_data(l->rhdr.data, l->rhdr.offset);
545         mem_realloc_data(l->rfault.data, l->rfault.offset);
546
547         /***/
548         /*** link rpc header and fault together ***/
549         /***/
550
551         prs_link(NULL    , &l->rhdr  , &l->rfault);
552         prs_link(&l->rhdr, &l->rfault, NULL      );
553
554         return True;
555 }
556
557 static BOOL srv_pipe_bind_and_alt_req(rpcsrv_struct *l, prs_struct *pd, 
558                                 const char* ack_pipe_name,
559                                 enum RPC_PKT_TYPE pkt_type)
560 {
561         uint16 assoc_gid;
562
563         l->ntlmssp_auth = False;
564
565         /* decode the bind request */
566         smb_io_rpc_hdr_rb("", &l->hdr_rb, pd, 0);
567
568         if (pd->offset == 0) return False;
569
570         if (l->hdr.auth_len != 0)
571         {
572                 /* decode the authentication verifier */
573                 smb_io_rpc_hdr_auth    ("", &l->auth_info    , pd, 0);
574                 if (pd->offset == 0) return False;
575
576                 l->ntlmssp_auth = l->auth_info.auth_type = 0x0a;
577
578                 if (l->ntlmssp_auth)
579                 {
580                         smb_io_rpc_auth_ntlmssp_verifier("", &l->auth_verifier, pd, 0);
581                         if (pd->offset == 0) return False;
582
583                         l->ntlmssp_auth = strequal(l->auth_verifier.signature, "NTLMSSP");
584                 }
585
586                 if (l->ntlmssp_auth)
587                 {
588                         if (!api_pipe_ntlmssp(l, pd)) return False;
589                 }
590         }
591
592         DEBUG(5,("api_pipe_bind_req: make response. %d\n", __LINE__));
593
594         prs_init(&(l->rdata), 1024, 4, 0, False);
595         prs_init(&(l->rhdr ), 0x18, 4, 0, False);
596         prs_init(&(l->rauth), 1024, 4, 0, False);
597         prs_init(&(l->rverf), 0x08, 4, 0, False);
598         prs_init(&(l->rntlm), 1024, 4, 0, False);
599
600         /***/
601         /*** do the bind ack first ***/
602         /***/
603
604         if (l->ntlmssp_auth)
605         {
606                 assoc_gid = 0x7a77;
607         }
608         else
609         {
610                 assoc_gid = l->hdr_rb.bba.assoc_gid;
611         }
612
613         make_rpc_hdr_ba(&l->hdr_ba,
614                         l->hdr_rb.bba.max_tsize,
615                         l->hdr_rb.bba.max_rsize,
616                         assoc_gid,
617                         ack_pipe_name,
618                         0x1, 0x0, 0x0,
619                         &(l->hdr_rb.transfer));
620
621         smb_io_rpc_hdr_ba("", &l->hdr_ba, &l->rdata, 0);
622         mem_realloc_data(l->rdata.data, l->rdata.offset);
623
624         /***/
625         /*** now the authentication ***/
626         /***/
627
628         if (l->ntlmssp_auth)
629         {
630                 uint8 challenge[8];
631                 generate_random_buffer(challenge, 8, False);
632
633                 /*** authentication info ***/
634
635                 make_rpc_hdr_auth(&l->auth_info, 0x0a, 0x06, 0, 1);
636                 smb_io_rpc_hdr_auth("", &l->auth_info, &l->rverf, 0);
637                 mem_realloc_data(l->rverf.data, l->rverf.offset);
638
639                 /*** NTLMSSP verifier ***/
640
641                 make_rpc_auth_ntlmssp_verifier(&l->auth_verifier,
642                                        "NTLMSSP", NTLMSSP_CHALLENGE);
643                 smb_io_rpc_auth_ntlmssp_verifier("", &l->auth_verifier, &l->rauth, 0);
644                 mem_realloc_data(l->rauth.data, l->rauth.offset);
645
646                 /* NTLMSSP challenge ***/
647
648                 make_rpc_auth_ntlmssp_chal(&l->ntlmssp_chal,
649                                            0x000082b1, challenge);
650                 smb_io_rpc_auth_ntlmssp_chal("", &l->ntlmssp_chal, &l->rntlm, 0);
651                 mem_realloc_data(l->rntlm.data, l->rntlm.offset);
652         }
653
654         /***/
655         /*** then do the header, now we know the length ***/
656         /***/
657
658         make_rpc_hdr(&l->hdr, pkt_type, RPC_FLG_FIRST | RPC_FLG_LAST,
659                      l->hdr.call_id,
660                      l->rdata.offset + l->rverf.offset + l->rauth.offset + l->rntlm.offset + 0x10,
661                      l->rauth.offset + l->rntlm.offset);
662
663         smb_io_rpc_hdr("", &l->hdr, &l->rhdr, 0);
664         mem_realloc_data(l->rhdr.data, l->rdata.offset);
665
666         /***/
667         /*** link rpc header, bind acknowledgment and authentication responses ***/
668         /***/
669
670         if (l->ntlmssp_auth)
671         {
672                 prs_link(NULL     , &l->rhdr , &l->rdata);
673                 prs_link(&l->rhdr , &l->rdata, &l->rverf);
674                 prs_link(&l->rdata, &l->rverf, &l->rauth);
675                 prs_link(&l->rverf, &l->rauth, &l->rntlm);
676                 prs_link(&l->rauth, &l->rntlm, NULL     );
677         }
678         else
679         {
680                 prs_link(NULL    , &l->rhdr , &l->rdata);
681                 prs_link(&l->rhdr, &l->rdata, NULL     );
682         }
683
684         return True;
685 }
686
687 static BOOL api_pipe_bind_and_alt_req(rpcsrv_struct *l, prs_struct *pd,
688                                 const char* name,
689                                 enum RPC_PKT_TYPE pkt_type)
690 {
691         fstring ack_pipe_name;
692         fstring pipe_srv_name;
693         int i = 0;
694
695         DEBUG(5,("api_pipe_bind_req: decode request. %d\n", __LINE__));
696
697         for (i = 0; i < num_cmds; i++)
698         {
699                 if (strequal(api_fd_commands[i]->pipe_clnt_name, name) &&
700                     api_fd_commands[i]->fn != NULL)
701                 {
702                         DEBUG(3,("api_pipe_bind_req: \\PIPE\\%s -> \\PIPE\\%s\n",
703                                    api_fd_commands[i]->pipe_clnt_name,
704                                    api_fd_commands[i]->pipe_srv_name));
705                         fstrcpy(pipe_srv_name, api_fd_commands[i]->pipe_srv_name);
706                         break;
707                 }
708         }
709
710         if (api_fd_commands[i]->fn == NULL) return False;
711
712         switch (pkt_type)
713         {
714                 case RPC_BINDACK:
715                 {
716                         /* name has to be \PIPE\xxxxx */
717                         fstrcpy(ack_pipe_name, "\\PIPE\\");
718                         fstrcat(ack_pipe_name, pipe_srv_name);
719                         break;
720                 }
721                 case RPC_ALTCONTRESP:
722                 {
723                         /* secondary address CAN be NULL
724                          * as the specs says it's ignored.
725                          * It MUST NULL to have the spoolss working.
726                          */
727                         fstrcpy(ack_pipe_name, "");
728                         break;
729                 }
730                 default:
731                 {
732                         return False;
733                 }
734         }
735         return srv_pipe_bind_and_alt_req(l, pd, ack_pipe_name, pkt_type);
736 }
737
738 /*
739  * The RPC Alter-Context call is used only by the spoolss pipe
740  * simply because there is a bug (?) in the MS unmarshalling code
741  * or in the marshalling code. If it's in the later, then Samba
742  * have the same bug.
743  */
744 static BOOL api_pipe_bind_req(rpcsrv_struct *l, prs_struct *pd,
745                                 const char* name)
746 {
747         return api_pipe_bind_and_alt_req(l, pd, name, RPC_BINDACK);
748 }
749
750 static BOOL api_pipe_alt_req(rpcsrv_struct *l, prs_struct *pd,
751                                 const char* name)
752 {
753         return api_pipe_bind_and_alt_req(l, pd, name, RPC_ALTCONTRESP);
754 }
755
756 static BOOL api_pipe_auth_process(rpcsrv_struct *l, prs_struct *pd)
757 {
758         BOOL auth_verify = IS_BITS_SET_ALL(l->ntlmssp_chal.neg_flags, NTLMSSP_NEGOTIATE_SIGN);
759         BOOL auth_seal   = IS_BITS_SET_ALL(l->ntlmssp_chal.neg_flags, NTLMSSP_NEGOTIATE_SEAL);
760         int data_len;
761         int auth_len;
762         uint32 old_offset;
763         uint32 crc32 = 0;
764
765         auth_len = l->hdr.auth_len;
766
767         if (auth_len != 16 && auth_verify)
768         {
769                 return False;
770         }
771
772         data_len = l->hdr.frag_len - auth_len - (auth_verify ? 8 : 0) - 0x18;
773         
774         DEBUG(5,("api_pipe_auth_process: sign: %s seal: %s data %d auth %d\n",
775                  BOOLSTR(auth_verify), BOOLSTR(auth_seal), data_len, auth_len));
776
777         if (auth_seal)
778         {
779                 char *data = mem_data(&pd->data, pd->offset);
780                 DEBUG(5,("api_pipe_auth_process: data %d\n", pd->offset));
781                 NTLMSSPcalc_p(l, (uchar*)data, data_len);
782                 crc32 = crc32_calc_buffer(data_len, data);
783         }
784
785         /*** skip the data, record the offset so we can restore it again */
786         old_offset = pd->offset;
787
788         if (auth_seal || auth_verify)
789         {
790                 pd->offset += data_len;
791                 smb_io_rpc_hdr_auth("hdr_auth", &l->auth_info, pd, 0);
792         }
793
794         if (auth_verify)
795         {
796                 char *req_data = mem_data(&pd->data, pd->offset + 4);
797                 DEBUG(5,("api_pipe_auth_process: auth %d\n", pd->offset + 4));
798                 NTLMSSPcalc_p(l, (uchar*)req_data, 12);
799                 smb_io_rpc_auth_ntlmssp_chk("auth_sign", &(l->ntlmssp_chk), pd, 0);
800
801                 if (!rpc_auth_ntlmssp_chk(&(l->ntlmssp_chk), crc32,
802                                           l->ntlmssp_seq_num))
803                 {
804                         return False;
805                 }
806         }
807
808         pd->offset = old_offset;
809
810         return True;
811 }
812
813 static BOOL api_pipe_request(rpcsrv_struct *l, prs_struct *pd, const char* name)
814 {
815         int i = 0;
816
817         if (l->ntlmssp_auth && l->ntlmssp_validated)
818         {
819                 if (!api_pipe_auth_process(l, pd)) return False;
820
821                 DEBUG(0,("api_pipe_request: **** MUST CALL become_user() HERE **** \n"));
822 #if 0
823                 become_user();
824 #endif
825         }
826
827         for (i = 0; i < num_cmds; i++)
828         {
829                 if (strequal(api_fd_commands[i]->pipe_clnt_name, name) &&
830                     api_fd_commands[i]->fn != NULL)
831                 {
832                         DEBUG(3,("Doing \\PIPE\\%s\n", api_fd_commands[i]->pipe_clnt_name));
833                         return api_fd_commands[i]->fn(l, pd);
834                 }
835         }
836         return False;
837 }
838
839 BOOL rpc_add_to_pdu(prs_struct *ps, const char *data, int len)
840 {
841         int prev_size;
842         int new_size;
843         char *to = NULL;
844
845         ps->offset = 0;
846
847         if (ps->data == NULL)
848         {
849                 DEBUG(10,("rpc_add_to_pdu: new_size: %d\n", len));
850                 prs_init(ps, len, 4, 0, True);
851                 prev_size = 0;
852                 new_size  = len;
853                 if (ps->data == NULL)
854                 {
855                         return False;
856                 }
857         }
858         else
859         {
860                 prev_size = ps->data->data_used;
861                 new_size  = prev_size + len;
862                 DEBUG(10,("rpc_add_to_pdu: prev_size: %d new_size: %d\n",
863                                 prev_size, new_size));
864                 if (!mem_realloc_data(ps->data, new_size))
865                 {
866                         return False;
867                 }
868         }
869
870         DEBUG(10,("ps->data->start: %d\n", ps->data->offset.start));
871         ps->data->offset.start = 0x0;
872
873         to = mem_data(&ps->data, prev_size);
874         if (to == NULL)
875         {
876                 DEBUG(10,("rpc_add_to_pdu: data could not be found\n"));
877                 return False;
878         }
879         if (ps->data->data_used != new_size)
880         {
881                 DEBUG(10,("rpc_add_to_pdu: ERROR: data used %d new_size %d\n",
882                                 ps->data->data_used, new_size));
883                 return False;
884         }
885         memcpy(to, data, len);
886         return True;
887 }
888
889 static BOOL rpc_redir_remote(pipes_struct *p, prs_struct *req, prs_struct *resp)
890 {
891         DEBUG(10,("rpc_redirect\n"));
892
893         if (!msrpc_send_prs(p->m, req))
894         {
895                 DEBUG(2,("msrpc redirect send failed\n"));
896                 return False;
897         }
898         if (!msrpc_receive_prs(p->m, resp))
899         {
900                 DEBUG(2,("msrpc redirect receive failed\n"));
901                 return False;
902         }
903         prs_link(NULL, resp, NULL);
904         prs_debug_out(resp, "redirect", 100);
905         return True;
906 }
907
908 static BOOL rpc_redir_local(rpcsrv_struct *l, prs_struct *req, prs_struct *resp,
909                                 const char* name)
910 {
911         BOOL reply = False;
912
913         if (req->data == NULL) return False;
914
915         /* lkclXXXX still assume that the first complete PDU is always
916            in a single request!!!
917          */
918         /* process the rpc header */
919         req->offset = 0x0;
920         smb_io_rpc_hdr("", &l->hdr, req, 0);
921
922         if (req->offset == 0) return False;
923
924         switch (l->hdr.pkt_type)
925         {
926                 case RPC_BIND   :
927                 {
928                         reply = api_pipe_bind_req(l, req, name);
929                         break;
930                 }
931                 case RPC_ALTCONT:
932                 {
933                         reply = api_pipe_alt_req(l, req, name);
934                         break;
935                 }
936                 case RPC_REQUEST:
937                 {
938                         if (l->ntlmssp_auth && !l->ntlmssp_validated)
939                         {
940                                 /* authentication _was_ requested
941                                    and it failed.  sorry, no deal!
942                                  */
943                                 reply = False;
944                         }
945                         else
946                         {
947                                 /* read the rpc header */
948                                 smb_io_rpc_hdr_req("req", &(l->hdr_req), req, 0);
949                                 reply = api_pipe_request(l, req, name);
950                         }
951                         break;
952                 }
953                 case RPC_BINDRESP: /* not the real name! */
954                 {
955                         reply = api_pipe_bind_auth_resp(l, req);
956                         l->ntlmssp_auth = reply;
957                         break;
958                 }
959         }
960
961         if (!reply)
962         {
963                 reply = api_pipe_fault_resp(l, req, 0x1c010002);
964         }
965         
966         if (reply)
967         {
968                 /* flatten the data into a single pdu */
969                 reply = prs_copy(resp, &l->rhdr);
970         }
971
972         /* delete intermediate data used to set up the pdu.  leave
973            rdata alone because that's got the rest of the data in it */
974         rpcsrv_free_temp(l);
975
976         return reply;
977 }
978
979 BOOL rpc_send_and_rcv_pdu(pipes_struct *p)
980 {
981         DEBUG(10,("rpc_send_and_rcv_pdu\n"));
982
983         if (p->m != NULL)
984         {
985                 return rpc_redir_remote(p, &p->smb_pdu, &p->rsmb_pdu);
986         }
987         else if (p->l != NULL)
988         {
989                 return rpc_redir_local(p->l, &p->smb_pdu, &p->rsmb_pdu,
990                                         p->name);
991         }
992         return False;
993 }
994
995 /*******************************************************************
996  entry point from msrpc to smb.  adds data received to pdu; checks
997  pdu; hands pdu off to msrpc, which gets a pdu back (except in the
998  case of the RPC_BINDCONT pdu).
999  ********************************************************************/
1000 BOOL rpc_to_smb(pipes_struct *p, char *data, int len)
1001 {
1002         BOOL reply = rpc_add_to_pdu(&p->smb_pdu, data, len);
1003
1004         if (reply && is_complete_pdu(&p->smb_pdu))
1005         {
1006                 p->smb_pdu.offset = p->smb_pdu.data->data_size;
1007                 prs_link(NULL, &p->smb_pdu, NULL);
1008                 reply = rpc_send_and_rcv_pdu(p);
1009                 mem_free_data(p->smb_pdu.data);
1010                 prs_init(&p->smb_pdu, 0, 4, 0, True);
1011
1012         }
1013         return reply;
1014 }
1015
1016 /*******************************************************************
1017  receives a netlogon pipe and responds.
1018  ********************************************************************/
1019 static BOOL api_rpc_command(rpcsrv_struct *l, 
1020                                 char *rpc_name, struct api_struct *api_rpc_cmds,
1021                                 prs_struct *data)
1022 {
1023         int fn_num;
1024         DEBUG(4,("api_rpc_command: %s op 0x%x - ", rpc_name, l->hdr_req.opnum));
1025
1026         for (fn_num = 0; api_rpc_cmds[fn_num].name; fn_num++)
1027         {
1028                 if (api_rpc_cmds[fn_num].opnum == l->hdr_req.opnum && api_rpc_cmds[fn_num].fn != NULL)
1029                 {
1030                         DEBUG(3,("api_rpc_command: %s\n", api_rpc_cmds[fn_num].name));
1031                         break;
1032                 }
1033         }
1034
1035         if (api_rpc_cmds[fn_num].name == NULL)
1036         {
1037                 DEBUG(4, ("unknown\n"));
1038                 return False;
1039         }
1040
1041         /* start off with 1024 bytes, and a large safety margin too */
1042         prs_init(&l->rdata, 1024, 4, SAFETY_MARGIN, False);
1043
1044         /* do the actual command */
1045         api_rpc_cmds[fn_num].fn(l, data, &(l->rdata));
1046
1047         if (l->rdata.data == NULL || l->rdata.offset == 0)
1048         {
1049                 mem_free_data(l->rdata.data);
1050                 return False;
1051         }
1052
1053         mem_realloc_data(l->rdata.data, l->rdata.offset);
1054
1055         DEBUG(10,("called %s\n", rpc_name));
1056
1057         return True;
1058 }
1059
1060
1061 /*******************************************************************
1062  receives a netlogon pipe and responds.
1063  ********************************************************************/
1064 BOOL api_rpcTNP(rpcsrv_struct *l, char *rpc_name, struct api_struct *api_rpc_cmds,
1065                                 prs_struct *data)
1066 {
1067         if (data == NULL || data->data == NULL)
1068         {
1069                 DEBUG(2,("%s: NULL data received\n", rpc_name));
1070                 return False;
1071         }
1072
1073         /* interpret the command */
1074         if (!api_rpc_command(l, rpc_name, api_rpc_cmds, data))
1075         {
1076                 return False;
1077         }
1078
1079         /* create the rpc header */
1080         if (!create_rpc_reply(l, 0))
1081         {
1082                 return False;
1083         }
1084
1085         return True;
1086 }
1087
1088 BOOL is_complete_pdu(prs_struct *ps)
1089 {
1090         RPC_HDR hdr;
1091         int len = ps->data->data_size;
1092
1093         DEBUG(10,("is_complete_pdu - len %d\n", len));
1094         ps->offset = 0x0;
1095
1096         if (!ps->io)
1097         {
1098                 /* writing.  oops!! */
1099                 DEBUG(4,("is_complete_pdu: write set, not read!\n"));
1100                 return False;
1101         }
1102                 
1103         if (!smb_io_rpc_hdr("hdr", &hdr, ps, 0))
1104         {
1105                 return False;
1106         }
1107         /* check that the fragment length is equal to the data length so far */
1108         return hdr.frag_len == len;
1109 }