Moved some code (NTLMSSPcalc) out of smbdes and inline for paranioa
[kai/samba.git] / source / rpc_server / srv_util.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 /*
47  * A list of the rids of well known BUILTIN and Domain users
48  * and groups.
49  */
50
51 rid_name builtin_alias_rids[] =
52 {  
53     { BUILTIN_ALIAS_RID_ADMINS       , "Administrators" },
54     { BUILTIN_ALIAS_RID_USERS        , "Users" },
55     { BUILTIN_ALIAS_RID_GUESTS       , "Guests" },
56     { BUILTIN_ALIAS_RID_POWER_USERS  , "Power Users" },
57    
58     { BUILTIN_ALIAS_RID_ACCOUNT_OPS  , "Account Operators" },
59     { BUILTIN_ALIAS_RID_SYSTEM_OPS   , "System Operators" },
60     { BUILTIN_ALIAS_RID_PRINT_OPS    , "Print Operators" },
61     { BUILTIN_ALIAS_RID_BACKUP_OPS   , "Backup Operators" },
62     { BUILTIN_ALIAS_RID_REPLICATOR   , "Replicator" },
63     { 0                             , NULL }
64 };
65
66 /* array lookup of well-known Domain RID users. */
67 rid_name domain_user_rids[] =
68 {  
69     { DOMAIN_USER_RID_ADMIN         , "Administrator" },
70     { DOMAIN_USER_RID_GUEST         , "Guest" },
71     { 0                             , NULL }
72 };
73
74 /* array lookup of well-known Domain RID groups. */
75 rid_name domain_group_rids[] =
76 {  
77     { DOMAIN_GROUP_RID_ADMINS       , "Domain Admins" },
78     { DOMAIN_GROUP_RID_USERS        , "Domain Users" },
79     { DOMAIN_GROUP_RID_GUESTS       , "Domain Guests" },
80     { 0                             , NULL }
81 };
82
83 int make_dom_gids(char *gids_str, DOM_GID **ppgids)
84 {
85   char *ptr;
86   pstring s2;
87   int count;
88   DOM_GID *gids;
89
90   *ppgids = NULL;
91
92   DEBUG(4,("make_dom_gids: %s\n", gids_str));
93
94   if (gids_str == NULL || *gids_str == 0)
95     return 0;
96
97   for (count = 0, ptr = gids_str; 
98        next_token(&ptr, s2, NULL, sizeof(s2)); 
99        count++)
100     ;
101
102   gids = (DOM_GID *)malloc( sizeof(DOM_GID) * count );
103   if(!gids)
104   {
105     DEBUG(0,("make_dom_gids: malloc fail !\n"));
106     return 0;
107   }
108
109   for (count = 0, ptr = gids_str; 
110        next_token(&ptr, s2, NULL, sizeof(s2)) && 
111                count < LSA_MAX_GROUPS; 
112        count++) 
113   {
114     /* the entries are of the form GID/ATTR, ATTR being optional.*/
115     char *attr;
116     uint32 rid = 0;
117     int i;
118
119     attr = strchr(s2,'/');
120     if (attr)
121       *attr++ = 0;
122
123     if (!attr || !*attr)
124       attr = "7"; /* default value for attribute is 7 */
125
126     /* look up the RID string and see if we can turn it into a rid number */
127     for (i = 0; builtin_alias_rids[i].name != NULL; i++)
128     {
129       if (strequal(builtin_alias_rids[i].name, s2))
130       {
131         rid = builtin_alias_rids[i].rid;
132         break;
133       }
134     }
135
136     if (rid == 0)
137       rid = atoi(s2);
138
139     if (rid == 0)
140     {
141       DEBUG(1,("make_dom_gids: unknown well-known alias RID %s/%s\n", s2, attr));
142       count--;
143     }
144     else
145     {
146       gids[count].g_rid = rid;
147       gids[count].attr  = atoi(attr);
148
149       DEBUG(5,("group id: %d attr: %d\n", gids[count].g_rid, gids[count].attr));
150     }
151   }
152
153   *ppgids = gids;
154   return count;
155 }
156
157 static void NTLMSSPcalc_p( pipes_struct *p, unsigned char *data, int len)
158 {
159     unsigned char *hash = p->ntlmssp_hash;
160     unsigned char index_i = hash[256];
161     unsigned char index_j = hash[257];
162     int ind;
163
164     for( ind = 0; ind < len; ind++)
165     {
166         unsigned char tc;
167         unsigned char t;
168
169         index_i++;
170         index_j += hash[index_i];
171
172         tc = hash[index_i];
173         hash[index_i] = hash[index_j];
174         hash[index_j] = tc;
175
176         t = hash[index_i] + hash[index_j];
177         data[ind] = data[ind] ^ hash[t];
178     }
179
180     hash[256] = index_i;
181     hash[257] = index_j;
182 }
183
184 /*******************************************************************
185  turns a DCE/RPC request into a DCE/RPC reply
186
187  this is where the data really should be split up into an array of
188  headers and data sections.
189
190  ********************************************************************/
191 BOOL create_rpc_reply(pipes_struct *p,
192                                 uint32 data_start, uint32 data_end)
193 {
194         char *data;
195         BOOL auth_verify = IS_BITS_SET_ALL(p->ntlmssp_chal.neg_flags, NTLMSSP_NEGOTIATE_SIGN);
196         BOOL auth_seal   = IS_BITS_SET_ALL(p->ntlmssp_chal.neg_flags, NTLMSSP_NEGOTIATE_SEAL);
197         uint32 data_len;
198         uint32 auth_len;
199
200         DEBUG(5,("create_rpc_reply: data_start: %d data_end: %d max_tsize: %d\n",
201                   data_start, data_end, p->hdr_ba.bba.max_tsize));
202
203         auth_len = p->hdr.auth_len;
204
205         if (p->ntlmssp_auth)
206         {
207                 DEBUG(10,("create_rpc_reply: auth\n"));
208                 if (auth_len != 16)
209                 {
210                         return False;
211                 }
212         }
213
214         prs_init(&p->rhdr , 0x18, 4, 0, False);
215         prs_init(&p->rauth, 1024, 4, 0, False);
216         prs_init(&p->rverf, 0x08, 4, 0, False);
217
218         p->hdr.pkt_type = RPC_RESPONSE; /* mark header as an rpc response */
219
220         /* set up rpc header (fragmentation issues) */
221         if (data_start == 0)
222         {
223                 p->hdr.flags = RPC_FLG_FIRST;
224         }
225         else
226         {
227                 p->hdr.flags = 0;
228         }
229
230         p->hdr_resp.alloc_hint = data_end - data_start; /* calculate remaining data to be sent */
231
232         if (p->hdr_resp.alloc_hint + 0x18 <= p->hdr_ba.bba.max_tsize)
233         {
234                 p->hdr.flags |= RPC_FLG_LAST;
235                 p->hdr.frag_len = p->hdr_resp.alloc_hint + 0x18;
236         }
237         else
238         {
239                 p->hdr.frag_len = p->hdr_ba.bba.max_tsize;
240         }
241
242         if (p->ntlmssp_auth)
243         {
244                 p->hdr_resp.alloc_hint -= auth_len + 8;
245         }
246
247         if (p->ntlmssp_auth)
248         {
249                 data_len = p->hdr.frag_len - auth_len - (auth_verify ? 8 : 0) - 0x18;
250         }
251         else
252         {
253                 data_len = p->hdr.frag_len - 0x18;
254         }
255
256         p->rhdr.data->offset.start = 0;
257         p->rhdr.data->offset.end   = 0x18;
258
259         /* store the header in the data stream */
260         smb_io_rpc_hdr     ("hdr" , &(p->hdr     ), &(p->rhdr), 0);
261         smb_io_rpc_hdr_resp("resp", &(p->hdr_resp), &(p->rhdr), 0);
262
263         /* don't use rdata: use rdata_i instead, which moves... */
264         /* make a pointer to the rdata data, NOT A COPY */
265
266         p->rdata_i.data = NULL;
267         prs_init(&p->rdata_i, 0, p->rdata.align, p->rdata.data->margin, p->rdata.io);
268         data = mem_data(&(p->rdata.data), data_start);
269         mem_create(p->rdata_i.data, data, 0, data_len, 0, False); 
270         p->rdata_i.offset = data_len;
271
272         if (auth_len > 0)
273         {
274                 uint32 crc32;
275
276                 DEBUG(5,("create_rpc_reply: sign: %s seal: %s data %d auth %d\n",
277                          BOOLSTR(auth_verify), BOOLSTR(auth_seal), data_len, auth_len));
278
279                 if (auth_seal)
280                 {
281                         crc32 = crc32_calc_buffer(data_len, data);
282                         NTLMSSPcalc_p(p, (uchar*)data, data_len);
283                 }
284
285                 if (auth_seal || auth_verify)
286                 {
287                         make_rpc_hdr_auth(&p->auth_info, 0x0a, 0x06, 0x08, (auth_verify ? 1 : 0));
288                         smb_io_rpc_hdr_auth("hdr_auth", &p->auth_info, &p->rauth, 0);
289                 }
290
291                 if (auth_verify)
292                 {
293                         char *auth_data;
294                         p->ntlmssp_seq_num++;
295                         make_rpc_auth_ntlmssp_chk(&p->ntlmssp_chk, NTLMSSP_SIGN_VERSION, crc32, p->ntlmssp_seq_num++);
296                         smb_io_rpc_auth_ntlmssp_chk("auth_sign", &(p->ntlmssp_chk), &p->rverf, 0);
297                         auth_data = mem_data(&p->rverf.data, 4);
298                         NTLMSSPcalc_p(p, (uchar*)auth_data, 12);
299                 }
300         }
301
302         /* set up the data chain */
303         if (p->ntlmssp_auth)
304         {
305                 prs_link(NULL       , &p->rhdr   , &p->rdata_i);
306                 prs_link(&p->rhdr   , &p->rdata_i, &p->rauth  );
307                 prs_link(&p->rdata_i, &p->rauth  , &p->rverf  );
308                 prs_link(&p->rauth  , &p->rverf  , NULL       );
309         }
310         else
311         {
312                 prs_link(NULL    , &p->rhdr   , &p->rdata_i);
313                 prs_link(&p->rhdr, &p->rdata_i, NULL       );
314         }
315
316         /* indicate to subsequent data reads where we are up to */
317         p->frag_len_left   = p->hdr.frag_len - p->file_offset;
318         p->next_frag_start = p->hdr.frag_len; 
319         
320         return p->rhdr.data != NULL && p->rhdr.offset == 0x18;
321 }
322
323 static BOOL api_pipe_ntlmssp_verify(pipes_struct *p)
324 {
325         uchar lm_owf[24];
326         uchar nt_owf[24];
327         struct smb_passwd *smb_pass = NULL;
328         
329         DEBUG(5,("api_pipe_ntlmssp_verify: checking user details\n"));
330
331         if (p->ntlmssp_resp.hdr_lm_resp.str_str_len == 0) return False;
332         if (p->ntlmssp_resp.hdr_nt_resp.str_str_len == 0) return False;
333         if (p->ntlmssp_resp.hdr_usr    .str_str_len == 0) return False;
334         if (p->ntlmssp_resp.hdr_domain .str_str_len == 0) return False;
335         if (p->ntlmssp_resp.hdr_wks    .str_str_len == 0) return False;
336
337         memset(p->user_name, 0, sizeof(p->user_name));
338         memset(p->domain   , 0, sizeof(p->domain   ));
339         memset(p->wks      , 0, sizeof(p->wks      ));
340
341         if (IS_BITS_SET_ALL(p->ntlmssp_chal.neg_flags, NTLMSSP_NEGOTIATE_UNICODE))
342         {
343                 fstrcpy(p->user_name, unistrn2((uint16*)p->ntlmssp_resp.user  , p->ntlmssp_resp.hdr_usr   .str_str_len/2));
344                 fstrcpy(p->domain   , unistrn2((uint16*)p->ntlmssp_resp.domain, p->ntlmssp_resp.hdr_domain.str_str_len/2));
345                 fstrcpy(p->wks      , unistrn2((uint16*)p->ntlmssp_resp.wks   , p->ntlmssp_resp.hdr_wks   .str_str_len/2));
346         }
347         else
348         {
349                 fstrcpy(p->user_name, p->ntlmssp_resp.user  );
350                 fstrcpy(p->domain   , p->ntlmssp_resp.domain);
351                 fstrcpy(p->wks      , p->ntlmssp_resp.wks   );
352         }
353
354         DEBUG(5,("user: %s domain: %s wks: %s\n", p->user_name, p->domain, p->wks));
355
356         memcpy(lm_owf, p->ntlmssp_resp.lm_resp, sizeof(lm_owf));
357         memcpy(nt_owf, p->ntlmssp_resp.nt_resp, sizeof(nt_owf));
358
359 #ifdef DEBUG_PASSWORD
360         DEBUG(100,("lm, nt owfs, chal\n"));
361         dump_data(100, lm_owf, sizeof(lm_owf));
362         dump_data(100, nt_owf, sizeof(nt_owf));
363         dump_data(100, p->ntlmssp_chal.challenge, 8);
364 #endif
365         become_root(True);
366         p->ntlmssp_validated = pass_check_smb(p->user_name, p->domain,
367                               (uchar*)p->ntlmssp_chal.challenge,
368                               lm_owf, nt_owf, NULL);
369         smb_pass = getsmbpwnam(p->user_name);
370         unbecome_root(True);
371
372         if (p->ntlmssp_validated && smb_pass != NULL && smb_pass->smb_passwd)
373         {
374                 uchar p24[24];
375                 NTLMSSPOWFencrypt(smb_pass->smb_passwd, lm_owf, p24);
376                 {
377                         unsigned char j = 0;
378                         int ind;
379
380                         unsigned char k2[8];
381
382                         memcpy(k2, p24, 5);
383                         k2[5] = 0xe5;
384                         k2[6] = 0x38;
385                         k2[7] = 0xb0;
386
387                         for (ind = 0; ind < 256; ind++)
388                         {
389                                 p->ntlmssp_hash[ind] = (unsigned char)ind;
390                         }
391
392                         for( ind = 0; ind < 256; ind++)
393                         {
394                                 unsigned char tc;
395
396                                 j += (p->ntlmssp_hash[ind] + k2[ind%8]);
397
398                                 tc = p->ntlmssp_hash[ind];
399                                 p->ntlmssp_hash[ind] = p->ntlmssp_hash[j];
400                                 p->ntlmssp_hash[j] = tc;
401                         }
402
403                         p->ntlmssp_hash[256] = 0;
404                         p->ntlmssp_hash[257] = 0;
405                 }
406 /*              NTLMSSPhash(p->ntlmssp_hash, p24); */
407                 p->ntlmssp_seq_num = 0;
408         }
409         else
410         {
411                 p->ntlmssp_validated = False;
412         }
413
414         return p->ntlmssp_validated;
415 }
416
417 static BOOL api_pipe_ntlmssp(pipes_struct *p, prs_struct *pd)
418 {
419         /* receive a negotiate; send a challenge; receive a response */
420         switch (p->auth_verifier.msg_type)
421         {
422                 case NTLMSSP_NEGOTIATE:
423                 {
424                         smb_io_rpc_auth_ntlmssp_neg("", &p->ntlmssp_neg, pd, 0);
425                         break;
426                 }
427                 case NTLMSSP_AUTH:
428                 {
429                         smb_io_rpc_auth_ntlmssp_resp("", &p->ntlmssp_resp, pd, 0);
430                         if (!api_pipe_ntlmssp_verify(p))
431                         {
432                                 pd->offset = 0;
433                         }
434                         break;
435                 }
436                 default:
437                 {
438                         /* NTLMSSP expected: unexpected message type */
439                         DEBUG(3,("unexpected message type in NTLMSSP %d\n",
440                                   p->auth_verifier.msg_type));
441                         return False;
442                 }
443         }
444
445         return (pd->offset != 0);
446 }
447
448 struct api_cmd
449 {
450   char * pipe_clnt_name;
451   char * pipe_srv_name;
452   BOOL (*fn) (pipes_struct *, prs_struct *);
453 };
454
455 static struct api_cmd api_fd_commands[] =
456 {
457     { "lsarpc",   "lsass",   api_ntlsa_rpc },
458     { "samr",     "lsass",   api_samr_rpc },
459     { "srvsvc",   "ntsvcs",  api_srvsvc_rpc },
460     { "wkssvc",   "ntsvcs",  api_wkssvc_rpc },
461     { "NETLOGON", "lsass",   api_netlog_rpc },
462     { "winreg",   "winreg",  api_reg_rpc },
463     { NULL,       NULL,      NULL }
464 };
465
466 static BOOL api_pipe_bind_auth_resp(pipes_struct *p, prs_struct *pd)
467 {
468         DEBUG(5,("api_pipe_bind_auth_resp: decode request. %d\n", __LINE__));
469
470         if (p->hdr.auth_len == 0) return False;
471
472         /* decode the authentication verifier response */
473         smb_io_rpc_hdr_autha("", &p->autha_info, pd, 0);
474         if (pd->offset == 0) return False;
475
476         if (!rpc_hdr_auth_chk(&(p->auth_info))) return False;
477
478         smb_io_rpc_auth_verifier("", &p->auth_verifier, pd, 0);
479         if (pd->offset == 0) return False;
480
481         if (!rpc_auth_verifier_chk(&(p->auth_verifier), "NTLMSSP", NTLMSSP_AUTH)) return False;
482         
483         return api_pipe_ntlmssp(p, pd);
484 }
485
486 static BOOL api_pipe_bind_req(pipes_struct *p, prs_struct *pd)
487 {
488         uint16 assoc_gid;
489         fstring ack_pipe_name;
490         int i = 0;
491
492         p->ntlmssp_auth = False;
493
494         DEBUG(5,("api_pipe_bind_req: decode request. %d\n", __LINE__));
495
496         for (i = 0; api_fd_commands[i].pipe_clnt_name; i++)
497         {
498                 if (strequal(api_fd_commands[i].pipe_clnt_name, p->name) &&
499                     api_fd_commands[i].fn != NULL)
500                 {
501                         DEBUG(3,("api_pipe_bind_req: \\PIPE\\%s -> \\PIPE\\%s\n",
502                                    api_fd_commands[i].pipe_clnt_name,
503                                    api_fd_commands[i].pipe_srv_name));
504                         fstrcpy(p->pipe_srv_name, api_fd_commands[i].pipe_srv_name);
505                         break;
506                 }
507         }
508
509         if (api_fd_commands[i].fn == NULL) return False;
510
511         /* decode the bind request */
512         smb_io_rpc_hdr_rb("", &p->hdr_rb, pd, 0);
513
514         if (pd->offset == 0) return False;
515
516         if (p->hdr.auth_len != 0)
517         {
518                 /* decode the authentication verifier */
519                 smb_io_rpc_hdr_auth    ("", &p->auth_info    , pd, 0);
520                 if (pd->offset == 0) return False;
521
522                 p->ntlmssp_auth = p->auth_info.auth_type = 0x0a;
523
524                 if (p->ntlmssp_auth)
525                 {
526                         smb_io_rpc_auth_verifier("", &p->auth_verifier, pd, 0);
527                         if (pd->offset == 0) return False;
528
529                         p->ntlmssp_auth = strequal(p->auth_verifier.signature, "NTLMSSP");
530                 }
531
532                 if (p->ntlmssp_auth)
533                 {
534                         if (!api_pipe_ntlmssp(p, pd)) return False;
535                 }
536         }
537
538         /* name has to be \PIPE\xxxxx */
539         fstrcpy(ack_pipe_name, "\\PIPE\\");
540         fstrcat(ack_pipe_name, p->pipe_srv_name);
541
542         DEBUG(5,("api_pipe_bind_req: make response. %d\n", __LINE__));
543
544         prs_init(&(p->rdata), 1024, 4, 0, False);
545         prs_init(&(p->rhdr ), 0x18, 4, 0, False);
546         prs_init(&(p->rauth), 1024, 4, 0, False);
547         prs_init(&(p->rverf), 0x08, 4, 0, False);
548         prs_init(&(p->rntlm), 1024, 4, 0, False);
549
550         /***/
551         /*** do the bind ack first ***/
552         /***/
553
554         if (p->ntlmssp_auth)
555         {
556                 assoc_gid = 0x7a77;
557         }
558         else
559         {
560                 assoc_gid = p->hdr_rb.bba.assoc_gid;
561         }
562
563         make_rpc_hdr_ba(&p->hdr_ba,
564                         p->hdr_rb.bba.max_tsize,
565                         p->hdr_rb.bba.max_rsize,
566                         assoc_gid,
567                         ack_pipe_name,
568                         0x1, 0x0, 0x0,
569                         &(p->hdr_rb.transfer));
570
571         smb_io_rpc_hdr_ba("", &p->hdr_ba, &p->rdata, 0);
572         mem_realloc_data(p->rdata.data, p->rdata.offset);
573
574         /***/
575         /*** now the authentication ***/
576         /***/
577
578         if (p->ntlmssp_auth)
579         {
580                 uint8 challenge[8];
581                 generate_random_buffer(challenge, 8, False);
582
583                 /*** authentication info ***/
584
585                 make_rpc_hdr_auth(&p->auth_info, 0x0a, 0x06, 0, 1);
586                 smb_io_rpc_hdr_auth("", &p->auth_info, &p->rverf, 0);
587                 mem_realloc_data(p->rverf.data, p->rverf.offset);
588
589                 /*** NTLMSSP verifier ***/
590
591                 make_rpc_auth_verifier(&p->auth_verifier,
592                                        "NTLMSSP", NTLMSSP_CHALLENGE);
593                 smb_io_rpc_auth_verifier("", &p->auth_verifier, &p->rauth, 0);
594                 mem_realloc_data(p->rauth.data, p->rauth.offset);
595
596                 /* NTLMSSP challenge ***/
597
598                 make_rpc_auth_ntlmssp_chal(&p->ntlmssp_chal,
599                                            0x000082b1, challenge);
600                 smb_io_rpc_auth_ntlmssp_chal("", &p->ntlmssp_chal, &p->rntlm, 0);
601                 mem_realloc_data(p->rntlm.data, p->rntlm.offset);
602         }
603
604         /***/
605         /*** then do the header, now we know the length ***/
606         /***/
607
608         make_rpc_hdr(&p->hdr, RPC_BINDACK, RPC_FLG_FIRST | RPC_FLG_LAST,
609                      p->hdr.call_id,
610                      p->rdata.offset + p->rverf.offset + p->rauth.offset + p->rntlm.offset + 0x10,
611                      p->rauth.offset + p->rntlm.offset);
612
613         smb_io_rpc_hdr("", &p->hdr, &p->rhdr, 0);
614         mem_realloc_data(p->rhdr.data, p->rdata.offset);
615
616         /***/
617         /*** link rpc header, bind acknowledgment and authentication responses ***/
618         /***/
619
620         if (p->ntlmssp_auth)
621         {
622                 prs_link(NULL     , &p->rhdr , &p->rdata);
623                 prs_link(&p->rhdr , &p->rdata, &p->rverf);
624                 prs_link(&p->rdata, &p->rverf, &p->rauth);
625                 prs_link(&p->rverf, &p->rauth, &p->rntlm);
626                 prs_link(&p->rauth, &p->rntlm, NULL     );
627         }
628         else
629         {
630                 prs_link(NULL    , &p->rhdr , &p->rdata);
631                 prs_link(&p->rhdr, &p->rdata, NULL     );
632         }
633
634         return True;
635 }
636
637
638 static BOOL api_pipe_auth_process(pipes_struct *p, prs_struct *pd)
639 {
640         BOOL auth_verify = IS_BITS_SET_ALL(p->ntlmssp_chal.neg_flags, NTLMSSP_NEGOTIATE_SIGN);
641         BOOL auth_seal   = IS_BITS_SET_ALL(p->ntlmssp_chal.neg_flags, NTLMSSP_NEGOTIATE_SEAL);
642         int data_len;
643         int auth_len;
644         uint32 old_offset;
645         uint32 crc32;
646
647         auth_len = p->hdr.auth_len;
648
649         if (auth_len != 16 && auth_verify)
650         {
651                 return False;
652         }
653
654         data_len = p->hdr.frag_len - auth_len - (auth_verify ? 8 : 0) - 0x18;
655         
656         DEBUG(5,("api_pipe_auth_process: sign: %s seal: %s data %d auth %d\n",
657                  BOOLSTR(auth_verify), BOOLSTR(auth_seal), data_len, auth_len));
658
659         if (auth_seal)
660         {
661                 char *data = mem_data(&pd->data, pd->offset);
662                 DEBUG(5,("api_pipe_auth_process: data %d\n", pd->offset));
663                 NTLMSSPcalc_p(p, (uchar*)data, data_len);
664                 crc32 = crc32_calc_buffer(data_len, data);
665         }
666
667         /*** skip the data, record the offset so we can restore it again */
668         old_offset = pd->offset;
669
670         if (auth_seal || auth_verify)
671         {
672                 pd->offset += data_len;
673                 smb_io_rpc_hdr_auth("hdr_auth", &p->auth_info, pd, 0);
674         }
675
676         if (auth_verify)
677         {
678                 char *req_data = mem_data(&pd->data, pd->offset + 4);
679                 DEBUG(5,("api_pipe_auth_process: auth %d\n", pd->offset + 4));
680                 NTLMSSPcalc_p(p, (uchar*)req_data, 12);
681                 smb_io_rpc_auth_ntlmssp_chk("auth_sign", &(p->ntlmssp_chk), pd, 0);
682
683                 if (!rpc_auth_ntlmssp_chk(&(p->ntlmssp_chk), crc32,
684                                           p->ntlmssp_seq_num))
685                 {
686                         return False;
687                 }
688         }
689
690         pd->offset = old_offset;
691
692         return True;
693 }
694
695 static BOOL api_pipe_request(pipes_struct *p, prs_struct *pd)
696 {
697         int i = 0;
698
699         if (p->ntlmssp_auth && p->ntlmssp_validated)
700         {
701                 if (!api_pipe_auth_process(p, pd)) return False;
702
703                 DEBUG(0,("api_pipe_request: **** MUST CALL become_user() HERE **** \n"));
704 #if 0
705                 become_user();
706 #endif
707         }
708
709         for (i = 0; api_fd_commands[i].pipe_clnt_name; i++)
710         {
711                 if (strequal(api_fd_commands[i].pipe_clnt_name, p->name) &&
712                     api_fd_commands[i].fn != NULL)
713                 {
714                         DEBUG(3,("Doing \\PIPE\\%s\n", api_fd_commands[i].pipe_clnt_name));
715                         return api_fd_commands[i].fn(p, pd);
716                 }
717         }
718         return False;
719 }
720
721 BOOL rpc_command(pipes_struct *p, prs_struct *pd)
722 {
723         BOOL reply = False;
724         if (pd->data == NULL) return False;
725
726         /* process the rpc header */
727         smb_io_rpc_hdr("", &p->hdr, pd, 0);
728
729         if (pd->offset == 0) return False;
730
731         switch (p->hdr.pkt_type)
732         {
733                 case RPC_BIND   :
734                 {
735                         reply = api_pipe_bind_req(p, pd);
736                         break;
737                 }
738                 case RPC_REQUEST:
739                 {
740                         if (p->ntlmssp_auth && !p->ntlmssp_validated)
741                         {
742                                 /* authentication _was_ requested
743                                    and it failed.  sorry, no deal!
744                                  */
745                                 reply = False;
746                         }
747                         else
748                         {
749                                 /* read the rpc header */
750                                 smb_io_rpc_hdr_req("req", &(p->hdr_req), pd, 0);
751                                 reply = api_pipe_request(p, pd);
752                         }
753                         break;
754                 }
755                 case RPC_BINDRESP: /* not the real name! */
756                 {
757                         reply = api_pipe_bind_auth_resp(p, pd);
758                         p->ntlmssp_auth = reply;
759                         break;
760                 }
761         }
762
763         if (!reply)
764         {
765                 DEBUG(3,("rpc_command: DCE/RPC fault should be sent here\n"));
766         }
767
768         return reply;
769 }
770
771
772 /*******************************************************************
773  receives a netlogon pipe and responds.
774  ********************************************************************/
775 static BOOL api_rpc_command(pipes_struct *p, 
776                                 char *rpc_name, struct api_struct *api_rpc_cmds,
777                                 prs_struct *data)
778 {
779         int fn_num;
780         DEBUG(4,("api_rpc_command: %s op 0x%x - ", rpc_name, p->hdr_req.opnum));
781
782         for (fn_num = 0; api_rpc_cmds[fn_num].name; fn_num++)
783         {
784                 if (api_rpc_cmds[fn_num].opnum == p->hdr_req.opnum && api_rpc_cmds[fn_num].fn != NULL)
785                 {
786                         DEBUG(3,("api_rpc_command: %s\n", api_rpc_cmds[fn_num].name));
787                         break;
788                 }
789         }
790
791         if (api_rpc_cmds[fn_num].name == NULL)
792         {
793                 DEBUG(4, ("unknown\n"));
794                 return False;
795         }
796
797         /* start off with 1024 bytes, and a large safety margin too */
798         prs_init(&p->rdata, 1024, 4, SAFETY_MARGIN, False);
799
800         /* do the actual command */
801         api_rpc_cmds[fn_num].fn(p->vuid, data, &(p->rdata));
802
803         if (p->rdata.data == NULL || p->rdata.offset == 0)
804         {
805                 mem_free_data(p->rdata.data);
806                 return False;
807         }
808
809         mem_realloc_data(p->rdata.data, p->rdata.offset);
810
811         DEBUG(10,("called %s\n", rpc_name));
812
813         return True;
814 }
815
816
817 /*******************************************************************
818  receives a netlogon pipe and responds.
819  ********************************************************************/
820 BOOL api_rpcTNP(pipes_struct *p, char *rpc_name, struct api_struct *api_rpc_cmds,
821                                 prs_struct *data)
822 {
823         if (data == NULL || data->data == NULL)
824         {
825                 DEBUG(2,("%s: NULL data received\n", rpc_name));
826                 return False;
827         }
828
829         /* interpret the command */
830         if (!api_rpc_command(p, rpc_name, api_rpc_cmds, data))
831         {
832                 return False;
833         }
834
835         /* create the rpc header */
836         if (!create_rpc_reply(p, 0, p->rdata.offset + (p->ntlmssp_auth ? (16 + 8) : 0)))
837         {
838                 return False;
839         }
840
841         return True;
842 }
843
844
845 /*******************************************************************
846  gets a domain user's groups
847  ********************************************************************/
848 void get_domain_user_groups(char *domain_groups, char *user)
849 {
850         pstring tmp;
851
852         if (domain_groups == NULL || user == NULL) return;
853
854         /* any additional groups this user is in.  e.g power users */
855         pstrcpy(domain_groups, lp_domain_groups());
856
857         /* can only be a user or a guest.  cannot be guest _and_ admin */
858         if (user_in_list(user, lp_domain_guest_group()))
859         {
860                 slprintf(tmp, sizeof(tmp) - 1, " %ld/7 ", DOMAIN_GROUP_RID_GUESTS);
861                 pstrcat(domain_groups, tmp);
862
863                 DEBUG(3,("domain guest group access %s granted\n", tmp));
864         }
865         else
866         {
867                 slprintf(tmp, sizeof(tmp) -1, " %ld/7 ", DOMAIN_GROUP_RID_USERS);
868                 pstrcat(domain_groups, tmp);
869
870                 DEBUG(3,("domain group access %s granted\n", tmp));
871
872                 if (user_in_list(user, lp_domain_admin_group()))
873                 {
874                         slprintf(tmp, sizeof(tmp) - 1, " %ld/7 ", DOMAIN_GROUP_RID_ADMINS);
875                         pstrcat(domain_groups, tmp);
876
877                         DEBUG(3,("domain admin group access %s granted\n", tmp));
878                 }
879         }
880 }
881
882
883 /*******************************************************************
884  lookup_group_name
885  ********************************************************************/
886 uint32 lookup_group_name(uint32 rid, char *group_name, uint32 *type)
887 {
888         int i = 0; 
889         (*type) = SID_NAME_DOM_GRP;
890
891         DEBUG(5,("lookup_group_name: rid: %d", rid));
892
893         while (domain_group_rids[i].rid != rid && domain_group_rids[i].rid != 0)
894         {
895                 i++;
896         }
897
898         if (domain_group_rids[i].rid != 0)
899         {
900                 fstrcpy(group_name, domain_group_rids[i].name);
901                 DEBUG(5,(" = %s\n", group_name));
902                 return 0x0;
903         }
904
905         DEBUG(5,(" none mapped\n"));
906         return 0xC0000000 | NT_STATUS_NONE_MAPPED;
907 }
908
909 /*******************************************************************
910  lookup_alias_name
911  ********************************************************************/
912 uint32 lookup_alias_name(uint32 rid, char *alias_name, uint32 *type)
913 {
914         int i = 0; 
915         (*type) = SID_NAME_WKN_GRP;
916
917         DEBUG(5,("lookup_alias_name: rid: %d", rid));
918
919         while (builtin_alias_rids[i].rid != rid && builtin_alias_rids[i].rid != 0)
920         {
921                 i++;
922         }
923
924         if (builtin_alias_rids[i].rid != 0)
925         {
926                 fstrcpy(alias_name, builtin_alias_rids[i].name);
927                 DEBUG(5,(" = %s\n", alias_name));
928                 return 0x0;
929         }
930
931         DEBUG(5,(" none mapped\n"));
932         return 0xC0000000 | NT_STATUS_NONE_MAPPED;
933 }
934
935 /*******************************************************************
936  lookup_user_name
937  ********************************************************************/
938 uint32 lookup_user_name(uint32 rid, char *user_name, uint32 *type)
939 {
940         struct sam_disp_info *disp_info;
941         int i = 0;
942         (*type) = SID_NAME_USER;
943
944         DEBUG(5,("lookup_user_name: rid: %d", rid));
945
946         /* look up the well-known domain user rids first */
947         while (domain_user_rids[i].rid != rid && domain_user_rids[i].rid != 0)
948         {
949                 i++;
950         }
951
952         if (domain_user_rids[i].rid != 0)
953         {
954                 fstrcpy(user_name, domain_user_rids[i].name);
955                 DEBUG(5,(" = %s\n", user_name));
956                 return 0x0;
957         }
958
959         /* ok, it's a user.  find the user account */
960         become_root(True);
961         disp_info = getsamdisprid(rid);
962         unbecome_root(True);
963
964         if (disp_info != NULL)
965         {
966                 fstrcpy(user_name, disp_info->smb_name);
967                 DEBUG(5,(" = %s\n", user_name));
968                 return 0x0;
969         }
970
971         DEBUG(5,(" none mapped\n"));
972         return 0xC0000000 | NT_STATUS_NONE_MAPPED;
973 }
974
975 /*******************************************************************
976  lookup_group_rid
977  ********************************************************************/
978 uint32 lookup_group_rid(char *group_name, uint32 *rid)
979 {
980         char *grp_name;
981         int i = -1; /* start do loop at -1 */
982
983         do /* find, if it exists, a group rid for the group name*/
984         {
985                 i++;
986                 (*rid) = domain_group_rids[i].rid;
987                 grp_name = domain_group_rids[i].name;
988
989         } while (grp_name != NULL && !strequal(grp_name, group_name));
990
991         return (grp_name != NULL) ? 0 : 0xC0000000 | NT_STATUS_NONE_MAPPED;
992 }
993
994 /*******************************************************************
995  lookup_alias_rid
996  ********************************************************************/
997 uint32 lookup_alias_rid(char *alias_name, uint32 *rid)
998 {
999         char *als_name;
1000         int i = -1; /* start do loop at -1 */
1001
1002         do /* find, if it exists, a alias rid for the alias name*/
1003         {
1004                 i++;
1005                 (*rid) = builtin_alias_rids[i].rid;
1006                 als_name = builtin_alias_rids[i].name;
1007
1008         } while (als_name != NULL && !strequal(als_name, alias_name));
1009
1010         return (als_name != NULL) ? 0 : 0xC0000000 | NT_STATUS_NONE_MAPPED;
1011 }
1012
1013 /*******************************************************************
1014  lookup_user_rid
1015  ********************************************************************/
1016 uint32 lookup_user_rid(char *user_name, uint32 *rid)
1017 {
1018         struct sam_passwd *sam_pass;
1019         (*rid) = 0;
1020
1021         /* find the user account */
1022         become_root(True);
1023         sam_pass = getsam21pwnam(user_name);
1024         unbecome_root(True);
1025
1026         if (sam_pass != NULL)
1027         {
1028                 (*rid) = sam_pass->user_rid;
1029                 return 0x0;
1030         }
1031
1032         return 0xC0000000 | NT_STATUS_NONE_MAPPED;
1033 }