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